summaryrefslogtreecommitdiff
path: root/internal/oidc/flow_client_credentials_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/oidc/flow_client_credentials_test.go')
-rw-r--r--internal/oidc/flow_client_credentials_test.go225
1 files changed, 225 insertions, 0 deletions
diff --git a/internal/oidc/flow_client_credentials_test.go b/internal/oidc/flow_client_credentials_test.go
index 0e1b0ef50..646263340 100644
--- a/internal/oidc/flow_client_credentials_test.go
+++ b/internal/oidc/flow_client_credentials_test.go
@@ -2,15 +2,20 @@ package oidc_test
import (
"context"
+ "errors"
"net/http"
+ "net/url"
"testing"
"time"
"github.com/ory/fosite"
"github.com/ory/fosite/handler/oauth2"
+ "github.com/ory/fosite/handler/openid"
+ fjwt "github.com/ory/fosite/token/jwt"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
+ "github.com/authelia/authelia/v4/internal/clock"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/oidc"
)
@@ -258,3 +263,223 @@ func TestClientCredentialsGrantHandler_PopulateTokenEndpointResponse(t *testing.
})
}
}
+
+func TestPopulateClientCredentialsFlowSessionWithAccessRequest(t *testing.T) {
+ testCases := []struct {
+ name string
+ setup func(ctx oidc.Context)
+ ctx oidc.Context
+ client fosite.Client
+ have *oidc.Session
+ expected *oidc.Session
+ err string
+ }{
+ {
+ "ShouldHandleIssuerError",
+ nil,
+ &TestContext{
+ IssuerURLFunc: func() (issuerURL *url.URL, err error) {
+ return nil, errors.New("an error")
+ },
+ },
+ nil,
+ oidc.NewSession(),
+ nil,
+ "The authorization server encountered an unexpected condition that prevented it from fulfilling the request. Failed to determine the issuer with error: an error.",
+ },
+ {
+ "ShouldHandleClientError",
+ nil,
+ &TestContext{
+ IssuerURLFunc: func() (issuerURL *url.URL, err error) {
+ return &url.URL{Scheme: "https", Host: "example.com"}, nil
+ },
+ },
+ nil,
+ oidc.NewSession(),
+ nil,
+ "The authorization server encountered an unexpected condition that prevented it from fulfilling the request. Failed to get the client for the request.",
+ },
+ {
+ "ShouldUpdateValues",
+ func(ctx oidc.Context) {
+ c := ctx.(*TestContext)
+
+ c.Clock = clock.NewFixed(time.Unix(10000000000, 0))
+ },
+ &TestContext{
+ IssuerURLFunc: func() (issuerURL *url.URL, err error) {
+ return &url.URL{Scheme: "https", Host: "example.com"}, nil
+ },
+ },
+ &oidc.BaseClient{
+ ID: abc,
+ },
+ oidc.NewSession(),
+ &oidc.Session{
+ Extra: map[string]any{},
+ DefaultSession: &openid.DefaultSession{
+ Headers: &fjwt.Headers{
+ Extra: map[string]any{},
+ },
+ Claims: &fjwt.IDTokenClaims{
+ Issuer: "https://example.com",
+ IssuedAt: time.Unix(10000000000, 0).UTC(),
+ RequestedAt: time.Unix(10000000000, 0).UTC(),
+ Subject: abc,
+ Extra: map[string]any{},
+ },
+ },
+ ClientID: abc,
+ ClientCredentials: true,
+ },
+ "",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.setup != nil {
+ tc.setup(tc.ctx)
+ }
+
+ err := oidc.PopulateClientCredentialsFlowSessionWithAccessRequest(tc.ctx, tc.client, tc.have)
+
+ assert.Equal(t, "", tc.have.GetSubject())
+
+ if len(tc.err) == 0 {
+ assert.NoError(t, err)
+ assert.EqualValues(t, tc.expected, tc.have)
+ } else {
+ assert.EqualError(t, oidc.ErrorToDebugRFC6749Error(err), tc.err)
+ }
+ })
+ }
+}
+
+func TestPopulateClientCredentialsFlowRequester(t *testing.T) {
+ testCases := []struct {
+ name string
+ setup func(ctx oidc.Context)
+ ctx oidc.Context
+ config fosite.Configurator
+ client fosite.Client
+ have *fosite.Request
+ expected *fosite.Request
+ err string
+ }{
+ {
+ "ShouldHandleBasic",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{},
+ &fosite.Request{},
+ &fosite.Request{},
+ "",
+ },
+ {
+ "ShouldHandleNilErrorClient",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ nil,
+ &fosite.Request{},
+ &fosite.Request{},
+ "The authorization server encountered an unexpected condition that prevented it from fulfilling the request. Failed to get the client, configuration, or requester for the request.",
+ },
+ {
+ "ShouldHandleBadScopeCombinationAuthz",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOpenID}},
+ &fosite.Request{RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOpenID}},
+ &fosite.Request{},
+ "The requested scope is invalid, unknown, or malformed. The scope 'authelia.bearer.authz' must only be requested by itself or with the 'offline_access' scope, no other scopes are permitted.",
+ },
+ {
+ "ShouldHandleScopeNotPermitted",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz}},
+ &fosite.Request{RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}},
+ &fosite.Request{},
+ "The requested scope is invalid, unknown, or malformed. The scope 'offline_access' is not authorized on client with id 'abc'.",
+ },
+ {
+ "ShouldHandleGoodScopesWithoutAudience",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}},
+ &fosite.Request{RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}},
+ &fosite.Request{},
+ "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Make sure that the various parameters are correct, be aware of case sensitivity and trim your parameters. Make sure that the client you are using has exactly whitelisted the redirect_uri you specified. The scope 'authelia.bearer.authz' requires the request also include an audience.",
+ },
+ {
+ "ShouldHandleGoodScopesAndBadAudience",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}},
+ &fosite.Request{RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}, RequestedAudience: fosite.Arguments{"https://example.com"}},
+ &fosite.Request{},
+ "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Requested audience 'https://example.com' has not been whitelisted by the OAuth 2.0 Client.",
+ },
+ {
+ "ShouldHandleGoodScopesAndAudience",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}, Audience: fosite.Arguments{"https://example.com"}},
+ &fosite.Request{
+ RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ RequestedAudience: fosite.Arguments{"https://example.com"},
+ },
+ &fosite.Request{
+ RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ GrantedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ RequestedAudience: fosite.Arguments{"https://example.com"},
+ GrantedAudience: fosite.Arguments{"https://example.com"},
+ },
+ "",
+ },
+ {
+ "ShouldHandleGoodScopesAndAudienceSubSet",
+ nil,
+ &TestContext{},
+ &oidc.Config{},
+ &oidc.BaseClient{ID: "abc", Scopes: []string{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess}, Audience: fosite.Arguments{"https://example.com", "https://app.example.com"}},
+ &fosite.Request{
+ RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ RequestedAudience: fosite.Arguments{"https://example.com"},
+ },
+ &fosite.Request{
+ RequestedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ GrantedScope: fosite.Arguments{oidc.ScopeAutheliaBearerAuthz, oidc.ScopeOfflineAccess},
+ RequestedAudience: fosite.Arguments{"https://example.com"},
+ GrantedAudience: fosite.Arguments{"https://example.com"},
+ },
+ "",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.setup != nil {
+ tc.setup(tc.ctx)
+ }
+
+ err := oidc.PopulateClientCredentialsFlowRequester(tc.ctx, tc.config, tc.client, tc.have)
+
+ if len(tc.err) == 0 {
+ assert.NoError(t, err)
+ assert.EqualValues(t, tc.expected, tc.have)
+ } else {
+ assert.EqualError(t, oidc.ErrorToDebugRFC6749Error(err), tc.err)
+ }
+ })
+ }
+}