Răsfoiți Sursa

fmt: fix cyclo complexity in recent jwt key merge

jamesread 2 ani în urmă
părinte
comite
56ef7ce95c
2 a modificat fișierele cu 63 adăugiri și 30 ștergeri
  1. 44 23
      internal/httpservers/restapi_auth_jwt.go
  2. 19 7
      internal/httpservers/restapi_test.go

+ 44 - 23
internal/httpservers/restapi_auth_jwt.go

@@ -15,31 +15,44 @@ var (
 	pubKey      *rsa.PublicKey
 	pubKey      *rsa.PublicKey
 )
 )
 
 
-func parseJwtToken(cookieValue string) (*jwt.Token, error) {
-	if cfg.AuthJwtPubKeyPath != "" { // activate this path only if pub key is specified
-		if pubKeyBytes == nil { // keep in memory after first load
-			var err error
-			pubKeyBytes, err = os.ReadFile(cfg.AuthJwtPubKeyPath)
-			if err != nil {
-				return nil, fmt.Errorf("couldn't read public key from file %s", cfg.AuthJwtPubKeyPath)
-			}
-			// Since the token is RSA (which we validated at the start of this function), the return type of this function actually has to be rsa.PublicKey!
-			pubKey, err = jwt.ParseRSAPublicKeyFromPEM(pubKeyBytes)
-			if err != nil {
-				return nil, fmt.Errorf("error parsing public key object (from %s)", cfg.AuthJwtPubKeyPath)
-			}
-		}
-		return jwt.Parse(cookieValue, func(token *jwt.Token) (interface{}, error) {
-			if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
-				return nil, fmt.Errorf(
-					"expected token algorithm '%v' but got '%v'",
-					jwt.SigningMethodRS256.Name,
-					token.Header)
-			}
-			return pubKey, nil
-		})
+func readPublicKey() error {
+	if pubKeyBytes != nil {
+		return nil // Already read.
+	}
+
+	pubKeyBytes, err := os.ReadFile(cfg.AuthJwtPubKeyPath)
+	if err != nil {
+		return fmt.Errorf("couldn't read public key from file %s", cfg.AuthJwtPubKeyPath)
+	}
+
+	// Since the token is RSA (which we validated at the start of this function), the return type of this function actually has to be rsa.PublicKey!
+	pubKey, err = jwt.ParseRSAPublicKeyFromPEM(pubKeyBytes)
+	if err != nil {
+		return fmt.Errorf("error parsing public key object (from %s)", cfg.AuthJwtPubKeyPath)
+	}
+
+	return nil
+}
+
+func parseJwtTokenWithKey(cookieValue string) (*jwt.Token, error) {
+	err := readPublicKey()
+
+	if err != nil {
+		return nil, err
 	}
 	}
 
 
+	return jwt.Parse(cookieValue, func(token *jwt.Token) (interface{}, error) {
+		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
+			return nil, fmt.Errorf(
+				"expected token algorithm '%v' but got '%v'",
+				jwt.SigningMethodRS256.Name,
+				token.Header)
+		}
+		return pubKey, nil
+	})
+}
+
+func parseJwtTokenWithoutKey(cookieValue string) (*jwt.Token, error) {
 	return jwt.Parse(cookieValue, func(token *jwt.Token) (interface{}, error) {
 	return jwt.Parse(cookieValue, func(token *jwt.Token) (interface{}, error) {
 		// Don't forget to validate the alg is what you expect:
 		// Don't forget to validate the alg is what you expect:
 		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
 		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
@@ -51,6 +64,14 @@ func parseJwtToken(cookieValue string) (*jwt.Token, error) {
 	})
 	})
 }
 }
 
 
+func parseJwtToken(cookieValue string) (*jwt.Token, error) {
+	if cfg.AuthJwtPubKeyPath != "" { // activate this path only if pub key is specified
+		return parseJwtTokenWithKey(cookieValue)
+	} else {
+		return parseJwtTokenWithoutKey(cookieValue)
+	}
+}
+
 func getClaimsFromJwtToken(cookieValue string) (jwt.MapClaims, error) {
 func getClaimsFromJwtToken(cookieValue string) (jwt.MapClaims, error) {
 	token, err := parseJwtToken(cookieValue)
 	token, err := parseJwtToken(cookieValue)
 
 

+ 19 - 7
internal/httpservers/restapi_test.go

@@ -20,7 +20,7 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-func testBase(t *testing.T, expire int64, expectCode int) {
+func createKeys() (*rsa.PrivateKey, string) {
 	tmpFile, _ := os.CreateTemp(os.TempDir(), "olivetin-jwt-")
 	tmpFile, _ := os.CreateTemp(os.TempDir(), "olivetin-jwt-")
 	defer os.Remove(tmpFile.Name())
 	defer os.Remove(tmpFile.Name())
 
 
@@ -36,13 +36,20 @@ func testBase(t *testing.T, expire int64, expectCode int) {
 			Bytes: pkixPubKey,
 			Bytes: pkixPubKey,
 		},
 		},
 	)
 	)
+
 	if err := os.WriteFile(tmpFile.Name(), pubPem, 0755); err != nil {
 	if err := os.WriteFile(tmpFile.Name(), pubPem, 0755); err != nil {
 		fmt.Printf("error when dumping pubKey: %s \n", err)
 		fmt.Printf("error when dumping pubKey: %s \n", err)
 	}
 	}
 
 
+	return privateKey, tmpFile.Name()
+}
+
+func testBase(t *testing.T, expire int64, expectCode int) {
+	privateKey, publicKeyPath := createKeys()
+
 	// default config + overrides
 	// default config + overrides
 	config := config2.DefaultConfig()
 	config := config2.DefaultConfig()
-	config.AuthJwtPubKeyPath = tmpFile.Name()
+	config.AuthJwtPubKeyPath = publicKeyPath
 	config.AuthJwtClaimUsername = "sub"
 	config.AuthJwtClaimUsername = "sub"
 	config.AuthJwtClaimUserGroup = "olivetinGroup"
 	config.AuthJwtClaimUserGroup = "olivetinGroup"
 	config.AuthJwtCookieName = "authorization_token"
 	config.AuthJwtCookieName = "authorization_token"
@@ -97,11 +104,16 @@ func testBase(t *testing.T, expire int64, expectCode int) {
 		MaxAge: 300,
 		MaxAge: 300,
 	}
 	}
 	req.AddCookie(cookie)
 	req.AddCookie(cookie)
-	res, _ := client.Do(req)
-	defer res.Body.Close()
-	assert.Equal(t, expectCode, res.StatusCode)
-	body, _ := io.ReadAll(res.Body)
-	fmt.Println(string(body))
+	res, err := client.Do(req)
+
+	if err != nil {
+		assert.Equal(t, expectCode, -1)
+	} else {
+		defer res.Body.Close()
+		assert.Equal(t, expectCode, res.StatusCode)
+		body, _ := io.ReadAll(res.Body)
+		fmt.Println(string(body))
+	}
 }
 }
 
 
 func TestJWTSignatureVerificationSucceeds(t *testing.T) {
 func TestJWTSignatureVerificationSucceeds(t *testing.T) {