// NewToken creates new JWT token for the gien username. It embedds the given // public key as kontrolKey and signs the token with the private one. func NewToken(username, private, public string) *jwt.Token { tknID := uuid.NewV4() hostname, err := os.Hostname() if err != nil { panic(err) } if username == "" { username = "******" } if testuser := os.Getenv("TESTKEY_USERNAME"); testuser != "" { username = testuser } claims := &kitekey.KiteClaims{ StandardClaims: jwt.StandardClaims{ Issuer: "testuser", Subject: username, Audience: hostname, IssuedAt: time.Now().UTC().Unix(), Id: tknID.String(), }, KontrolKey: public, KontrolURL: "http://localhost:4000/kite", } token := jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims) rsaPrivate, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(private)) if err != nil { panic(err) } token.Raw, err = token.SignedString(rsaPrivate) if err != nil { panic(err) } // verify the token _, err = jwt.ParseWithClaims(token.Raw, claims, func(*jwt.Token) (interface{}, error) { return jwt.ParseRSAPublicKeyFromPEM([]byte(public)) }) if err != nil { panic(err) } token.Valid = true return token }
func InitTokens() (err error) { signBytes, err := ioutil.ReadFile("config/rsaKey") if err != nil { log.Error("Error reading private key from file: ", err) return } signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes) if err != nil { log.Error("Error parsing private key from file: ", err) return } verifyBytes, err := ioutil.ReadFile("config/pubKey") if err != nil { log.Error("Error reading public key from file: ", err) return } verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes) if err != nil { log.Error("Error parsing public key from file: ", err) return } return }
// http://openid.net/specs/openid-connect-core-1_0.html#IDToken func (s *Server) generateIDToken(userData interface{}, client Client, scopesString string, nonce string, accessToken string) (string, error) { token := jwt.New(jwt.SigningMethodRS256) token.Claims["iss"] = s.Config.Issuer token.Claims["sub"] = userData.(User).GetSub() token.Claims["aud"] = client.GetId() token.Claims["iat"] = time.Now().Unix() token.Claims["nonce"] = nonce token.Claims["exp"] = time.Now().Add(time.Duration(s.Config.IDTokenExpiration) * time.Second).Unix() if accessToken != "" { hasher := sha256.New() io.WriteString(hasher, accessToken) sum := hasher.Sum(nil) accessTokenHash := base64.URLEncoding.EncodeToString(sum[0 : len(sum)/2]) token.Claims["at_hash"] = accessTokenHash } scopes := strings.Split(scopesString, " ") for _, scope := range scopes { claims := s.ClaimManager.GetClaims(scope, userData) for k, v := range claims { token.Claims[k] = v } } // kid token.Header["kid"] = s.Config.JWTKeyID key, _ := jwt.ParseRSAPrivateKeyFromPEM(s.Config.JWTKey) a, err := token.SignedString(key) return a, err }
// ReadPrivateKey is a helper function for reading an rsa.PrivateKey from a PEM-encoded file func ReadPrivateKey(file string) (*rsa.PrivateKey, error) { data, err := ioutil.ReadFile(file) if err != nil { return nil, err } return jwt.ParseRSAPrivateKeyFromPEM(data) }
// loadMintKeyByName loads a key by filename and stores it in the struct // The function is threadsafe and panics if the key file is invalid func LoadMintKeyByName(filename string) { keyPath := util.GetPaths([]string{filename})[0] b, err := ioutil.ReadFile(keyPath) if err != nil { log.WithFields(log.Fields{ "path": keyPath, }).Panic("Failed to load mint key: ", err) } k, err := jwt.ParseRSAPrivateKeyFromPEM(b) if err != nil { log.WithFields(log.Fields{ "path": keyPath, }).Panic("Failed to parse mint key: ", err) } log.WithFields(log.Fields{ "path": keyPath, }).Debugf("Successfully loaded mint key from %s", keyPath) // Store only after we are sure loading was good mint.Lock() defer mint.Unlock() mint.Key = k mint.From = keyPath }
// ReadPrivateKeyFromPEM is a helper function for reading a private key from a PEM-encoded file func ReadPrivateKeyFromPEM(data []byte) (interface{}, error) { if key, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil { return key, nil } if key, err := jwt.ParseECPrivateKeyFromPEM(data); err == nil { return key, nil } return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key") }
func GetPrivateKeyFromPath(path string) *rsa.PrivateKey { bytes, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } key, err := jwt.ParseRSAPrivateKeyFromPEM(bytes) if err != nil { log.Fatal(err) } return key }
func NewAuthServer(rsaPrivateKey string) (*authServer, error) { key, err := ioutil.ReadFile(rsaPrivateKey) if err != nil { return nil, fmt.Errorf("Error reading the jwt private key: %s", err) } parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) if err != nil { return nil, fmt.Errorf("Error parsing the jwt private key: %s", err) } return &authServer{parsedKey}, nil }
// generateToken returns a JWT token string. Please see the URL for details: // http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1 func (k *Kontrol) generateToken(aud, username, issuer string, kp *KeyPair) (string, error) { uniqKey := aud + username + issuer + kp.ID k.tokenCacheMu.Lock() defer k.tokenCacheMu.Unlock() signed, ok := k.tokenCache[uniqKey] if ok { return signed, nil } rsaPrivate, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(kp.Private)) if err != nil { return "", err } now := time.Now().UTC() claims := &kitekey.KiteClaims{ StandardClaims: jwt.StandardClaims{ Issuer: issuer, Subject: username, Audience: aud, ExpiresAt: now.Add(k.tokenTTL()).Add(k.tokenLeeway()).UTC().Unix(), IssuedAt: now.Add(-k.tokenLeeway()).UTC().Unix(), Id: uuid.NewV4().String(), }, } if !k.TokenNoNBF { claims.NotBefore = now.Add(-k.tokenLeeway()).Unix() } signed, err = jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims).SignedString(rsaPrivate) if err != nil { return "", errors.New("Server error: Cannot generate a token") } // cache our token k.tokenCache[uniqKey] = signed // cache invalidation, because we cache the token in tokenCache we need to // invalidate it expiration time. This was handled usually within JWT, but // now we have to do it manually for our own cache. time.AfterFunc(TokenTTL-TokenLeeway, func() { k.tokenCacheMu.Lock() defer k.tokenCacheMu.Unlock() delete(k.tokenCache, uniqKey) }) return signed, nil }
// ReadPublicKey is a helper function for reading an rsa.PublicKey from a PEM-encoded file // Reads public keys from both public and private key files func ReadPublicKey(file string) (*rsa.PublicKey, error) { data, err := ioutil.ReadFile(file) if err != nil { return nil, err } if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil { return &privateKey.PublicKey, nil } return jwt.ParseRSAPublicKeyFromPEM(data) }
func (t *JwtToken) parsePrivateKey(keyPath string) error { if pem, err := ioutil.ReadFile(keyPath); err != nil { return err } else { if privKey, err := libjwt.ParseRSAPrivateKeyFromPEM(pem); err != nil { return err } else { t.privKey = privKey return nil } } }
func init() { signBytes, err := ioutil.ReadFile(privKeyPath) fatal(err) signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes) fatal(err) verifyBytes, err := ioutil.ReadFile(pubKeyPath) fatal(err) verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes) fatal(err) }
func ParseTestPrivateKey() interface{} { keyBytes, err := ioutil.ReadFile("../test_utils/private.pem") if err != nil { log.Fatal("Failed to parse private key.", err) } privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyBytes) if err != nil { log.Fatal("Failed to parse private key.", err) } return privateKey }
func showDevAuth() { currentKeyBytes, _ := ioutil.ReadFile(config.GetStr(setting.JWT_RSA_KEY_LOCATION)) currentKey, err1 := jwt.ParseRSAPrivateKeyFromPEM(currentKeyBytes) if err1 != nil { log.Panic(err1) } token := jwt.New(jwt.SigningMethodRS512) // Set some claims token.Claims["userId"] = `eeee1df4-9fae-4e32-98c1-88f850a00001` token.Claims["exp"] = time.Now().Add(time.Minute * 60 * 24 * 30).Unix() // Sign and get the complete encoded token as a string tokenString, _ := token.SignedString(currentKey) fmt.Println("Please put the following string into http 'Authorization' header:") fmt.Println(tokenString) }
func TestCreateTrackerQueryREST(t *testing.T) { resource.Require(t, resource.Database) privatekey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(almtoken.RSAPrivateKey)) if err != nil { t.Fatal("Could not parse Key ", err) } service := goa.New("API") controller := NewTrackerController(service, gormapplication.NewGormDB(DB), RwiScheduler) payload := app.CreateTrackerAlternatePayload{ URL: "http://api.github.com", Type: "github", } _, tracker := test.CreateTrackerCreated(t, nil, nil, controller, &payload) jwtMiddleware := goajwt.New(&privatekey.PublicKey, nil, app.NewJWTSecurity()) app.UseJWTMiddleware(service, jwtMiddleware) controller2 := NewTrackerqueryController(service, gormapplication.NewGormDB(DB), RwiScheduler) app.MountTrackerqueryController(service, controller2) server := httptest.NewServer(service.Mux) tqPayload := fmt.Sprintf(`{"query": "abcdefgh", "schedule": "1 1 * * * *", "trackerID": "%s"}`, tracker.ID) trackerQueryCreateURL := "/api/trackerqueries" req, _ := http.NewRequest("POST", server.URL+trackerQueryCreateURL, strings.NewReader(tqPayload)) jwtToken := getValidAuthHeader(t, privatekey) req.Header.Set("Authorization", jwtToken) client := http.Client{} res, err := client.Do(req) if err != nil { t.Fatalf("Server error %s", err) } if res.StatusCode != http.StatusCreated { t.Fatalf("Expected a 201 Created response, got %d", res.StatusCode) } server.Close() }
func init() { signBytes, err := ioutil.ReadFile(config.Settings.PrivKeyPath) if err != nil { logger.Log("Reading private Key File "+config.Settings.PrivKeyPath+" failed, Error: "+err.Error(), logger.ERROR) } signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes) if err != nil { logger.Log("Parsing private Key File failed, Error: "+err.Error(), logger.ERROR) } verifyBytes, err := ioutil.ReadFile(config.Settings.PubKeyPath) if err != nil { logger.Log("Reading public Key File "+config.Settings.PubKeyPath+" failed, Error: "+err.Error(), logger.ERROR) } verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes) if err != nil { logger.Log("Parsing public Key File failed, Error: "+err.Error(), logger.ERROR) } }
func (k *Kontrol) registerUser(username, publicKey, privateKey string) (kiteKey string, err error) { claims := &kitekey.KiteClaims{ StandardClaims: jwt.StandardClaims{ Issuer: k.Kite.Kite().Username, Subject: username, IssuedAt: time.Now().Add(-k.tokenLeeway()).UTC().Unix(), Id: uuid.NewV4().String(), }, KontrolURL: k.Kite.Config.KontrolURL, KontrolKey: strings.TrimSpace(publicKey), } rsaPrivate, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey)) if err != nil { return "", err } k.Kite.Log.Info("Registered machine on user: %s", username) return jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims).SignedString(rsaPrivate) }
// ReadPublicKeysFromPEM is a helper function for reading an array of rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array. // Reads public keys from both public and private key files. func ReadPublicKeysFromPEM(data []byte) ([]interface{}, error) { var block *pem.Block keys := []interface{}{} for { // read the next block block, data = pem.Decode(data) if block == nil { break } // get PEM bytes for just this block blockData := pem.EncodeToMemory(block) if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(blockData); err == nil { keys = append(keys, &privateKey.PublicKey) continue } if publicKey, err := jwt.ParseRSAPublicKeyFromPEM(blockData); err == nil { keys = append(keys, publicKey) continue } if privateKey, err := jwt.ParseECPrivateKeyFromPEM(blockData); err == nil { keys = append(keys, &privateKey.PublicKey) continue } if publicKey, err := jwt.ParseECPublicKeyFromPEM(blockData); err == nil { keys = append(keys, publicKey) continue } // tolerate non-key PEM blocks for backwards compatibility // originally, only the first PEM block was parsed and expected to be a key block } if len(keys) == 0 { return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA key") } return keys, nil }
func (k *Kontrol) updateKeyWithKeyPair(t *jwt.Token, keyPair *KeyPair) string { claims := t.Claims.(*kitekey.KiteClaims) if claims.KontrolKey != "" { claims.KontrolKey = keyPair.Public } rsaPrivate, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(keyPair.Private)) if err != nil { k.log.Error("key update error for %q: %s", claims.Subject, err) return "" } kiteKey, err := t.SignedString(rsaPrivate) if err != nil { k.log.Error("key update error for %q: %s", claims.Subject, err) return "" } return kiteKey }
func NewAuthResource(privateKeyPath, publicKeyPath string, tokenDuration time.Duration, validator AuthValidator) *AuthResource { verifyBytes, err := ioutil.ReadFile(publicKeyPath) fatal(err) verifyKey, err := jwt.ParseRSAPublicKeyFromPEM(verifyBytes) fatal(err) signBytes, err := ioutil.ReadFile(privateKeyPath) fatal(err) signKey, err := jwt.ParseRSAPrivateKeyFromPEM(signBytes) fatal(err) if tokenDuration < 1 { tokenDuration = DEFAULT_TOKEN_DURATION } if nil == validator { validator = DummyAuthValidator } return &AuthResource{verifyKey, signKey, tokenDuration, validator} }
func TestJWTToken(t *testing.T) { var err error var privateKeyContent, publicKeyContent []byte if privateKeyContent, err = ioutil.ReadFile("jwt-test.key"); err != nil { t.Fatal(err) } if publicKeyContent, err = ioutil.ReadFile("jwt-test.pub"); err != nil { t.Fatal(err) } if privateKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKeyContent); err != nil { t.Fatal(err) } if publicKey, err = jwt.ParseRSAPublicKeyFromPEM(publicKeyContent); err != nil { t.Fatal(err) } token := jwt.New(jwt.GetSigningMethod("RS256")) token.Claims = jwt.MapClaims{ "PERMISSION": "admin@tiedot", "exp": time.Now().Add(time.Hour * 72).Unix(), } ts, err := token.SignedString(privateKey) if err != nil { t.Fatal(err) } if token, err = jwt.Parse(ts, func(ts *jwt.Token) (interface{}, error) { return publicKey, nil }); err != nil { t.Fatal(err) } if token.Valid { t.Log(token) } else { t.Log(token) t.Fail() } }
func getWorkItemLinkTypeTestData(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM((configuration.GetTokenPrivateKey())) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) if err != nil { t.Fatal("Could not parse different private key ", err) } createWorkItemLinkTypePayloadString := bytes.NewBuffer([]byte(` { "data": { "type": "workitemlinktypes", "id": "0270e113-7790-477f-9371-97c37d734d5d", "attributes": { "name": "sample", "description": "A sample work item link type", "version": 0, "forward_name": "forward string name", "reverse_name": "reverse string name" }, "relationships": { "link_category": {"data": {"type":"workitemlinkcategories", "id": "a75ea296-6378-4578-8573-90f11b8efb00"}}, "source_type": {"data": {"type":"workitemtypes", "id": "bug"}}, "target_type": {"data": {"type":"workitemtypes", "id": "bug"}} } } } `)) return []testSecureAPI{ // Create Work Item API with different parameters { method: http.MethodPost, url: endpointWorkItemLinkTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: "", }, // Update Work Item API with different parameters { method: http.MethodPatch, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkTypePayloadString, jwtToken: "", }, // Delete Work Item API with different parameters { method: http.MethodDelete, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkTypes + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: "", }, // Try fetching a random work item link type // We do not have security on GET hence this should return 404 not found { method: http.MethodGet, url: endpointWorkItemLinkTypes + "/fc591f38-a805-4abd-bfce-2460e49d8cc4", expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, } }
func getWorkItemLinkCategoryTestData(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM((configuration.GetTokenPrivateKey())) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) if err != nil { t.Fatal("Could not parse different private key ", err) } createWorkItemLinkCategoryPayloadString := bytes.NewBuffer([]byte(` { "data": { "attributes": { "description": "A sample work item link category", "name": "sample", "version": 0 }, "id": "6c5610be-30b2-4880-9fec-81e4f8e4fddd", "type": "workitemlinkcategories" } } `)) return []testSecureAPI{ // Create Work Item API with different parameters { method: http.MethodPost, url: endpointWorkItemLinkCategories, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkCategories, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkCategories, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: endpointWorkItemLinkCategories, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: "", }, // Update Work Item API with different parameters { method: http.MethodPatch, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkCategoryPayloadString, jwtToken: "", }, // Delete Work Item API with different parameters { method: http.MethodDelete, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinkCategories + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: "", }, // Try fetching a random work item link category // We do not have security on GET hence this should return 404 not found { method: http.MethodGet, url: endpointWorkItemLinkCategories + "/fc591f38-a805-4abd-bfce-2460e49d8cc4", expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, } }
// ParsePrivateKey parses a []byte representation of a private key into a rsa.PrivateKey instance func ParsePrivateKey(key []byte) (*rsa.PrivateKey, error) { return jwt.ParseRSAPrivateKeyFromPEM(key) }
func getWorkItemTypeTestData(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM((configuration.GetTokenPrivateKey())) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) require.Nil(t, err) createWITPayloadString := bytes.NewBuffer([]byte(`{"fields": {"system.administrator": {"Required": true,"Type": {"Kind": "string"}}},"name": "Epic"}`)) return []testSecureAPI{ // Create Work Item API with different parameters { method: http.MethodPost, url: endpointWorkItemTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWITPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWITPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWITPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: endpointWorkItemTypes, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWITPayloadString, jwtToken: "", }, // Try fetching a random work Item Type // We do not have security on GET hence this should return 404 not found { method: http.MethodGet, url: endpointWorkItemTypes + "/someRandomTestWIT8712", expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, { method: http.MethodGet, url: fmt.Sprintf(endpointWorkItemTypesSourceLinkTypes, "someNotExistingWIT"), expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, { method: http.MethodGet, url: fmt.Sprintf(endpointWorkItemTypesTargetLinkTypes, "someNotExistingWIT"), expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, } }
}) var rsaKey1, _ = jwtpkg.ParseRSAPrivateKeyFromPEM([]byte(`-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEArZIJcPQd7aSGb80wgFpy5SVjzzsGpfIysZ30SdWlTcWMVbAT XmsDNgw98TzIeoyikSbSHEeORbKWKS2clgNsdLjYKv3XLTBaXfLcU3x9mhnk/kUL N/AQgyvsRGynPris2oVzGSib7uOZK/9+u+QAKIrp7prcmMmnwvdcjFXjwzx83RTF 1b+iuVGCdV0T4m1XQdm/YtIUh7JNbYrUolkdwZlOxMZuV0FDC+ms02+gyj580Pyl TuAD4JmtSmmijyWfEx5dsZYtGALyUxcm5Hz15RP3FACrv4B++BHI6smO4sWdrSYV l3sHJ60Bm6zbwuyB2twJPOdL5nVIGiIDdf+1IwIDAQABAoIBACF3MtLQfqS/QBx2 V4+n4NdFqkTegJ2mYRfV+K/zvXeNS02KMXHW+DuHiLnmmlDmpMGP1psVQN03XbR6 0uIprtOigCtp3f8cf4/1r315V05LB9fuwAb9BnIEGf3nZSe2u702VcbYCZi50WKm VG0tvMoUXp5exYG//9SblQCJ3uxZf9D8y5RnrUZtP4Pnjkn/3YeJCF+Kked55Cvi gv56/aiyWp9xEGsSWig5Zt8VNXihgT7D2KZzxcQDQlxw0CR5ECT7/4w7sZVvwc7B I76JJDvpD0UGvzoUgx928efGKxJBrcjzvTNSKgHJYYCvaa6+qX2tjkmOqdG4xl27 /TaBISECgYEA4YJ32HKaS2ikn5J2C1qlHy4nRuVNhX8T9qvp6OBdbE2BQq3O5IUt +wdTcjhD88aDdHCZmAd8i3FC4l+CKsQ5sTwRk0vTOZ7axC6+zDHg+na5/+NCq+xm ffoaZ5jsZFyqfbsFn8NiLWLo2JSFV1AnUxwpPA2jbuylAuZVvVbLYHcCgYEAxQnO L+U6NwTvN6EJgt3h1jHfXiQnapsj0O0XgK+g2K6vMovpXAf9noO+r3Qbx/aKxuRg TvRQ08T5yyqysz+sYe0rp8oaMUhYQFMgJOUUBlmUVGxYdARMD6kTy/384B9Azoex UCosMSEAD909MAsyQWB4X6OJKd+V68QpFYeIx7UCgYBHgaRY6PYOBU92He36abLE MVFZBKrRMtt0s0yHgGV/SxA6wXxCMAzFdaw7IqZBbWgPiwjZET6nxLFNsLVItFIK 5h44k6mVss5xuNTdUM+i+/S8tCZW964EMkMfKHmE1XFmTuBYqY6/D4b/7hBeAFeH 3f0hQr3ZFYa5Zao4UIZKvwKBgGL8lhUBt8lENVlhEYIpLfeJfomw6AxqfAfN1GzV zpyMxX9DQqz1ZrhnvzgtwHcoqHda6/c+TgzVfBhRDw12A4f+ulvE8HupuIw4NoHS g8jc3+O5uoYuUnfbnRJyOsPtb4VSLgXz6deUmI9fugmU1l55tH93jMT4ijyzg2BJ grGxAoGAWX24Yx9qoasqEQ2rgdTsgylwL28UczKQ5KNHt2PcEfPNw6/GpfK7YmlU Heef2umEzb1K2ZK95wlMbF8zpNDWBf4PkxgfW+JEE+pO1kb5KXysBymymyXhGHAP CwH9XHqbjVlsD358AbPeKqLgTCaGo9JgsEZDBpESmBDnIPUahMc= -----END RSA PRIVATE KEY-----`)) var rsaPubKey1, _ = jwtpkg.ParseRSAPublicKeyFromPEM([]byte(`-----BEGIN PUBLIC KEY-----
// The work item ID will be used to construct /api/workitems/:id/relationships/links endpoints func getWorkItemRelationshipLinksTestData(t *testing.T, wiID string) func(t *testing.T) []testSecureAPI { return func(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM((configuration.GetTokenPrivateKey())) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) if err != nil { t.Fatal("Could not parse different private key ", err) } createWorkItemLinkPayloadString := bytes.NewBuffer([]byte(` { "data": { "attributes": { "version": 0 }, "id": "40bbdd3d-8b5d-4fd6-ac90-7236b669af04", "relationships": { "link_type": { "data": { "id": "6c5610be-30b2-4880-9fec-81e4f8e4fd76", "type": "workitemlinktypes" } }, "source": { "data": { "id": "1234", "type": "workitems" } }, "target": { "data": { "id": "1234", "type": "workitems" } } }, "type": "workitemlinks" } } `)) relationshipsEndpoint := fmt.Sprintf(endpointWorkItemRelationshipsLinks, wiID) testWorkItemLinksAPI := []testSecureAPI{ // Create Work Item API with different parameters { method: http.MethodPost, url: relationshipsEndpoint, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: relationshipsEndpoint, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: relationshipsEndpoint, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: relationshipsEndpoint, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: "", }, } return testWorkItemLinksAPI } }
func getTrackerTestData(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(almtoken.RSAPrivateKey)) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) require.Nil(t, err) createTrackerPayload := bytes.NewBuffer([]byte(`{"type": "github", "url": "https://api.github.com/"}`)) return []testSecureAPI{ // Create tracker API with different parameters { method: http.MethodPost, url: "/api/trackers", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: "/api/trackers", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: "/api/trackers", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: "/api/trackers", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: "", }, // Update tracker API with different parameters { method: http.MethodPut, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPut, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPut, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPut, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: "", }, // Delete tracker API with different parameters { method: http.MethodDelete, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodDelete, url: "/api/trackers/12345", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createTrackerPayload, jwtToken: "", }, // Try fetching a random tracker // We do not have security on GET hence this should return 404 not found { method: http.MethodGet, url: "/api/trackers/088481764871", expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, } }
// init the various object and inject the database object to the modules func initDependency() { //the postgresql connection string connectStr := "host=" + config.GetStr(setting.DB_HOST) + " port=" + strconv.Itoa(config.GetInt(setting.DB_PORT)) + " dbname=" + config.GetStr(setting.DB_NAME) + " user="******" password='******' sslmode=disable" //db, err := gorm.Open("postgres", connectStr) db, err := xorm.NewEngine("postgres", connectStr) if err != nil { log.Panic("DB connection initialization failed", err) } db.SetMaxIdleConns(config.GetInt(setting.DB_MAX_IDLE_CONN)) db.SetMaxOpenConns(config.GetInt(setting.DB_MAX_OPEN_CONN)) db.SetColumnMapper(xormCore.SnakeMapper{}) //uncomment it if you want to debug // db.ShowSQL = true // db.ShowErr = true //setup the redis redisOptions := redis.Options{ Addr: config.GetStr(setting.REDIS_ENDPOINT), PoolSize: config.GetInt(setting.REDIS_POOL_SIZE), Network: "tcp", //FIXME: check the purpose of these timeout DialTimeout: 5 * time.Second, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, } redisClient := redis.NewClient(&redisOptions) //load the RSA key from the file system, for the jwt auth var err1 error var currentKey *rsa.PrivateKey = nil var oldKey *rsa.PrivateKey = nil currentKeyBytes, _ := ioutil.ReadFile(config.GetStr(setting.JWT_RSA_KEY_LOCATION)) currentKey, err1 = jwt.ParseRSAPrivateKeyFromPEM(currentKeyBytes) if err1 != nil { log.Panic(err1) } if location := config.GetStr(setting.JWT_OLD_RSA_KEY_LOCATION); location != `` { oldKeyBytes, _ := ioutil.ReadFile(location) oldKey, err1 = jwt.ParseRSAPrivateKeyFromPEM(oldKeyBytes) if err1 != nil { log.Panic(err1) } } lifetime := time.Duration(config.GetInt(setting.JWT_TOKEN_LIFETIME)) * time.Minute auth.Init(currentKey, oldKey, lifetime) httputil.Init(xormCore.SnakeMapper{}) //add the db dependency to middleware module middleware.Init(db, redisClient) //add the redis dependency to lock module lock.Init(redisClient) }
func getWorkItemLinkTestData(t *testing.T) []testSecureAPI { privatekey, err := jwt.ParseRSAPrivateKeyFromPEM((configuration.GetTokenPrivateKey())) if err != nil { t.Fatal("Could not parse Key ", err) } differentPrivatekey, err := jwt.ParseRSAPrivateKeyFromPEM(([]byte(RSADifferentPrivateKeyTest))) if err != nil { t.Fatal("Could not parse different private key ", err) } createWorkItemLinkPayloadString := bytes.NewBuffer([]byte(` { "data": { "attributes": { "version": 0 }, "id": "40bbdd3d-8b5d-4fd6-ac90-7236b669af04", "relationships": { "link_type": { "data": { "id": "6c5610be-30b2-4880-9fec-81e4f8e4fd76", "type": "workitemlinktypes" } }, "source": { "data": { "id": "1234", "type": "workitems" } }, "target": { "data": { "id": "1234", "type": "workitems" } } }, "type": "workitemlinks" } } `)) testWorkItemLinksAPI := []testSecureAPI{ // Create Work Item API with different parameters { method: http.MethodPost, url: endpointWorkItemLinks, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinks, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPost, url: endpointWorkItemLinks, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPost, url: endpointWorkItemLinks, expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: "", }, // Update Work Item API with different parameters { method: http.MethodPatch, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodPatch, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: createWorkItemLinkPayloadString, jwtToken: "", }, // Delete Work Item API with different parameters { method: http.MethodDelete, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getExpiredAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getMalformedAuthHeader(t, privatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: getValidAuthHeader(t, differentPrivatekey), }, { method: http.MethodDelete, url: endpointWorkItemLinks + "/6c5610be-30b2-4880-9fec-81e4f8e4fd76", expectedStatusCode: http.StatusUnauthorized, expectedErrorCode: jsonapi.ErrorCodeJWTSecurityError, payload: nil, jwtToken: "", }, // Try fetching a random work item link // We do not have security on GET hence this should return 404 not found { method: http.MethodGet, url: endpointWorkItemLinks + "/fc591f38-a805-4abd-bfce-2460e49d8cc4", expectedStatusCode: http.StatusNotFound, expectedErrorCode: jsonapi.ErrorCodeNotFound, payload: nil, jwtToken: "", }, } return testWorkItemLinksAPI }