From f2d3317edc275151aa86573329702f83dba29b94 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Sat, 9 Mar 2024 13:59:07 +1100 Subject: [PATCH] refactor: naming --- client.go | 79 ++++++++++--------- client_authentication.go | 12 +-- client_test.go | 4 +- client_with_custom_token_lifespans.go | 11 ++- client_with_custom_token_lifespans_test.go | 2 +- handler/oauth2/revocation.go | 2 +- handler/oauth2/revocation_test.go | 2 +- handler/rfc8693/access_token_type_handler.go | 2 +- handler/rfc8693/client.go | 14 ++-- handler/rfc8693/refresh_token_type_handler.go | 2 +- 10 files changed, 70 insertions(+), 60 deletions(-) diff --git a/client.go b/client.go index b73c7e0e..7f573323 100644 --- a/client.go +++ b/client.go @@ -6,7 +6,6 @@ package oauth2 import ( "context" "fmt" - "github.com/go-jose/go-jose/v3" "authelia.com/provider/oauth2/internal/consts" @@ -15,115 +14,119 @@ import ( // Client represents a client or an app. type Client interface { // GetID returns the client ID. - GetID() string + GetID() (id string) // GetHashedSecret returns the hashed secret as it is stored in the store. - GetHashedSecret() []byte + GetHashedSecret() (secret []byte) // GetRedirectURIs returns the client's allowed redirect URIs. GetRedirectURIs() []string // GetGrantTypes returns the client's allowed grant types. - GetGrantTypes() Arguments + GetGrantTypes() (types Arguments) // GetResponseTypes returns the client's allowed response types. // All allowed combinations of response types have to be listed, each combination having // response types of the combination separated by a space. - GetResponseTypes() Arguments + GetResponseTypes() (types Arguments) // GetScopes returns the scopes this client is allowed to request. - GetScopes() Arguments + GetScopes() (scopes Arguments) // IsPublic returns true, if this client is marked as public. - IsPublic() bool + IsPublic() (public bool) // GetAudience returns the allowed audience(s) for this client. - GetAudience() Arguments + GetAudience() (audience Arguments) } -// ClientWithSecretRotation extends Client interface by a method providing a slice of rotated secrets. -type ClientWithSecretRotation interface { +// RotatedSecretHashesClient extends Client interface by a method providing a slice of rotated secrets. +type RotatedSecretHashesClient interface { + // GetRotatedHashedSecrets returns a slice of hashed secrets used for secrets rotation. + GetRotatedHashedSecrets() (secrets [][]byte) + Client - // GetRotatedHashes returns a slice of hashed secrets used for secrets rotation. - GetRotatedHashes() [][]byte } // ClientAuthenticationPolicyClient is a Client implementation which also provides client authentication policy values. type ClientAuthenticationPolicyClient interface { - Client - // GetAllowMultipleAuthenticationMethods should return true if the client policy allows multiple authentication // methods due to the client implementation breaching RFC6749 Section 2.3. // // See: https://datatracker.ietf.org/doc/html/rfc6749#section-2.3. - GetAllowMultipleAuthenticationMethods(ctx context.Context) bool + GetAllowMultipleAuthenticationMethods(ctx context.Context) (allow bool) + + Client } // OpenIDConnectClient represents a client capable of performing OpenID Connect requests. type OpenIDConnectClient interface { - Client - // GetRequestURIs is an array of request_uri values that are pre-registered by the RP for use at the OP. Servers MAY // cache the contents of the files referenced by these URIs and not retrieve them at the time they are used in a request. // OPs can require that request_uri values used be pre-registered with the require_request_uri_registration // discovery parameter. - GetRequestURIs() []string + GetRequestURIs() (requestURIs []string) // GetJSONWebKeys returns the JSON Web Key Set containing the public key used by the client to authenticate. - GetJSONWebKeys() *jose.JSONWebKeySet + GetJSONWebKeys() (jwks *jose.JSONWebKeySet) // GetJSONWebKeysURI returns the URL for lookup of JSON Web Key Set containing the // public key used by the client to authenticate. - GetJSONWebKeysURI() string + GetJSONWebKeysURI() (uri string) - // JWS [JWS] alg algorithm [JWA] that MUST be used for signing Request Objects sent to the OP. - // All Request Objects from this Client MUST be rejected, if not signed with this algorithm. - GetRequestObjectSigningAlgorithm() string + // GetRequestObjectSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing Request + // Objects sent to the OP. All Request Objects from this Client MUST be rejected, if not signed with this algorithm. + GetRequestObjectSigningAlgorithm() (alg string) - // Requested Client Authentication method for the Token Endpoint. The options are client_secret_post, - // client_secret_basic, client_secret_jwt, private_key_jwt, and none. - GetTokenEndpointAuthMethod() string + // GetTokenEndpointAuthMethod requested Client Authentication method for the Token Endpoint. The options are + // client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none. + GetTokenEndpointAuthMethod() (method string) - // JWS [JWS] alg algorithm [JWA] that MUST be used for signing the JWT [JWT] used to authenticate the - // Client at the Token Endpoint for the private_key_jwt and client_secret_jwt authentication methods. - GetTokenEndpointAuthSigningAlgorithm() string + // GetTokenEndpointAuthSigningAlgorithm returns the JWS [JWS] alg algorithm [JWA] that MUST be used for signing the + // JWT [JWT] used to authenticate the Client at the Token Endpoint for the private_key_jwt and client_secret_jwt + // authentication methods. + GetTokenEndpointAuthSigningAlgorithm() (alg string) // GetSecretPlainText returns the client secret in plain text. // This is used to validate the 'token_endpoint_client_auth_method' with a value of 'client_secret_jwt'. If this // client does NOT have a plain text secret then it MUST return an error. GetSecretPlainText() (secret []byte, err error) + + Client } // RefreshFlowScopeClient is a client which can be customized to ignore scopes that were not originally granted. type RefreshFlowScopeClient interface { - Client - GetRefreshFlowIgnoreOriginalGrantedScopes(ctx context.Context) (ignoreOriginalGrantedScopes bool) + + Client } // RevokeFlowRevokeRefreshTokensExplicitClient is a client which can be customized to only revoke Refresh Tokens // explicitly. type RevokeFlowRevokeRefreshTokensExplicitClient interface { - Client + // GetRevokeRefreshTokensExplicit returns true if this client will only revoke refresh tokens explicitly. + GetRevokeRefreshTokensExplicit(ctx context.Context) (explicit bool) - // GetRevokeRefreshTokensExplicitly returns true if this client will only revoke refresh tokens explicitly. - GetRevokeRefreshTokensExplicitly(ctx context.Context) bool + Client } // JARMClient is a client which supports JARM. type JARMClient interface { - Client - GetAuthorizationSignedResponseKeyID() (kid string) GetAuthorizationSignedResponseAlg() (alg string) GetAuthorizationEncryptedResponseAlg() (alg string) GetAuthorizationEncryptedResponseEncryptionAlg() (alg string) + + Client } // ResponseModeClient represents a client capable of handling response_mode type ResponseModeClient interface { // GetResponseModes returns the response modes that client is allowed to send - GetResponseModes() []ResponseModeType + GetResponseModes() (modes []ResponseModeType) + + Client } // DefaultClient is a simple default implementation of the Client interface. @@ -174,7 +177,7 @@ func (c *DefaultClient) GetHashedSecret() []byte { return c.Secret } -func (c *DefaultClient) GetRotatedHashes() [][]byte { +func (c *DefaultClient) GetRotatedHashedSecrets() [][]byte { return c.RotatedSecrets } diff --git a/client_authentication.go b/client_authentication.go index d74eaed8..968ef33d 100644 --- a/client_authentication.go +++ b/client_authentication.go @@ -169,15 +169,15 @@ func (s *DefaultClientAuthenticationStrategy) doAuthenticateClientSecret(ctx con } var ( - clientwsr ClientWithSecretRotation - ok bool + rclient RotatedSecretHashesClient + ok bool ) - if clientwsr, ok = client.(ClientWithSecretRotation); !ok { + if rclient, ok = client.(RotatedSecretHashesClient); !ok { return nil, "", err } - for _, hash := range clientwsr.GetRotatedHashes() { + for _, hash := range rclient.GetRotatedHashedSecrets() { if hasher.Compare(ctx, hash, value) == nil { return client, method, nil } @@ -597,11 +597,11 @@ func (f *Fosite) checkClientSecret(ctx context.Context, client Client, clientSec return nil } - cc, ok := client.(ClientWithSecretRotation) + cc, ok := client.(RotatedSecretHashesClient) if !ok { return err } - for _, hash := range cc.GetRotatedHashes() { + for _, hash := range cc.GetRotatedHashedSecrets() { err = f.Config.GetSecretsHasher(ctx).Compare(ctx, hash, clientSecret) if err == nil { return nil diff --git a/client_test.go b/client_test.go index 83ed8d7a..6b55b97b 100644 --- a/client_test.go +++ b/client_test.go @@ -25,7 +25,7 @@ func TestDefaultClient(t *testing.T) { assert.Equal(t, sc.ID, sc.GetID()) assert.Equal(t, sc.RedirectURIs, sc.GetRedirectURIs()) assert.Equal(t, sc.Secret, sc.GetHashedSecret()) - assert.Equal(t, sc.RotatedSecrets, sc.GetRotatedHashes()) + assert.Equal(t, sc.RotatedSecrets, sc.GetRotatedHashedSecrets()) assert.EqualValues(t, sc.ResponseTypes, sc.GetResponseTypes()) assert.EqualValues(t, sc.GrantTypes, sc.GetGrantTypes()) assert.EqualValues(t, sc.Scopes, sc.GetScopes()) @@ -35,7 +35,7 @@ func TestDefaultClient(t *testing.T) { assert.Equal(t, consts.ResponseTypeAuthorizationCodeFlow, sc.GetResponseTypes()[0]) assert.Equal(t, consts.GrantTypeAuthorizationCode, sc.GetGrantTypes()[0]) - var _ ClientWithSecretRotation = sc + var _ RotatedSecretHashesClient = sc } func TestDefaultResponseModeClient_GetResponseMode(t *testing.T) { diff --git a/client_with_custom_token_lifespans.go b/client_with_custom_token_lifespans.go index adfd58f2..936912ef 100644 --- a/client_with_custom_token_lifespans.go +++ b/client_with_custom_token_lifespans.go @@ -8,16 +8,19 @@ import ( ) // GetEffectiveLifespan either maps GrantType x TokenType to the client's configured lifespan, or returns the fallback value. -func GetEffectiveLifespan(c Client, gt GrantType, tt TokenType, fallback time.Duration) time.Duration { - if clc, ok := c.(ClientWithCustomTokenLifespans); ok { +func GetEffectiveLifespan(c Client, gt GrantType, tt TokenType, fallback time.Duration) (lifespan time.Duration) { + if clc, ok := c.(CustomTokenLifespansClient); ok { return clc.GetEffectiveLifespan(gt, tt, fallback) } return fallback } -type ClientWithCustomTokenLifespans interface { +// CustomTokenLifespansClient is a Client with specific lifespans. +type CustomTokenLifespansClient interface { // GetEffectiveLifespan either maps GrantType x TokenType to the client's configured lifespan, or returns the fallback value. - GetEffectiveLifespan(gt GrantType, tt TokenType, fallback time.Duration) time.Duration + GetEffectiveLifespan(gt GrantType, tt TokenType, fallback time.Duration) (lifespan time.Duration) + + Client } // ClientLifespanConfig holds default lifespan configuration for the different diff --git a/client_with_custom_token_lifespans_test.go b/client_with_custom_token_lifespans_test.go index ae9377bb..e62e7237 100644 --- a/client_with_custom_token_lifespans_test.go +++ b/client_with_custom_token_lifespans_test.go @@ -25,5 +25,5 @@ func TestDefaultClientWithCustomTokenLifespans(t *testing.T) { assert.NotEqual(t, clc.GetTokenLifespans(), nil) require.Equal(t, customLifespan, GetEffectiveLifespan(clc, GrantTypeImplicit, IDToken, time.Minute*42)) - var _ ClientWithCustomTokenLifespans = clc + var _ CustomTokenLifespansClient = clc } diff --git a/handler/oauth2/revocation.go b/handler/oauth2/revocation.go index ff36af0c..0912d124 100644 --- a/handler/oauth2/revocation.go +++ b/handler/oauth2/revocation.go @@ -89,7 +89,7 @@ func (r *TokenRevocationHandler) getRevokeRefreshTokensExplicitly(ctx context.Co return r.Config.GetRevokeRefreshTokensExplicitly(ctx) } - if ok = c.GetRevokeRefreshTokensExplicitly(ctx); ok || r.Config.GetEnforceRevokeFlowRevokeRefreshTokensExplicitClient(ctx) { + if ok = c.GetRevokeRefreshTokensExplicit(ctx); ok || r.Config.GetEnforceRevokeFlowRevokeRefreshTokensExplicitClient(ctx) { return ok } diff --git a/handler/oauth2/revocation_test.go b/handler/oauth2/revocation_test.go index fee5087b..64b36f10 100644 --- a/handler/oauth2/revocation_test.go +++ b/handler/oauth2/revocation_test.go @@ -543,6 +543,6 @@ type ExplicitClient struct { RevokeRefreshTokensExplicitly bool } -func (c *ExplicitClient) GetRevokeRefreshTokensExplicitly(ctx context.Context) bool { +func (c *ExplicitClient) GetRevokeRefreshTokensExplicit(ctx context.Context) bool { return c.RevokeRefreshTokensExplicitly } diff --git a/handler/rfc8693/access_token_type_handler.go b/handler/rfc8693/access_token_type_handler.go index f12cb0da..e494daf1 100644 --- a/handler/rfc8693/access_token_type_handler.go +++ b/handler/rfc8693/access_token_type_handler.go @@ -126,7 +126,7 @@ func (c *AccessTokenTypeHandler) validate(ctx context.Context, request oauth2.Ac // Check if the client is allowed to exchange this token if subjectTokenClient, ok := or.GetClient().(Client); ok { - allowed := subjectTokenClient.TokenExchangeAllowed(client) + allowed := subjectTokenClient.GetTokenExchangePermitted(client) if !allowed { return nil, nil, errors.WithStack(oauth2.ErrRequestForbidden.WithHintf( "The OAuth 2.0 client is not permitted to exchange a subject token issued to client %s", subjectTokenClientID)) diff --git a/handler/rfc8693/client.go b/handler/rfc8693/client.go index 59ceea4b..f9fe8ee0 100644 --- a/handler/rfc8693/client.go +++ b/handler/rfc8693/client.go @@ -2,14 +2,18 @@ package rfc8693 import "authelia.com/provider/oauth2" +// Client is a representation of a client that may support RFC8693. type Client interface { // GetSupportedSubjectTokenTypes indicates the token types allowed for subject_token - GetSupportedSubjectTokenTypes() []string + GetSupportedSubjectTokenTypes() (types []string) + // GetSupportedActorTokenTypes indicates the token types allowed for subject_token - GetSupportedActorTokenTypes() []string + GetSupportedActorTokenTypes() (types []string) + // GetSupportedRequestTokenTypes indicates the token types allowed for requested_token_type - GetSupportedRequestTokenTypes() []string - // TokenExchangeAllowed checks if the subject token client allows the specified client + GetSupportedRequestTokenTypes() (types []string) + + // GetTokenExchangePermitted checks if the subject token client allows the specified client // to perform the exchange - TokenExchangeAllowed(client oauth2.Client) bool + GetTokenExchangePermitted(client oauth2.Client) (allowed bool) } diff --git a/handler/rfc8693/refresh_token_type_handler.go b/handler/rfc8693/refresh_token_type_handler.go index 31f68e53..aed78a9a 100644 --- a/handler/rfc8693/refresh_token_type_handler.go +++ b/handler/rfc8693/refresh_token_type_handler.go @@ -124,7 +124,7 @@ func (c *RefreshTokenTypeHandler) validate(ctx context.Context, request oauth2.A // Check if the client is allowed to exchange this token if subjectTokenClient, ok := or.GetClient().(Client); ok { - allowed := subjectTokenClient.TokenExchangeAllowed(client) + allowed := subjectTokenClient.GetTokenExchangePermitted(client) if !allowed { return nil, nil, errors.WithStack(oauth2.ErrRequestForbidden.WithHintf( "The OAuth 2.0 client is not permitted to exchange a subject token issued to client %s", tokenClientID))