Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(deps): update module github.com/micahparks/keyfunc/v2 to v3 #213

Merged
merged 2 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 54 additions & 36 deletions echojwtx/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (
"net/url"
"time"

"github.com/MicahParks/keyfunc/v2"
"github.com/MicahParks/jwkset"
"github.com/MicahParks/keyfunc/v3"
echojwt "github.com/labstack/echo-jwt/v4"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
Expand All @@ -43,14 +44,14 @@ const (
// ActorKey defines the context key an actor is stored in for an echo context
ActorKey = "actor"

// DefaultKeyFuncOptionRefreshInterval defines the frequency at which the jwks file is refreshed.
DefaultKeyFuncOptionRefreshInterval = time.Hour
// DefaultHTTPClientStorageOptionRefreshInterval defines the frequency at which the jwks file is refreshed.
DefaultHTTPClientStorageOptionRefreshInterval = time.Hour

// DefaultKeyFuncOptionRefreshRateLimit limits how frequently jwks is reloaded when a provided KID is not found.
DefaultKeyFuncOptionRefreshRateLimit = 5 * time.Minute
// DefaultHTTPClientStorageOptionHTTPTimeout limits the runtime of a reload of jwks.
DefaultHTTPClientStorageOptionHTTPTimeout = 10 * time.Second

// DefaultKeyFuncOptionRefreshTimeout limits the runtime of a reload of jwks.
DefaultKeyFuncOptionRefreshTimeout = 10 * time.Second
// DefaultRateLimitWaitMax is the default timeout for waiting for rate limiting to end.
DefaultRateLimitWaitMax = time.Minute
)

var (
Expand All @@ -74,6 +75,9 @@ type AuthConfig struct {

// RefreshTimeout is the timeout for fetching the JWKS from the issuer.
RefreshTimeout time.Duration `mapstructure:"refresh_timeout"`

// RateLimitWaitMax is the timeout for waiting for rate limiting to end.
RateLimitWaitMax time.Duration `mapstructure:"rate_limit_wait_max"`
}

// Auth handles JWT Authentication as echo middleware.
Expand All @@ -85,8 +89,8 @@ type Auth struct {
// JWTConfig configuration for handling JWT validation.
JWTConfig echojwt.Config

// KeyFuncOptions configuration for fetching JWKS.
KeyFuncOptions keyfunc.Options
// HTTPClientStorageOptions configuration for fetching JWKS.
HTTPClientStorageOptions jwkset.HTTPClientStorageOptions

issuer string
audience string
Expand All @@ -106,10 +110,10 @@ func WithJWTConfig(jwtConfig echojwt.Config) Opts {
}
}

// WithKeyFuncOptions sets the KeyFuncOptions for the auth middleware.
func WithKeyFuncOptions(keyFuncOptions keyfunc.Options) Opts {
// WithHTTPClientStorageOptions sets the HTTPClientStorageOptions for the auth middleware.
func WithHTTPClientStorageOptions(options jwkset.HTTPClientStorageOptions) Opts {
return func(a *Auth) {
a.KeyFuncOptions = keyFuncOptions
a.HTTPClientStorageOptions = options
}
}

Expand All @@ -124,7 +128,11 @@ func (a *Auth) setup(ctx context.Context, config AuthConfig, options ...Opts) er
}

if config.RefreshTimeout > 0 {
a.KeyFuncOptions.RefreshTimeout = config.RefreshTimeout
a.HTTPClientStorageOptions.HTTPTimeout = config.RefreshTimeout
}

if config.RateLimitWaitMax == 0 {
config.RateLimitWaitMax = DefaultRateLimitWaitMax
}

a.issuer = config.Issuer
Expand All @@ -136,35 +144,45 @@ func (a *Auth) setup(ctx context.Context, config AuthConfig, options ...Opts) er
return err
}

if a.KeyFuncOptions.Client == nil {
a.KeyFuncOptions.Client = otelhttp.DefaultClient
}

if a.KeyFuncOptions.Ctx == nil {
a.KeyFuncOptions.Ctx = ctx
if a.HTTPClientStorageOptions.Ctx == nil {
a.HTTPClientStorageOptions.Ctx = ctx
}

if a.KeyFuncOptions.RefreshErrorHandler == nil {
a.KeyFuncOptions.RefreshErrorHandler = func(err error) {
if a.HTTPClientStorageOptions.RefreshErrorHandler == nil {
a.HTTPClientStorageOptions.RefreshErrorHandler = func(_ context.Context, err error) {
a.logger.Error("error refreshing jwks", zap.Error(err))
}
}

if a.KeyFuncOptions.RefreshInterval == 0 {
a.KeyFuncOptions.RefreshInterval = DefaultKeyFuncOptionRefreshInterval
if a.HTTPClientStorageOptions.RefreshInterval == 0 {
a.HTTPClientStorageOptions.RefreshInterval = DefaultHTTPClientStorageOptionRefreshInterval
}

if a.HTTPClientStorageOptions.HTTPTimeout == 0 {
a.HTTPClientStorageOptions.HTTPTimeout = DefaultHTTPClientStorageOptionHTTPTimeout
}

storage, err := jwkset.NewStorageFromHTTP(jwksURI, a.HTTPClientStorageOptions)
if err != nil {
return err
}

if a.KeyFuncOptions.RefreshRateLimit == 0 {
a.KeyFuncOptions.RefreshRateLimit = DefaultKeyFuncOptionRefreshRateLimit
clientOptions := jwkset.HTTPClientOptions{
Given: storage,
RateLimitWaitMax: config.RateLimitWaitMax,
}

if a.KeyFuncOptions.RefreshTimeout == 0 {
a.KeyFuncOptions.RefreshTimeout = DefaultKeyFuncOptionRefreshTimeout
clientStorage, err := jwkset.NewHTTPClient(clientOptions)
if err != nil {
return err
}

a.KeyFuncOptions.RefreshUnknownKID = true
keyfuncOptions := keyfunc.Options{
Ctx: ctx,
Storage: clientStorage,
}

jwks, err := keyfunc.Get(jwksURI, a.KeyFuncOptions)
jwks, err := keyfunc.New(keyfuncOptions)
if err != nil {
return err
}
Expand Down Expand Up @@ -224,32 +242,32 @@ func NewAuth(ctx context.Context, config AuthConfig, options ...Opts) (*Auth, er
return auth, nil
}

func jwksURI(ctx context.Context, issuer string) (string, error) {
func jwksURI(ctx context.Context, issuer string) (*url.URL, error) {
uri, err := url.JoinPath(issuer, ".well-known", "openid-configuration")
if err != nil {
return "", err
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return "", err
return nil, err
}

res, err := jwksClient.Do(req)
if err != nil {
return "", err
return nil, err
}
defer res.Body.Close() //nolint:errcheck // no need to check

var m map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&m); err != nil {
return "", err
return nil, err
}

jwksURL, ok := m["jwks_uri"]
if !ok {
return "", ErrJWKSURIMissing
return nil, ErrJWKSURIMissing
}

return jwksURL.(string), nil
return url.Parse(jwksURL.(string))
}
6 changes: 3 additions & 3 deletions echojwtx/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"
"time"

"github.com/MicahParks/keyfunc/v2"
"github.com/MicahParks/jwkset"
"github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -128,8 +128,8 @@ func TestAudienceValidation(t *testing.T) {
Audience: tc.serverAudience,
Issuer: issuer,
},
echojwtx.WithLogger(logger), echojwtx.WithKeyFuncOptions(keyfunc.Options{
RefreshTimeout: 5 * time.Second,
echojwtx.WithLogger(logger), echojwtx.WithHTTPClientStorageOptions(jwkset.HTTPClientStorageOptions{
HTTPTimeout: 5 * time.Second,
}),
)

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ require (
entgo.io/contrib v0.4.5
entgo.io/ent v0.13.1
github.com/99designs/gqlgen v0.17.45
github.com/MicahParks/keyfunc/v2 v2.1.0
github.com/MicahParks/jwkset v0.5.17
github.com/MicahParks/keyfunc/v3 v3.3.2
github.com/XSAM/otelsql v0.29.0
github.com/brianvoe/gofakeit/v6 v6.28.0
github.com/cockroachdb/cockroach-go/v2 v2.3.7
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ github.com/ClickHouse/clickhouse-go/v2 v2.17.1/go.mod h1:rkGTvFDTLqLIm0ma+13xmcC
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
github.com/MicahParks/jwkset v0.5.17 h1:DrcwyKwSP5adD0G2XJTvDulnWXjD6gbjROMgMXDbkKA=
github.com/MicahParks/jwkset v0.5.17/go.mod h1:q8ptTGn/Z9c4MwbcfeCDssADeVQb3Pk7PnVxrvi+2QY=
github.com/MicahParks/keyfunc/v3 v3.3.2 h1:YTtwc4dxalBZKFqHhqctBWN6VhbLdGhywmne9u5RQVM=
github.com/MicahParks/keyfunc/v3 v3.3.2/go.mod h1:GJBeEjnv25OnD9y2OYQa7ELU6gYahEMBNXINZb+qm34=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
Expand Down Expand Up @@ -117,8 +119,6 @@ github.com/gin-contrib/requestid v1.0.0 h1:Ms19AcktabHdXDiMDvsR+PrkBEOtURWliX89n
github.com/gin-contrib/requestid v1.0.0/go.mod h1:311ycyAmroVeV6hDO1Wojooq/jmWfrgqU33M1ncP/TI=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/zap v0.2.0 h1:HLvt3rZXyC8XC+s2lHzMFow3UDqiEbfrBWJyHHS6L8A=
github.com/gin-contrib/zap v0.2.0/go.mod h1:eqfbe9ZmI+GgTZF6nRiC2ZwDeM4DK1Viwc8OxTCphh0=
github.com/gin-contrib/zap v1.1.1 h1:DDyIF9YQorl3gZzAabIowRywHJuohDfiLnhwvWKl6SY=
github.com/gin-contrib/zap v1.1.1/go.mod h1:YW8KOko2kYLy8g6k9YgVNTj7SIcrUEzYiAd9IjiBPs0=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
Expand Down
Loading