From ca363be28b9d26b1fd11098f8038617d8710b51f Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Wed, 27 Mar 2024 16:04:52 +0100 Subject: [PATCH] ginjwt/Validate config (#206) * jwt/NewAuthMiddleware: verify Audience and Issuer is defined in config When auth is enabled, we'd like to make sure this returns an error if its a misconfiguration * ginjwt/multitoken: return error if configuration is not defined * make lint --- events/nats_config_test.go | 2 ++ ginjwt/jwt.go | 9 +++++++++ ginjwt/jwt_test.go | 30 ++++++++++++++++++++++++++++-- ginjwt/multitokenmiddleware.go | 10 +++++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/events/nats_config_test.go b/events/nats_config_test.go index 4c2da05..85190a3 100644 --- a/events/nats_config_test.go +++ b/events/nats_config_test.go @@ -66,6 +66,7 @@ func TestNatsOptions_ValidatePrereqs(t *testing.T) { CredsFile: tt.fields.CredsFile, ConnectTimeout: tt.fields.ConnectTimeout, } + err := o.validatePrereqs() if tt.errorContains != "" { assert.True(t, errors.Is(err, ErrNatsConfig)) @@ -180,6 +181,7 @@ func TestNatsConsumerOptions_Validate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := &NatsConsumerOptions{Name: tt.fields.Name} + err := c.validate() if tt.errorContains != "" { assert.True(t, errors.Is(err, ErrNatsConfig)) diff --git a/ginjwt/jwt.go b/ginjwt/jwt.go index 541e4f0..382b9ed 100644 --- a/ginjwt/jwt.go +++ b/ginjwt/jwt.go @@ -8,6 +8,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/pkg/errors" "golang.org/x/net/context" "gopkg.in/square/go-jose.v2" "gopkg.in/square/go-jose.v2/jwt" @@ -73,6 +74,14 @@ func NewAuthMiddleware(cfg AuthConfig) (*Middleware, error) { return mw, nil } + if cfg.Audience == "" { + return nil, errors.Wrap(ErrInvalidAudience, "empty value") + } + + if cfg.Issuer == "" { + return nil, errors.Wrap(ErrInvalidIssuer, "empty value") + } + uriProvided := (cfg.JWKSURI != "") jwksProvided := len(cfg.JWKS.Keys) > 0 diff --git a/ginjwt/jwt_test.go b/ginjwt/jwt_test.go index 2e58886..52cc5ec 100644 --- a/ginjwt/jwt_test.go +++ b/ginjwt/jwt_test.go @@ -220,7 +220,9 @@ func TestMiddlewareValidatesTokensWithScopes(t *testing.T) { for _, tt := range testCases { t.Run(tt.testName, func(t *testing.T) { var jwksURI string + var jwks jose.JSONWebKeySet + if tt.jwksFromURI { jwksURI = ginjwt.TestHelperJWKSProvider(ginjwt.TestPrivRSAKey1ID, ginjwt.TestPrivRSAKey2ID) } else { @@ -719,7 +721,7 @@ func TestAuthMiddlewareConfig(t *testing.T) { JWKS: jwks, RoleValidationStrategy: "all", }, - checkFn: func(t *testing.T, mw ginauth.GenericAuthMiddleware, err error) { + checkFn: func(t *testing.T, _ ginauth.GenericAuthMiddleware, err error) { assert.ErrorIs(t, err, ginjwt.ErrInvalidAuthConfig) }, }, @@ -731,10 +733,34 @@ func TestAuthMiddlewareConfig(t *testing.T) { Issuer: "example-iss", RoleValidationStrategy: "all", }, - checkFn: func(t *testing.T, mw ginauth.GenericAuthMiddleware, err error) { + checkFn: func(t *testing.T, _ ginauth.GenericAuthMiddleware, err error) { assert.ErrorIs(t, err, ginjwt.ErrInvalidAuthConfig) }, }, + { + name: "MissingAudience", + input: ginjwt.AuthConfig{ + Enabled: true, + Audience: "", + Issuer: "example-iss", + RoleValidationStrategy: "all", + }, + checkFn: func(t *testing.T, _ ginauth.GenericAuthMiddleware, err error) { + assert.ErrorIs(t, err, ginjwt.ErrInvalidAudience) + }, + }, + { + name: "MissingIssuer", + input: ginjwt.AuthConfig{ + Enabled: true, + Audience: "example-aud", + Issuer: "", + RoleValidationStrategy: "all", + }, + checkFn: func(t *testing.T, _ ginauth.GenericAuthMiddleware, err error) { + assert.ErrorIs(t, err, ginjwt.ErrInvalidIssuer) + }, + }, } for _, tc := range testCases { diff --git a/ginjwt/multitokenmiddleware.go b/ginjwt/multitokenmiddleware.go index aa8ffe0..b42a9be 100644 --- a/ginjwt/multitokenmiddleware.go +++ b/ginjwt/multitokenmiddleware.go @@ -1,9 +1,17 @@ package ginjwt -import "go.hollow.sh/toolbox/ginauth" +import ( + "github.com/pkg/errors" + + "go.hollow.sh/toolbox/ginauth" +) // NewMultiTokenMiddlewareFromConfigs builds a MultiTokenMiddleware object from multiple AuthConfigs. func NewMultiTokenMiddlewareFromConfigs(cfgs ...AuthConfig) (*ginauth.MultiTokenMiddleware, error) { + if len(cfgs) == 0 { + return nil, errors.Wrap(ErrInvalidAuthConfig, "configuration empty") + } + mtm := &ginauth.MultiTokenMiddleware{} for _, cfg := range cfgs {