authelia/internal/oidc/store_test.go

667 lines
23 KiB
Go
Raw Permalink Normal View History

package oidc_test
2022-04-12 03:02:12 +00:00
import (
"context"
"database/sql"
"encoding/json"
"fmt"
2022-04-12 03:02:12 +00:00
"testing"
"time"
2022-04-12 03:02:12 +00:00
"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/ory/fosite"
2022-04-12 03:02:12 +00:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2022-04-12 03:02:12 +00:00
"github.com/authelia/authelia/v4/internal/authorization"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/mocks"
"github.com/authelia/authelia/v4/internal/model"
"github.com/authelia/authelia/v4/internal/oidc"
"github.com/authelia/authelia/v4/internal/storage"
2022-04-12 03:02:12 +00:00
)
func TestOpenIDConnectStore_GetClientPolicy(t *testing.T) {
s := oidc.NewStore(&schema.OpenIDConnectConfiguration{
IssuerCertificateChain: schema.X509CertificateChain{},
IssuerPrivateKey: keyRSA2048,
Clients: []schema.OpenIDConnectClientConfiguration{
{
ID: myclient,
Description: myclientdesc,
Policy: onefactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
},
{
ID: "myotherclient",
Description: myclientdesc,
Policy: twofactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
},
},
2022-04-12 03:02:12 +00:00
}, nil)
policyOne := s.GetClientPolicy(myclient)
assert.Equal(t, authorization.OneFactor, policyOne)
policyTwo := s.GetClientPolicy("myotherclient")
assert.Equal(t, authorization.TwoFactor, policyTwo)
policyInvalid := s.GetClientPolicy("invalidclient")
assert.Equal(t, authorization.TwoFactor, policyInvalid)
}
func TestOpenIDConnectStore_GetInternalClient(t *testing.T) {
s := oidc.NewStore(&schema.OpenIDConnectConfiguration{
IssuerCertificateChain: schema.X509CertificateChain{},
IssuerPrivateKey: keyRSA2048,
Clients: []schema.OpenIDConnectClientConfiguration{
{
ID: myclient,
Description: myclientdesc,
Policy: onefactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
},
},
2022-04-12 03:02:12 +00:00
}, nil)
client, err := s.GetClient(context.Background(), "myinvalidclient")
assert.EqualError(t, err, "invalid_client")
assert.Nil(t, client)
client, err = s.GetClient(context.Background(), myclient)
require.NoError(t, err)
require.NotNil(t, client)
assert.Equal(t, myclient, client.GetID())
}
func TestOpenIDConnectStore_GetInternalClient_ValidClient(t *testing.T) {
id := myclient
c1 := schema.OpenIDConnectClientConfiguration{
ID: id,
Description: myclientdesc,
Policy: onefactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
}
s := oidc.NewStore(&schema.OpenIDConnectConfiguration{
IssuerCertificateChain: schema.X509CertificateChain{},
IssuerPrivateKey: keyRSA2048,
Clients: []schema.OpenIDConnectClientConfiguration{c1},
2022-04-12 03:02:12 +00:00
}, nil)
client, err := s.GetFullClient(id)
require.NoError(t, err)
require.NotNil(t, client)
assert.Equal(t, id, client.GetID())
assert.Equal(t, myclientdesc, client.GetDescription())
assert.Equal(t, fosite.Arguments(c1.Scopes), client.GetScopes())
assert.Equal(t, fosite.Arguments([]string{oidc.GrantTypeAuthorizationCode}), client.GetGrantTypes())
assert.Equal(t, fosite.Arguments([]string{oidc.ResponseTypeAuthorizationCodeFlow}), client.GetResponseTypes())
assert.Equal(t, []string(nil), client.GetRedirectURIs())
assert.Equal(t, authorization.OneFactor, client.GetAuthorizationPolicy())
assert.Equal(t, "$plaintext$client-secret", client.GetSecret().Encode())
}
func TestOpenIDConnectStore_GetInternalClient_InvalidClient(t *testing.T) {
c1 := schema.OpenIDConnectClientConfiguration{
ID: myclient,
Description: myclientdesc,
Policy: onefactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
}
s := oidc.NewStore(&schema.OpenIDConnectConfiguration{
IssuerCertificateChain: schema.X509CertificateChain{},
IssuerPrivateKey: keyRSA2048,
Clients: []schema.OpenIDConnectClientConfiguration{c1},
2022-04-12 03:02:12 +00:00
}, nil)
client, err := s.GetFullClient("another-client")
assert.Nil(t, client)
assert.EqualError(t, err, "invalid_client")
}
func TestOpenIDConnectStore_IsValidClientID(t *testing.T) {
s := oidc.NewStore(&schema.OpenIDConnectConfiguration{
IssuerCertificateChain: schema.X509CertificateChain{},
IssuerPrivateKey: keyRSA2048,
Clients: []schema.OpenIDConnectClientConfiguration{
{
ID: myclient,
Description: myclientdesc,
Policy: onefactor,
Scopes: []string{oidc.ScopeOpenID, oidc.ScopeProfile},
Secret: tOpenIDConnectPlainTextClientSecret,
},
},
2022-04-12 03:02:12 +00:00
}, nil)
validClient := s.IsValidClientID(myclient)
invalidClient := s.IsValidClientID("myinvalidclient")
assert.True(t, validClient)
assert.False(t, invalidClient)
2022-04-12 03:02:12 +00:00
}
func TestStoreSuite(t *testing.T) {
suite.Run(t, &StoreSuite{})
}
type StoreSuite struct {
suite.Suite
ctx context.Context
ctrl *gomock.Controller
mock *mocks.MockStorage
store *oidc.Store
}
func (s *StoreSuite) SetupTest() {
s.ctx = context.Background()
s.ctrl = gomock.NewController(s.T())
s.mock = mocks.NewMockStorage(s.ctrl)
s.store = oidc.NewStore(&schema.OpenIDConnectConfiguration{
Clients: []schema.OpenIDConnectClientConfiguration{
{
ID: "hs256",
Secret: tOpenIDConnectPBKDF2ClientSecret,
Policy: authorization.OneFactor.String(),
RedirectURIs: []string{
"https://client.example.com",
},
TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT,
TokenEndpointAuthSigningAlg: oidc.SigningAlgHMACUsingSHA256,
},
}}, s.mock)
}
func (s *StoreSuite) TestGetSubject() {
s.T().Run("GenerateNew", func(t *testing.T) {
s.mock.
EXPECT().
LoadUserOpaqueIdentifierBySignature(s.ctx, "openid", "", "john").
Return(nil, nil)
s.mock.
EXPECT().
SaveUserOpaqueIdentifier(s.ctx, gomock.Any()).
Return(nil)
opaqueID, err := s.store.GetSubject(s.ctx, "", "john")
assert.NoError(t, err)
assert.NotEqual(t, uint32(0), opaqueID)
})
s.T().Run("ReturnDatabaseErrorOnLoad", func(t *testing.T) {
s.mock.
EXPECT().
LoadUserOpaqueIdentifierBySignature(s.ctx, "openid", "", "john").
Return(nil, fmt.Errorf("failed to load"))
opaqueID, err := s.store.GetSubject(s.ctx, "", "john")
assert.EqualError(t, err, "failed to load")
assert.Equal(t, uint32(0), opaqueID.ID())
})
s.T().Run("ReturnDatabaseErrorOnSave", func(t *testing.T) {
s.mock.
EXPECT().
LoadUserOpaqueIdentifierBySignature(s.ctx, "openid", "", "john").
Return(nil, nil)
s.mock.
EXPECT().
SaveUserOpaqueIdentifier(s.ctx, gomock.Any()).
Return(fmt.Errorf("failed to save"))
opaqueID, err := s.store.GetSubject(s.ctx, "", "john")
assert.EqualError(t, err, "failed to save")
assert.Equal(t, uint32(0), opaqueID.ID())
})
}
func (s *StoreSuite) TestTx() {
gomock.InOrder(
s.mock.EXPECT().BeginTX(s.ctx).Return(s.ctx, nil),
s.mock.EXPECT().Commit(s.ctx).Return(nil),
s.mock.EXPECT().Rollback(s.ctx).Return(nil),
s.mock.EXPECT().BeginTX(s.ctx).Return(nil, fmt.Errorf("failed to begin")),
s.mock.EXPECT().Commit(s.ctx).Return(fmt.Errorf("failed to commit")),
s.mock.EXPECT().Rollback(s.ctx).Return(fmt.Errorf("failed to rollback")),
)
x, err := s.store.BeginTX(s.ctx)
s.Equal(s.ctx, x)
s.NoError(err)
s.NoError(s.store.Commit(s.ctx))
s.NoError(s.store.Rollback(s.ctx))
x, err = s.store.BeginTX(s.ctx)
s.Equal(nil, x)
s.EqualError(err, "failed to begin")
s.EqualError(s.store.Commit(s.ctx), "failed to commit")
s.EqualError(s.store.Rollback(s.ctx), "failed to rollback")
}
func (s *StoreSuite) TestClientAssertionJWTValid() {
gomock.InOrder(
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "3a240379e8286a7a8ff5e99d68567e0e5e34e80168b8feffa89d3d33dea95b63").
Return(&model.OAuth2BlacklistedJTI{
ID: 1,
Signature: "3a240379e8286a7a8ff5e99d68567e0e5e34e80168b8feffa89d3d33dea95b63",
ExpiresAt: time.Now().Add(time.Hour),
}, nil),
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "e7f67ad76c80d57d34b19598462817932aec21d2806a08a786a8d4b9dd476068").
Return(&model.OAuth2BlacklistedJTI{
ID: 1,
Signature: "e7f67ad76c80d57d34b19598462817932aec21d2806a08a786a8d4b9dd476068",
ExpiresAt: time.Now().Add(-time.Hour),
}, nil),
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "f29ef0d85303a09411b76001c579980f1b1b7fc9deb1fa647875a724f4f231c6").
Return(nil, fmt.Errorf("failed to load")),
)
s.EqualError(s.store.ClientAssertionJWTValid(s.ctx, "066ee771-e156-4886-b99f-ee09b0d3edf4"), "jti_known")
s.NoError(s.store.ClientAssertionJWTValid(s.ctx, "5dad3ff7-e4f2-41b6-98a3-b73d872076ce"))
s.EqualError(s.store.ClientAssertionJWTValid(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202"), "failed to load")
}
func (s *StoreSuite) TestCreateSessions() {
challenge := uuid.Must(uuid.NewRandom())
session := &model.OpenIDSession{
ChallengeID: challenge,
}
sessionData, _ := json.Marshal(session)
gomock.InOrder(
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(nil),
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(fmt.Errorf("duplicate key")),
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypeAccessToken, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(nil),
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypeRefreshToken, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(nil),
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypeOpenIDConnect, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(nil),
s.mock.
EXPECT().
SaveOAuth2Session(s.ctx, storage.OAuth2SessionTypePKCEChallenge, model.OAuth2Session{ChallengeID: challenge, RequestID: "abc", ClientID: "example", Signature: "abc", Active: true, Session: sessionData}).
Return(nil),
s.mock.
EXPECT().
SaveOAuth2PARContext(s.ctx, model.OAuth2PARContext{Signature: "abc", RequestID: "abc", ClientID: "example", Session: sessionData}).
Return(nil),
)
s.NoError(s.store.CreateAuthorizeCodeSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}))
s.EqualError(s.store.CreateAuthorizeCodeSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}), "duplicate key")
s.EqualError(s.store.CreateAuthorizeCodeSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: nil,
}), "can't convert type '<nil>' to an *OAuth2Session")
s.NoError(s.store.CreateAccessTokenSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}))
s.NoError(s.store.CreateRefreshTokenSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}))
s.NoError(s.store.CreateOpenIDConnectSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}))
s.NoError(s.store.CreatePKCERequestSession(s.ctx, "abc", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}))
s.NoError(s.store.CreatePARSession(s.ctx, "abc", &fosite.AuthorizeRequest{
Request: fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
}}))
s.EqualError(s.store.CreatePARSession(s.ctx, "abc", &fosite.AuthorizeRequest{
Request: fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: nil,
}}), "can't convert type '<nil>' to an *OAuth2Session")
}
func (s *StoreSuite) TestRevokeSessions() {
gomock.InOrder(
s.mock.
EXPECT().
DeactivateOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "abc1").
Return(nil),
s.mock.
EXPECT().
DeactivateOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "abc2").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeAccessToken, "at_example1").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeAccessToken, "at_example2").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
RevokeOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeAccessToken, "65471ccb-d650-4006-a95f-cb4f4e3d7200").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeAccessToken, "65471ccb-d650-4006-a95f-cb4f4e3d7201").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
RevokeOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeAccessToken, "65471ccb-d650-4006-a95f-cb4f4e3d7202").
Return(sql.ErrNoRows),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeRefreshToken, "rt_example1").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeRefreshToken, "rt_example2").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7200").
Return(nil),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7201").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7202").
Return(sql.ErrNoRows),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7200").
Return(nil),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7201").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
DeactivateOAuth2SessionByRequestID(s.ctx, storage.OAuth2SessionTypeRefreshToken, "65471ccb-d650-4006-a95f-cb4f4e3d7202").
Return(sql.ErrNoRows),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypePKCEChallenge, "pkce1").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypePKCEChallenge, "pkce2").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeOpenIDConnect, "ac_1").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2Session(s.ctx, storage.OAuth2SessionTypeOpenIDConnect, "ac_2").
Return(fmt.Errorf("not found")),
s.mock.
EXPECT().
RevokeOAuth2PARContext(s.ctx, "urn:par1").
Return(nil),
s.mock.
EXPECT().
RevokeOAuth2PARContext(s.ctx, "urn:par2").
Return(fmt.Errorf("not found")),
)
s.NoError(s.store.InvalidateAuthorizeCodeSession(s.ctx, "abc1"))
s.EqualError(s.store.InvalidateAuthorizeCodeSession(s.ctx, "abc2"), "not found")
s.NoError(s.store.DeleteAccessTokenSession(s.ctx, "at_example1"))
s.EqualError(s.store.DeleteAccessTokenSession(s.ctx, "at_example2"), "not found")
s.NoError(s.store.RevokeAccessToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7200"))
s.EqualError(s.store.RevokeAccessToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7201"), "not found")
s.EqualError(s.store.RevokeAccessToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202"), "not_found")
s.NoError(s.store.DeleteRefreshTokenSession(s.ctx, "rt_example1"))
s.EqualError(s.store.DeleteRefreshTokenSession(s.ctx, "rt_example2"), "not found")
s.NoError(s.store.RevokeRefreshToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7200"))
s.EqualError(s.store.RevokeRefreshToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7201"), "not found")
s.EqualError(s.store.RevokeRefreshToken(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202"), "sql: no rows in result set")
s.NoError(s.store.RevokeRefreshTokenMaybeGracePeriod(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7200", "1"))
s.EqualError(s.store.RevokeRefreshTokenMaybeGracePeriod(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7201", "2"), "not found")
s.EqualError(s.store.RevokeRefreshTokenMaybeGracePeriod(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202", "3"), "sql: no rows in result set")
s.NoError(s.store.DeletePKCERequestSession(s.ctx, "pkce1"))
s.EqualError(s.store.DeletePKCERequestSession(s.ctx, "pkce2"), "not found")
s.NoError(s.store.DeleteOpenIDConnectSession(s.ctx, "ac_1"))
s.EqualError(s.store.DeleteOpenIDConnectSession(s.ctx, "ac_2"), "not found")
s.NoError(s.store.DeletePARSession(s.ctx, "urn:par1"))
s.EqualError(s.store.DeletePARSession(s.ctx, "urn:par2"), "not found")
}
func (s *StoreSuite) TestGetSessions() {
challenge := uuid.Must(uuid.NewRandom())
session := &model.OpenIDSession{
ChallengeID: challenge,
ClientID: "hs256",
}
sessionData, _ := json.Marshal(session)
sessionb := &model.OpenIDSession{
ChallengeID: challenge,
ClientID: "hs256",
}
sessionDatab, _ := json.Marshal(sessionb)
gomock.InOrder(
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "ac_123").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: true}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "ac_456").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: false}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "ac_aaa").
Return(nil, sql.ErrNoRows),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "ac_130").
Return(nil, fmt.Errorf("timeout")),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAuthorizeCode, "ac_badclient").
Return(&model.OAuth2Session{ClientID: "no-client", Session: sessionDatab, Active: true}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeAccessToken, "at").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: true}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeRefreshToken, "rt").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: true}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypePKCEChallenge, "pkce").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: true}, nil),
s.mock.EXPECT().LoadOAuth2Session(s.ctx, storage.OAuth2SessionTypeOpenIDConnect, "ot").
Return(&model.OAuth2Session{ClientID: "hs256", Session: sessionData, Active: true}, nil),
s.mock.
EXPECT().
LoadOAuth2PARContext(s.ctx, "urn:par").
Return(&model.OAuth2PARContext{Signature: "abc", RequestID: "abc", ClientID: "hs256", Session: sessionData}, nil),
s.mock.
EXPECT().
LoadOAuth2PARContext(s.ctx, "urn:par").
Return(nil, sql.ErrNoRows),
)
var (
r fosite.Requester
err error
)
r, err = s.store.GetAuthorizeCodeSession(s.ctx, "ac_123", &model.OpenIDSession{})
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetAuthorizeCodeSession(s.ctx, "ac_456", &model.OpenIDSession{})
s.NotNil(r)
s.EqualError(err, "Authorization code has ben invalidated")
r, err = s.store.GetAuthorizeCodeSession(s.ctx, "ac_aaa", &model.OpenIDSession{})
s.Nil(r)
s.EqualError(err, "not_found")
r, err = s.store.GetAuthorizeCodeSession(s.ctx, "ac_130", &model.OpenIDSession{})
s.Nil(r)
s.EqualError(err, "timeout")
r, err = s.store.GetAuthorizeCodeSession(s.ctx, "ac_badclient", &model.OpenIDSession{})
s.Nil(r)
s.EqualError(err, "invalid_client")
r, err = s.store.GetAccessTokenSession(s.ctx, "at", &model.OpenIDSession{})
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetRefreshTokenSession(s.ctx, "rt", &model.OpenIDSession{})
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetPKCERequestSession(s.ctx, "pkce", &model.OpenIDSession{})
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetOpenIDConnectSession(s.ctx, "ot", &fosite.Request{
ID: "abc",
Client: &oidc.BaseClient{
ID: "example",
},
Session: session,
})
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetPARSession(s.ctx, "urn:par")
s.NotNil(r)
s.NoError(err)
r, err = s.store.GetPARSession(s.ctx, "urn:par")
s.Nil(r)
s.EqualError(err, "sql: no rows in result set")
}
func (s *StoreSuite) TestIsJWTUsed() {
gomock.InOrder(
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "3a240379e8286a7a8ff5e99d68567e0e5e34e80168b8feffa89d3d33dea95b63").
Return(&model.OAuth2BlacklistedJTI{
ID: 1,
Signature: "3a240379e8286a7a8ff5e99d68567e0e5e34e80168b8feffa89d3d33dea95b63",
ExpiresAt: time.Now().Add(time.Hour),
}, nil),
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "e7f67ad76c80d57d34b19598462817932aec21d2806a08a786a8d4b9dd476068").
Return(&model.OAuth2BlacklistedJTI{
ID: 1,
Signature: "e7f67ad76c80d57d34b19598462817932aec21d2806a08a786a8d4b9dd476068",
ExpiresAt: time.Now().Add(-time.Hour),
}, nil),
s.mock.
EXPECT().
LoadOAuth2BlacklistedJTI(s.ctx, "f29ef0d85303a09411b76001c579980f1b1b7fc9deb1fa647875a724f4f231c6").
Return(nil, fmt.Errorf("failed to load")),
)
used, err := s.store.IsJWTUsed(s.ctx, "066ee771-e156-4886-b99f-ee09b0d3edf4")
s.True(used)
s.EqualError(err, "jti_known")
used, err = s.store.IsJWTUsed(s.ctx, "5dad3ff7-e4f2-41b6-98a3-b73d872076ce")
s.False(used)
s.NoError(err)
used, err = s.store.IsJWTUsed(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202")
s.True(used)
s.EqualError(err, "failed to load")
}
func (s *StoreSuite) TestMarkJWTUsedForTime() {
gomock.InOrder(
s.mock.EXPECT().
SaveOAuth2BlacklistedJTI(s.ctx, model.OAuth2BlacklistedJTI{Signature: "f29ef0d85303a09411b76001c579980f1b1b7fc9deb1fa647875a724f4f231c6", ExpiresAt: time.Unix(160000000, 0)}).
Return(nil),
s.mock.EXPECT().SaveOAuth2BlacklistedJTI(s.ctx, model.OAuth2BlacklistedJTI{Signature: "0dab0de97ed4e05da82763497448daf4f6b555c99218100e3ef5a81f36232940", ExpiresAt: time.Unix(160000000, 0)}).
Return(fmt.Errorf("already marked")),
)
s.NoError(s.store.MarkJWTUsedForTime(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7202", time.Unix(160000000, 0)))
s.EqualError(s.store.MarkJWTUsedForTime(s.ctx, "65471ccb-d650-4006-a95f-cb4f4e3d7201", time.Unix(160000000, 0)), "already marked")
}