mirror of https://github.com/authelia/authelia.git
388 lines
14 KiB
Go
388 lines
14 KiB
Go
package oidc_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"testing"
|
|
"time"
|
|
|
|
"authelia.com/provider/oauth2/handler/oauth2"
|
|
"authelia.com/provider/oauth2/token/jwt"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
|
"github.com/authelia/authelia/v4/internal/model"
|
|
"github.com/authelia/authelia/v4/internal/oidc"
|
|
"github.com/authelia/authelia/v4/internal/templates"
|
|
)
|
|
|
|
func TestConfig_GetAllowedPrompts(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
|
|
assert.Equal(t, []string(nil), config.AllowedPrompts)
|
|
assert.Equal(t, []string{oidc.PromptNone, oidc.PromptLogin, oidc.PromptConsent, oidc.PromptSelectAccount}, config.GetAllowedPrompts(ctx))
|
|
assert.Equal(t, []string{oidc.PromptNone, oidc.PromptLogin, oidc.PromptConsent, oidc.PromptSelectAccount}, config.AllowedPrompts)
|
|
|
|
config.AllowedPrompts = []string{oidc.PromptNone}
|
|
assert.Equal(t, []string{oidc.PromptNone}, config.AllowedPrompts)
|
|
}
|
|
|
|
func TestConfig_PKCE(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
|
|
assert.False(t, config.GetEnforcePKCE(ctx))
|
|
assert.False(t, config.GetEnforcePKCEForPublicClients(ctx))
|
|
|
|
config.ProofKeyCodeExchange.Enforce = true
|
|
assert.True(t, config.GetEnforcePKCE(ctx))
|
|
assert.True(t, config.GetEnforcePKCEForPublicClients(ctx))
|
|
|
|
config.ProofKeyCodeExchange.Enforce = false
|
|
|
|
assert.False(t, config.GetEnforcePKCEForPublicClients(ctx))
|
|
|
|
config.ProofKeyCodeExchange.EnforcePublicClients = true
|
|
|
|
assert.True(t, config.GetEnforcePKCEForPublicClients(ctx))
|
|
|
|
assert.False(t, config.GetEnablePKCEPlainChallengeMethod(ctx))
|
|
config.ProofKeyCodeExchange.AllowPlainChallengeMethod = true
|
|
|
|
assert.True(t, config.GetEnablePKCEPlainChallengeMethod(ctx))
|
|
}
|
|
|
|
func TestConfig_GrantTypeJWTBearer(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
assert.False(t, config.GetGrantTypeJWTBearerIDOptional(ctx))
|
|
assert.False(t, config.GetGrantTypeJWTBearerCanSkipClientAuth(ctx))
|
|
assert.False(t, config.GetGrantTypeJWTBearerIssuedDateOptional(ctx))
|
|
|
|
config.GrantTypeJWTBearer.OptionalJTIClaim = true
|
|
assert.True(t, config.GetGrantTypeJWTBearerIDOptional(ctx))
|
|
assert.False(t, config.GetGrantTypeJWTBearerCanSkipClientAuth(ctx))
|
|
assert.False(t, config.GetGrantTypeJWTBearerIssuedDateOptional(ctx))
|
|
|
|
config.GrantTypeJWTBearer.OptionalClientAuth = true
|
|
assert.True(t, config.GetGrantTypeJWTBearerIDOptional(ctx))
|
|
assert.True(t, config.GetGrantTypeJWTBearerCanSkipClientAuth(ctx))
|
|
assert.False(t, config.GetGrantTypeJWTBearerIssuedDateOptional(ctx))
|
|
|
|
config.GrantTypeJWTBearer.OptionalIssuedDate = true
|
|
assert.True(t, config.GetGrantTypeJWTBearerIDOptional(ctx))
|
|
assert.True(t, config.GetGrantTypeJWTBearerCanSkipClientAuth(ctx))
|
|
assert.True(t, config.GetGrantTypeJWTBearerIssuedDateOptional(ctx))
|
|
}
|
|
|
|
func TestConfig_Durations(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
assert.Equal(t, time.Duration(0), config.JWTMaxDuration)
|
|
assert.Equal(t, time.Hour*24, config.GetJWTMaxDuration(ctx))
|
|
assert.Equal(t, time.Hour*24, config.JWTMaxDuration)
|
|
|
|
assert.Equal(t, time.Duration(0), config.Lifespans.IDToken)
|
|
assert.Equal(t, time.Hour, config.GetIDTokenLifespan(ctx))
|
|
assert.Equal(t, time.Hour, config.Lifespans.IDToken)
|
|
|
|
assert.Equal(t, time.Duration(0), config.Lifespans.AccessToken)
|
|
assert.Equal(t, time.Hour, config.GetAccessTokenLifespan(ctx))
|
|
assert.Equal(t, time.Hour, config.Lifespans.AccessToken)
|
|
|
|
assert.Equal(t, time.Duration(0), config.Lifespans.RefreshToken)
|
|
assert.Equal(t, time.Hour*24*30, config.GetRefreshTokenLifespan(ctx))
|
|
assert.Equal(t, time.Hour*24*30, config.Lifespans.RefreshToken)
|
|
|
|
assert.Equal(t, time.Duration(0), config.Lifespans.AuthorizeCode)
|
|
assert.Equal(t, time.Minute*15, config.GetAuthorizeCodeLifespan(ctx))
|
|
assert.Equal(t, time.Minute*15, config.Lifespans.AuthorizeCode)
|
|
}
|
|
|
|
func TestConfig_GetTokenEntropy(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
|
|
assert.Equal(t, 0, config.TokenEntropy)
|
|
assert.Equal(t, 32, config.GetTokenEntropy(ctx))
|
|
assert.Equal(t, 32, config.TokenEntropy)
|
|
}
|
|
|
|
func TestConfig_Misc(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
|
|
assert.False(t, config.DisableRefreshTokenValidation)
|
|
assert.False(t, config.GetDisableRefreshTokenValidation(ctx))
|
|
|
|
assert.Equal(t, "", config.Issuers.AccessToken)
|
|
assert.Equal(t, "", config.GetAccessTokenIssuer(ctx))
|
|
|
|
assert.Equal(t, "", config.Issuers.IDToken)
|
|
assert.Equal(t, "", config.GetIDTokenIssuer(ctx))
|
|
|
|
assert.Equal(t, jwt.JWTScopeFieldUnset, config.JWTScopeField)
|
|
assert.Equal(t, jwt.JWTScopeFieldList, config.GetJWTScopeField(ctx))
|
|
assert.Equal(t, jwt.JWTScopeFieldList, config.JWTScopeField)
|
|
|
|
assert.Equal(t, []string(nil), config.SanitationWhiteList)
|
|
assert.Equal(t, []string(nil), config.GetSanitationWhiteList(ctx))
|
|
assert.Equal(t, []string(nil), config.SanitationWhiteList)
|
|
|
|
assert.False(t, config.OmitRedirectScopeParameter)
|
|
assert.False(t, config.GetOmitRedirectScopeParam(ctx))
|
|
|
|
assert.NotNil(t, config.GetRedirectSecureChecker(ctx))
|
|
assert.NotNil(t, config.GetHTTPClient(ctx))
|
|
|
|
assert.Nil(t, config.Strategy.Scope)
|
|
assert.NotNil(t, config.GetScopeStrategy(ctx))
|
|
assert.NotNil(t, config.Strategy.Scope)
|
|
|
|
assert.Nil(t, config.Strategy.Audience)
|
|
assert.NotNil(t, config.GetAudienceStrategy(ctx))
|
|
assert.NotNil(t, config.Strategy.Audience)
|
|
|
|
assert.Equal(t, []string(nil), config.RefreshTokenScopes)
|
|
assert.Equal(t, []string{oidc.ScopeOffline, oidc.ScopeOfflineAccess}, config.GetRefreshTokenScopes(ctx))
|
|
assert.Equal(t, []string{oidc.ScopeOffline, oidc.ScopeOfflineAccess}, config.RefreshTokenScopes)
|
|
|
|
assert.Equal(t, 0, config.MinParameterEntropy)
|
|
assert.Equal(t, 8, config.GetMinParameterEntropy(ctx))
|
|
assert.Equal(t, 8, config.MinParameterEntropy)
|
|
|
|
assert.False(t, config.SendDebugMessagesToClients)
|
|
assert.False(t, config.GetSendDebugMessagesToClients(ctx))
|
|
|
|
config.SendDebugMessagesToClients = true
|
|
|
|
assert.True(t, config.GetSendDebugMessagesToClients(ctx))
|
|
|
|
assert.Nil(t, config.Strategy.JWKSFetcher)
|
|
assert.NotNil(t, config.GetJWKSFetcherStrategy(ctx))
|
|
assert.NotNil(t, config.Strategy.JWKSFetcher)
|
|
|
|
assert.Nil(t, config.Strategy.ClientAuthentication)
|
|
assert.Nil(t, config.GetClientAuthenticationStrategy(ctx))
|
|
|
|
assert.Nil(t, config.MessageCatalog)
|
|
assert.Nil(t, config.GetMessageCatalog(ctx))
|
|
|
|
assert.Nil(t, config.Templates)
|
|
assert.Nil(t, config.GetFormPostHTMLTemplate(ctx))
|
|
|
|
var err error
|
|
|
|
config.Templates, err = templates.New(templates.Config{})
|
|
require.NoError(t, err)
|
|
|
|
assert.NotNil(t, config.GetFormPostHTMLTemplate(ctx))
|
|
assert.NotNil(t, config.Templates)
|
|
|
|
assert.False(t, config.GetUseLegacyErrorFormat(ctx))
|
|
|
|
assert.Nil(t, config.GetAuthorizeEndpointHandlers(ctx))
|
|
assert.Nil(t, config.GetTokenEndpointHandlers(ctx))
|
|
assert.Nil(t, config.GetTokenIntrospectionHandlers(ctx))
|
|
assert.Nil(t, config.GetRevocationHandlers(ctx))
|
|
assert.Nil(t, config.GetPushedAuthorizeEndpointHandlers(ctx))
|
|
|
|
assert.Equal(t, []string(nil), config.GetAllowedJWTAssertionAudiences(ctx))
|
|
|
|
var octx context.Context
|
|
|
|
octx = &TestContext{
|
|
Context: ctx,
|
|
IssuerURLFunc: func() (issuerURL *url.URL, err error) {
|
|
return nil, fmt.Errorf("test error")
|
|
},
|
|
}
|
|
|
|
octx = context.WithValue(octx, model.CtxKeyAutheliaCtx, octx)
|
|
|
|
assert.Equal(t, []string(nil), config.GetAllowedJWTAssertionAudiences(octx))
|
|
}
|
|
|
|
func TestConfig_PAR(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
config := &oidc.Config{}
|
|
|
|
assert.Equal(t, "", config.PAR.URIPrefix)
|
|
assert.Equal(t, "urn:ietf:params:oauth:request_uri:", config.GetPushedAuthorizeRequestURIPrefix(ctx))
|
|
assert.Equal(t, "urn:ietf:params:oauth:request_uri:", config.PAR.URIPrefix)
|
|
|
|
assert.False(t, config.PAR.Require)
|
|
assert.False(t, config.GetRequirePushedAuthorizationRequests(ctx))
|
|
assert.False(t, config.PAR.Require)
|
|
|
|
config.PAR.Require = true
|
|
|
|
assert.True(t, config.GetRequirePushedAuthorizationRequests(ctx))
|
|
|
|
assert.Equal(t, time.Duration(0), config.PAR.ContextLifespan)
|
|
assert.Equal(t, time.Minute*5, config.GetPushedAuthorizeContextLifespan(ctx))
|
|
assert.Equal(t, time.Minute*5, config.PAR.ContextLifespan)
|
|
}
|
|
|
|
func TestNewConfig(t *testing.T) {
|
|
c := &schema.IdentityProvidersOpenIDConnect{
|
|
Discovery: schema.IdentityProvidersOpenIDConnectDiscovery{
|
|
JWTResponseAccessTokens: true,
|
|
},
|
|
}
|
|
|
|
tmpl, err := templates.New(templates.Config{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
signer := oidc.NewKeyManager(c)
|
|
|
|
config := oidc.NewConfig(c, signer, tmpl)
|
|
|
|
assert.IsType(t, &oauth2.JWTProfileCoreStrategy{}, config.Strategy.Core)
|
|
|
|
config.LoadHandlers(nil)
|
|
|
|
assert.Len(t, config.Handlers.TokenIntrospection, 1)
|
|
|
|
config.JWTAccessToken.EnableStatelessIntrospection = true
|
|
|
|
config.LoadHandlers(nil)
|
|
|
|
assert.Len(t, config.Handlers.TokenIntrospection, 2)
|
|
}
|
|
|
|
func TestConfig_GetIssuerFuncs(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
have oidc.IssuersConfig
|
|
ctx context.Context
|
|
expectIntrospection, expectIDToken, expectAccessToken, expectAS, expectJARM string
|
|
}{
|
|
{
|
|
"ShouldReturnCtxValues",
|
|
oidc.IssuersConfig{},
|
|
&TestContext{
|
|
Context: context.Background(),
|
|
IssuerURLFunc: func() (issuerURL *url.URL, err error) {
|
|
return &url.URL{Scheme: "https", Host: "example.com", Path: "/issuer"}, nil
|
|
},
|
|
},
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
},
|
|
{
|
|
"ShouldNotReturnDefaultValues",
|
|
oidc.IssuersConfig{
|
|
IDToken: "https://example.com/id-issuer",
|
|
},
|
|
&TestContext{
|
|
Context: context.Background(),
|
|
IssuerURLFunc: func() (issuerURL *url.URL, err error) {
|
|
return &url.URL{Scheme: "https", Host: "example.com", Path: "/issuer"}, nil
|
|
},
|
|
},
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
"https://example.com/issuer",
|
|
},
|
|
{
|
|
"ShouldReturnDefaultValues",
|
|
oidc.IssuersConfig{
|
|
IDToken: "https://example.com/id-issuer",
|
|
AccessToken: "https://example.com/at-issuer",
|
|
Introspection: "https://example.com/i-issuer",
|
|
JWTSecuredResponseMode: "https://example.com/jarm-issuer",
|
|
AuthorizationServerIssuerIdentification: "https://example.com/as-issuer",
|
|
},
|
|
context.Background(),
|
|
"https://example.com/i-issuer",
|
|
"https://example.com/id-issuer",
|
|
"https://example.com/at-issuer",
|
|
"https://example.com/as-issuer",
|
|
"https://example.com/jarm-issuer",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
config := &oidc.Config{
|
|
Issuers: tc.have,
|
|
}
|
|
|
|
ctx := context.WithValue(tc.ctx, 0, 1) //nolint:staticcheck // This value is used to demonstrate a functionality not used for an actual value.
|
|
|
|
assert.Equal(t, tc.expectIntrospection, config.GetIntrospectionIssuer(ctx))
|
|
assert.Equal(t, tc.expectIDToken, config.GetIDTokenIssuer(ctx))
|
|
assert.Equal(t, tc.expectAccessToken, config.GetAccessTokenIssuer(ctx))
|
|
assert.Equal(t, tc.expectAS, config.GetAuthorizationServerIdentificationIssuer(ctx))
|
|
assert.Equal(t, tc.expectJARM, config.GetJWTSecuredAuthorizeResponseModeIssuer(ctx))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMisc(t *testing.T) {
|
|
tctx := &TestContext{
|
|
Context: context.Background(),
|
|
IssuerURLFunc: func() (issuerURL *url.URL, err error) {
|
|
return &url.URL{Scheme: "https", Host: "example.com", Path: "/issuer"}, nil
|
|
},
|
|
}
|
|
|
|
config := &oidc.Config{}
|
|
assert.Nil(t, config.GetIntrospectionJWTResponseSigner(context.Background()))
|
|
assert.Nil(t, config.GetJWTSecuredAuthorizeResponseModeSigner(context.Background()))
|
|
|
|
secret, err := config.GetGlobalSecret(context.Background())
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, secret)
|
|
|
|
secrets, err := config.GetRotatedGlobalSecrets(context.Background())
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, secrets)
|
|
|
|
assert.Equal(t, time.Minute*5, config.GetJWTSecuredAuthorizeResponseModeLifespan(context.Background()))
|
|
|
|
assert.False(t, config.GetRevokeRefreshTokensExplicit(context.Background()))
|
|
assert.False(t, config.GetEnforceRevokeFlowRevokeRefreshTokensExplicitClient(context.Background()))
|
|
assert.False(t, config.GetClientCredentialsFlowImplicitGrantRequested(context.Background()))
|
|
assert.False(t, config.GetEnforceJWTProfileAccessTokens(context.Background()))
|
|
config.ClientCredentialsFlowImplicitGrantRequested = true
|
|
|
|
assert.True(t, config.GetClientCredentialsFlowImplicitGrantRequested(context.Background()))
|
|
|
|
assert.NotNil(t, config.GetHMACHasher(context.Background()))
|
|
assert.NotNil(t, config.GetFormPostResponseWriter(context.Background()))
|
|
|
|
assert.Equal(t, time.Hour, config.GetVerifiableCredentialsNonceLifespan(context.Background()))
|
|
assert.Nil(t, config.GetResponseModeHandlers(context.Background()))
|
|
assert.Nil(t, config.GetResponseModeParameterHandlers(context.Background()))
|
|
assert.Nil(t, config.GetRFC8628DeviceAuthorizeEndpointHandlers(context.Background()))
|
|
assert.Nil(t, config.GetRFC8628UserAuthorizeEndpointHandlers(context.Background()))
|
|
assert.Nil(t, config.GetRFC8693TokenTypes(context.Background()))
|
|
|
|
assert.Equal(t, "", config.GetDefaultRFC8693RequestedTokenType(context.Background()))
|
|
assert.Equal(t, time.Minute*10, config.GetRFC8628CodeLifespan(context.Background()))
|
|
assert.Equal(t, time.Second*10, config.GetRFC8628TokenPollingInterval(context.Background()))
|
|
|
|
assert.Equal(t, []string{"https://example.com/issuer", "https://example.com/issuer/api/oidc/token", "https://example.com/issuer/api/oidc/pushed-authorization-request"}, config.GetAllowedJWTAssertionAudiences(tctx))
|
|
|
|
assert.Equal(t, "https://example.com/issuer/api/oidc/device-code/user-verification", config.GetRFC8628UserVerificationURL(tctx))
|
|
assert.Equal(t, "https://example.com/issuer/api/oidc/device-code/user-verification", config.GetRFC8628UserVerificationURL(tctx))
|
|
}
|