mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
feat(session): IDP Intent Check API with relation tables (#11820)
# Which Problems Are Solved As part of #11035 , this PR implements the IDP intent check logic for session validation # How the Problems Are Solved - Inject encryption algorithm for IDP intent tokens at DB initialization - Add the IDP intent repository as an invoke option - Rework crypto mocks using gomock - Implement IDP intent check logic - minor - DB: expand IDP Intent deletion testing table with a test case where IDP intent is not found # Noteworthy I did not implement `domain.Transactional` given the doubts that @adlerhurst expressed in https://github.com/zitadel/zitadel/pull/11804 . So, there is no transaction AT ALL in here because the `Execute()` method contains one single DB call (Delete) and `Validate()` just does Get calls. # Additional Context This is a cherry-picked PR + minor changes, coming from https://github.com/zitadel/zitadel/pull/11164 - Relates to #11035 - Depends on https://github.com/zitadel/zitadel/pull/11804
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
session_grpc "github.com/zitadel/zitadel/pkg/grpc/session/v2"
|
||||
)
|
||||
|
||||
func CheckIDPIntentGRPCToDomain(checkIDPIntent *session_grpc.CheckIDPIntent) *domain.CheckIDPIntentType {
|
||||
if checkIDPIntent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &domain.CheckIDPIntentType{
|
||||
ID: checkIDPIntent.GetIdpIntentId(),
|
||||
Token: checkIDPIntent.GetIdpIntentToken(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
session_grpc "github.com/zitadel/zitadel/pkg/grpc/session/v2"
|
||||
)
|
||||
|
||||
func TestCheckIDPIntentGRPCToDomain(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := []struct {
|
||||
testName string
|
||||
input *session_grpc.CheckIDPIntent
|
||||
expected *domain.CheckIDPIntentType
|
||||
}{
|
||||
{
|
||||
testName: "nil input",
|
||||
input: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
testName: "valid input",
|
||||
input: &session_grpc.CheckIDPIntent{
|
||||
IdpIntentId: "intent-123",
|
||||
IdpIntentToken: "token-abc",
|
||||
},
|
||||
expected: &domain.CheckIDPIntentType{
|
||||
ID: "intent-123",
|
||||
Token: "token-abc",
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "empty strings",
|
||||
input: &session_grpc.CheckIDPIntent{
|
||||
IdpIntentId: "",
|
||||
IdpIntentToken: "",
|
||||
},
|
||||
expected: &domain.CheckIDPIntentType{
|
||||
ID: "",
|
||||
Token: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result := CheckIDPIntentGRPCToDomain(tc.input)
|
||||
assert.Equal(t, tc.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
pool database.Pool
|
||||
legacyEventstore eventstore.LegacyEventstore
|
||||
sysConfig systemdefaults.SystemDefaults
|
||||
passwordHasher *crypto.Hasher
|
||||
pool database.Pool
|
||||
// tracer tracing.Tracer = tracing.GlobalTracer()
|
||||
// runtimeLogger *slog.Logger = logging.New(logging.StreamRuntime, nil)
|
||||
legacyEventstore eventstore.LegacyEventstore
|
||||
sysConfig systemdefaults.SystemDefaults
|
||||
passwordHasher *crypto.Hasher
|
||||
idpEncryptionAlgo crypto.EncryptionAlgorithm
|
||||
)
|
||||
|
||||
func SetPool(p database.Pool) {
|
||||
@@ -29,3 +32,7 @@ func SetSystemConfig(cfg systemdefaults.SystemDefaults) {
|
||||
func SetPasswordHasher(hasher *crypto.Hasher) {
|
||||
passwordHasher = hasher
|
||||
}
|
||||
|
||||
func SetIDPEncryptionAlgorithm(idpEncryptionAlg crypto.EncryptionAlgorithm) {
|
||||
idpEncryptionAlgo = idpEncryptionAlg
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
type wrongIDPTypeError struct {
|
||||
@@ -89,6 +93,25 @@ func (e *PasswordVerificationError) Error() string {
|
||||
return fmt.Sprintf("Message=failed password attempts (%d)", e.failedAttempts)
|
||||
}
|
||||
|
||||
// handleGetError wraps DB errors coming from Get calls into [zerrors] errors.
|
||||
//
|
||||
// - errorID should be in the format <package short name>-<random id>
|
||||
// - objectType should be the string representation of a DB object (e.g. 'user', 'session', 'idp'...)
|
||||
//
|
||||
// The function wraps [database.NoRowFoundError] to [zerrors.NotFound] error
|
||||
// and any other error to [zerrors.InternalError]
|
||||
func handleGetError(inputErr error, errorID, objectType string) error {
|
||||
if inputErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if errors.Is(inputErr, &database.NoRowFoundError{}) {
|
||||
return zerrors.CreateZitadelError(zerrors.KindNotFound, inputErr, errorID, fmt.Sprintf("%s not found", objectType), 1)
|
||||
}
|
||||
|
||||
return zerrors.CreateZitadelError(zerrors.KindInternal, inputErr, errorID, fmt.Sprintf("failed fetching %s", objectType), 1)
|
||||
}
|
||||
|
||||
func (err *PasswordVerificationError) Is(target error) bool {
|
||||
_, ok := target.(*PasswordVerificationError)
|
||||
return ok
|
||||
|
||||
@@ -63,6 +63,12 @@ func WithPermissionChecker(checker PermissionChecker) InvokeOpt {
|
||||
}
|
||||
}
|
||||
|
||||
func WithIDPIntentRepo(repo IDPIntentRepository) InvokeOpt {
|
||||
return func(opts *InvokeOpts) {
|
||||
opts.idpIntentRepo = repo
|
||||
}
|
||||
}
|
||||
|
||||
// WithQueryExecutor sets the database client to be used by the command.
|
||||
// If not set, the default pool will be used.
|
||||
// This is mainly used for testing.
|
||||
@@ -99,6 +105,7 @@ type InvokeOpts struct {
|
||||
instanceDomainRepo InstanceDomainRepository
|
||||
sessionRepo SessionRepository
|
||||
userRepo UserRepository
|
||||
idpIntentRepo IDPIntentRepository
|
||||
|
||||
// Settings repos
|
||||
lockoutSettingRepo LockoutSettingsRepository
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package domainmock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
|
||||
domain "github.com/zitadel/zitadel/backend/v3/domain"
|
||||
database "github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
)
|
||||
|
||||
func NewIDPIntentRepo(ctrl *gomock.Controller) *IDPIntentRepo {
|
||||
return &IDPIntentRepo{
|
||||
mock: NewMockIDPIntentRepository(ctrl),
|
||||
IDPIntentRepository: repository.IDPIntentRepository(),
|
||||
}
|
||||
}
|
||||
|
||||
type IDPIntentRepo struct {
|
||||
domain.IDPIntentRepository
|
||||
mock *MockIDPIntentRepository
|
||||
}
|
||||
|
||||
func (u *IDPIntentRepo) EXPECT() *MockIDPIntentRepositoryMockRecorder {
|
||||
return u.mock.EXPECT()
|
||||
}
|
||||
|
||||
func (i *IDPIntentRepo) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.IDPIntent, error) {
|
||||
return i.mock.Get(ctx, client, opts...)
|
||||
}
|
||||
|
||||
func (i *IDPIntentRepo) Create(ctx context.Context, client database.QueryExecutor, intent *domain.IDPIntent) error {
|
||||
return i.mock.Create(ctx, client, intent)
|
||||
}
|
||||
|
||||
func (i *IDPIntentRepo) Update(ctx context.Context, client database.QueryExecutor, condition database.Condition, changes ...database.Change) (int64, error) {
|
||||
return i.mock.Update(ctx, client, condition, changes...)
|
||||
}
|
||||
|
||||
func (i *IDPIntentRepo) Delete(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) {
|
||||
return i.mock.Delete(ctx, client, condition)
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/idpintent"
|
||||
"github.com/zitadel/zitadel/internal/repository/session"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
type CheckIDPIntentType struct {
|
||||
ID string
|
||||
Token string
|
||||
}
|
||||
|
||||
type IDPIntentCheckCommand struct {
|
||||
CheckIntent *CheckIDPIntentType
|
||||
|
||||
SessionID string
|
||||
InstanceID string
|
||||
EncAlgo crypto.EncryptionAlgorithm
|
||||
|
||||
FetchedUser User
|
||||
IsCheckComplete bool
|
||||
}
|
||||
|
||||
// NewIDPIntentCheckCommand returns an IDPIntentCheckCommand initialized with the input values.
|
||||
//
|
||||
// If encryptionAlgo is nil, the default [crypto.EncryptionAlgorithm] will be used
|
||||
func NewIDPIntentCheckCommand(request *CheckIDPIntentType, sessionID, instanceID string, encryptionAlgo crypto.EncryptionAlgorithm) *IDPIntentCheckCommand {
|
||||
idpCheckCommand := &IDPIntentCheckCommand{
|
||||
CheckIntent: request,
|
||||
SessionID: sessionID,
|
||||
InstanceID: instanceID,
|
||||
EncAlgo: idpEncryptionAlgo,
|
||||
}
|
||||
|
||||
if encryptionAlgo != nil {
|
||||
idpCheckCommand.EncAlgo = encryptionAlgo
|
||||
}
|
||||
|
||||
return idpCheckCommand
|
||||
}
|
||||
|
||||
// Events implements [Commander].
|
||||
func (i *IDPIntentCheckCommand) Events(ctx context.Context, opts *InvokeOpts) ([]eventstore.Command, error) {
|
||||
if i.CheckIntent == nil || !i.IsCheckComplete {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return []eventstore.Command{
|
||||
session.NewIntentCheckedEvent(ctx, &session.NewAggregate(i.SessionID, i.InstanceID).Aggregate, time.Now()),
|
||||
idpintent.NewConsumedEvent(ctx, &idpintent.NewAggregate(i.CheckIntent.ID, "").Aggregate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Execute implements [Commander].
|
||||
func (i *IDPIntentCheckCommand) Execute(ctx context.Context, opts *InvokeOpts) (err error) {
|
||||
if i.CheckIntent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
intentRepo := opts.idpIntentRepo
|
||||
|
||||
removedRows, err := intentRepo.Delete(ctx, opts.DB(), intentRepo.PrimaryKeyCondition(i.InstanceID, i.CheckIntent.ID))
|
||||
if err != nil {
|
||||
return zerrors.ThrowInternal(err, "DOM-j1s5Eu", "failed deleting IDP intent")
|
||||
}
|
||||
if removedRows != 1 {
|
||||
return zerrors.ThrowInternal(NewRowsReturnedMismatchError(1, removedRows), "DOM-3CBpdB", "unexpected number of rows deleted")
|
||||
}
|
||||
|
||||
i.IsCheckComplete = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements [Commander].
|
||||
func (i *IDPIntentCheckCommand) String() string {
|
||||
return "IDPIntentCheckCommand"
|
||||
}
|
||||
|
||||
// Validate implements [Commander].
|
||||
func (i *IDPIntentCheckCommand) Validate(ctx context.Context, opts *InvokeOpts) (err error) {
|
||||
if i.CheckIntent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if i.SessionID == "" {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-5Y8pb4", "Errors.Missing.SessionID")
|
||||
}
|
||||
if i.InstanceID == "" {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-Q4YFIq", "Errors.Missing.InstanceID")
|
||||
}
|
||||
|
||||
sessionRepo := opts.sessionRepo
|
||||
idpIntentRepo := opts.idpIntentRepo
|
||||
userRepo := opts.userRepo
|
||||
|
||||
session, err := sessionRepo.Get(ctx, opts.DB(), database.WithCondition(sessionRepo.PrimaryKeyCondition(i.InstanceID, i.SessionID)))
|
||||
if err = handleGetError(err, "DOM-EhIgey", "session"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if session.UserID == "" {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-IJcVkV", "Errors.User.UserIDMissing")
|
||||
}
|
||||
|
||||
if err := crypto.CheckToken(i.EncAlgo, i.CheckIntent.Token, i.CheckIntent.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
intent, err := idpIntentRepo.Get(ctx, opts.DB(), database.WithCondition(idpIntentRepo.PrimaryKeyCondition(i.InstanceID, i.CheckIntent.ID)))
|
||||
if err = handleGetError(err, "DOM-5XkWJV", "intent"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if intent.State != IDPIntentStateSucceeded {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-0UKHku", "Errors.Intent.NotSucceeded")
|
||||
}
|
||||
|
||||
if intent.ExpiresAt == nil || intent.ExpiresAt.Before(time.Now()) {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-kDR1XK", "Errors.Intent.Expired")
|
||||
}
|
||||
|
||||
user, err := userRepo.Get(ctx, opts.DB(), database.WithCondition(userRepo.PrimaryKeyCondition(i.InstanceID, session.UserID)))
|
||||
if err = handleGetError(err, "DOM-Vnx2G9", "user"); err != nil {
|
||||
return err
|
||||
}
|
||||
if user.Human == nil {
|
||||
return zerrors.ThrowInternal(nil, "DOM-FkX5lZ", "user not human")
|
||||
}
|
||||
|
||||
if intentUsr := intent.UserID; intentUsr != "" {
|
||||
if intentUsr != session.UserID {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-FLdnLH", "Errors.Intent.OtherUser")
|
||||
}
|
||||
i.FetchedUser = *user
|
||||
return nil
|
||||
}
|
||||
|
||||
var matchingLink *IdentityProviderLink
|
||||
for _, idpLink := range user.Human.IdentityProviderLinks {
|
||||
if idpLink.ProviderID == intent.IDPID {
|
||||
matchingLink = idpLink
|
||||
break
|
||||
}
|
||||
}
|
||||
if matchingLink == nil {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "DOM-XuNkt7", "Errors.Intent.OtherUser")
|
||||
}
|
||||
|
||||
i.FetchedUser = *user
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ Commander = (*IDPIntentCheckCommand)(nil)
|
||||
@@ -0,0 +1,821 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
domainmock "github.com/zitadel/zitadel/backend/v3/domain/mock"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/dbmock"
|
||||
noopdb "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/noop"
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/idpintent"
|
||||
"github.com/zitadel/zitadel/internal/repository/session"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
func TestIDPIntentCheckCommand_Events(t *testing.T) {
|
||||
t.Parallel()
|
||||
tt := []struct {
|
||||
name string
|
||||
command *domain.IDPIntentCheckCommand
|
||||
expectedEvents []eventstore.Command
|
||||
}{
|
||||
{
|
||||
name: "nil CheckIntent returns nil events",
|
||||
command: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: nil,
|
||||
IsCheckComplete: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "isCheckComplete false returns nil events",
|
||||
command: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid command returns events",
|
||||
command: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123"},
|
||||
SessionID: "session-456",
|
||||
InstanceID: "instance-789",
|
||||
IsCheckComplete: true,
|
||||
},
|
||||
|
||||
expectedEvents: []eventstore.Command{
|
||||
session.NewIntentCheckedEvent(t.Context(), &session.NewAggregate("session-456", "instance-789").Aggregate, time.Now()),
|
||||
idpintent.NewConsumedEvent(t.Context(), &idpintent.NewAggregate("intent-123", "").Aggregate),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Test
|
||||
events, err := tc.command.Events(context.Background(), &domain.InvokeOpts{})
|
||||
|
||||
// Verify
|
||||
assert.NoError(t, err)
|
||||
|
||||
require.Len(t, events, len(tc.expectedEvents))
|
||||
|
||||
for i, expectedType := range tc.expectedEvents {
|
||||
assert.IsType(t, expectedType, events[i])
|
||||
switch expectedAssertedType := expectedType.(type) {
|
||||
case *session.IntentCheckedEvent:
|
||||
actualAssertedType, ok := events[i].(*session.IntentCheckedEvent)
|
||||
require.True(t, ok)
|
||||
assert.InDelta(t, expectedAssertedType.CheckedAt.UnixMilli(), actualAssertedType.CheckedAt.UnixMilli(), 10)
|
||||
case *idpintent.ConsumedEvent:
|
||||
_, ok := events[i].(*idpintent.ConsumedEvent)
|
||||
require.True(t, ok)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDPIntentCheckCommand_Validate(t *testing.T) {
|
||||
t.Parallel()
|
||||
getErr := errors.New("get error")
|
||||
notFoundErr := database.NewNoRowFoundError(nil)
|
||||
decryptionError := errors.New("decryption error")
|
||||
invalidTokenEncoding := base64.RawURLEncoding.EncodeToString([]byte("invalid-token"))
|
||||
validTokenEncoding := base64.RawURLEncoding.EncodeToString([]byte("token-123"))
|
||||
|
||||
tt := []struct {
|
||||
testName string
|
||||
sessionRepo func(ctrl *gomock.Controller) domain.SessionRepository
|
||||
idpIntentRepo func(ctrl *gomock.Controller) domain.IDPIntentRepository
|
||||
userRepo func(ctrl *gomock.Controller) domain.UserRepository
|
||||
encryptionAlgorithm func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm
|
||||
cmd *domain.IDPIntentCheckCommand
|
||||
expectedError error
|
||||
expectedUser domain.User
|
||||
}{
|
||||
{
|
||||
testName: "when CheckIntent is nil should return no error",
|
||||
cmd: &domain.IDPIntentCheckCommand{},
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
testName: "when session ID is not set should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-5Y8pb4", "Errors.Missing.SessionID"),
|
||||
},
|
||||
{
|
||||
testName: "when instance ID is not set should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "",
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-Q4YFIq", "Errors.Missing.InstanceID"),
|
||||
},
|
||||
{
|
||||
testName: "when retrieving session fails should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(nil, getErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(getErr, "DOM-EhIgey", "failed fetching session"),
|
||||
},
|
||||
{
|
||||
testName: "when session not found should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(nil, notFoundErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowNotFound(notFoundErr, "DOM-EhIgey", "session not found"),
|
||||
},
|
||||
{
|
||||
testName: "when session userID is empty should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: ""}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-IJcVkV", "Errors.User.UserIDMissing"),
|
||||
},
|
||||
{
|
||||
testName: "when token verification fails should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: invalidTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("", decryptionError)
|
||||
return cryptoAlg
|
||||
},
|
||||
expectedError: zerrors.ThrowPermissionDenied(decryptionError, "CRYPTO-Sf4gt", "Errors.Intent.InvalidToken"),
|
||||
},
|
||||
{
|
||||
testName: "when retrieving intent fails should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(nil, getErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(getErr, "DOM-5XkWJV", "failed fetching intent"),
|
||||
},
|
||||
{
|
||||
testName: "when intent not found should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(nil, notFoundErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowNotFound(notFoundErr, "DOM-5XkWJV", "intent not found"),
|
||||
},
|
||||
{
|
||||
testName: "when intent state is not succeeded should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateFailed, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour))}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-0UKHku", "Errors.Intent.NotSucceeded"),
|
||||
},
|
||||
{
|
||||
testName: "when intent is expired should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(-time.Hour))}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-kDR1XK", "Errors.Intent.Expired"),
|
||||
},
|
||||
{
|
||||
testName: "when intent expiration is nil should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: nil}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-kDR1XK", "Errors.Intent.Expired"),
|
||||
},
|
||||
{
|
||||
testName: "when retrieving user fails should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: ""}, nil)
|
||||
return repo
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(nil, getErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(getErr, "DOM-Vnx2G9", "failed fetching user"),
|
||||
},
|
||||
{
|
||||
testName: "when user is not found should return not found error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: ""}, nil)
|
||||
return repo
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(nil, notFoundErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowNotFound(notFoundErr, "DOM-Vnx2G9", "user not found"),
|
||||
},
|
||||
{
|
||||
testName: "when user is not human should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: ""}, nil)
|
||||
return repo
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(&domain.User{ID: "user-1", State: domain.UserStateActive, Human: nil}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(nil, "DOM-FkX5lZ", "user not human"),
|
||||
},
|
||||
{
|
||||
testName: "when intent has user and it matches session user should return no error and set fetched user",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(&domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{IdentityProviderLinks: []*domain.IdentityProviderLink{{ProviderID: "idp-123"}}},
|
||||
}, nil)
|
||||
return repo
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: nil,
|
||||
expectedUser: domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{
|
||||
IdentityProviderLinks: []*domain.IdentityProviderLink{
|
||||
{ProviderID: "idp-123"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "when intent has user but it does not match session user should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(&domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{IdentityProviderLinks: []*domain.IdentityProviderLink{{ProviderID: "idp-123"}}},
|
||||
}, nil)
|
||||
return repo
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: "user-2"}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-FLdnLH", "Errors.Intent.OtherUser"),
|
||||
},
|
||||
{
|
||||
testName: "when user has no matching IDP link should return error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: "", IDPID: "idp-123"}, nil)
|
||||
return repo
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(&domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{IdentityProviderLinks: []*domain.IdentityProviderLink{{ProviderID: "idp-456"}}},
|
||||
}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-XuNkt7", "Errors.Intent.OtherUser"),
|
||||
},
|
||||
{
|
||||
testName: "when all validations pass should return no error",
|
||||
cmd: &domain.IDPIntentCheckCommand{
|
||||
CheckIntent: &domain.CheckIDPIntentType{ID: "intent-123", Token: validTokenEncoding},
|
||||
SessionID: "session-1",
|
||||
InstanceID: "instance-1",
|
||||
},
|
||||
sessionRepo: func(ctrl *gomock.Controller) domain.SessionRepository {
|
||||
repo := domainmock.NewSessionRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "session-1")))).
|
||||
Return(&domain.Session{ID: "session-1", UserID: "user-1"}, nil)
|
||||
return repo
|
||||
},
|
||||
encryptionAlgorithm: func(ctrl *gomock.Controller) crypto.EncryptionAlgorithm {
|
||||
cryptoAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
cryptoAlg.EXPECT().
|
||||
EncryptionKeyID().
|
||||
Times(1)
|
||||
cryptoAlg.EXPECT().
|
||||
DecryptString(gomock.Any(), gomock.Any()).
|
||||
Times(1).
|
||||
Return("intent-123", nil)
|
||||
return cryptoAlg
|
||||
},
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "intent-123")))).
|
||||
Return(&domain.IDPIntent{ID: "intent-123", State: domain.IDPIntentStateSucceeded, ExpiresAt: gu.Ptr(time.Now().Add(time.Hour)), UserID: "", IDPID: "idp-123"}, nil)
|
||||
return repo
|
||||
},
|
||||
userRepo: func(ctrl *gomock.Controller) domain.UserRepository {
|
||||
repo := domainmock.NewUserRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition(repo.PrimaryKeyCondition("instance-1", "user-1")))).
|
||||
Return(&domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{
|
||||
IdentityProviderLinks: []*domain.IdentityProviderLink{
|
||||
{ProviderID: "idp-123"},
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: nil,
|
||||
expectedUser: domain.User{
|
||||
ID: "user-1",
|
||||
State: domain.UserStateActive,
|
||||
Human: &domain.HumanUser{
|
||||
IdentityProviderLinks: []*domain.IdentityProviderLink{
|
||||
{ProviderID: "idp-123"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Given
|
||||
ctrl := gomock.NewController(t)
|
||||
ctx := authz.NewMockContext(tc.cmd.InstanceID, "", "")
|
||||
|
||||
opts := &domain.InvokeOpts{
|
||||
Invoker: domain.NewTransactionInvoker(nil),
|
||||
}
|
||||
domain.WithQueryExecutor(new(noopdb.Pool))(opts)
|
||||
|
||||
if tc.sessionRepo != nil {
|
||||
domain.WithSessionRepo(tc.sessionRepo(ctrl))(opts)
|
||||
}
|
||||
if tc.userRepo != nil {
|
||||
domain.WithUserRepo(tc.userRepo(ctrl))(opts)
|
||||
}
|
||||
if tc.idpIntentRepo != nil {
|
||||
domain.WithIDPIntentRepo(tc.idpIntentRepo(ctrl))(opts)
|
||||
}
|
||||
if tc.encryptionAlgorithm != nil {
|
||||
tc.cmd.EncAlgo = tc.encryptionAlgorithm(ctrl)
|
||||
}
|
||||
|
||||
// Test
|
||||
err := tc.cmd.Validate(ctx, opts)
|
||||
|
||||
// Verify
|
||||
assert.ErrorIs(t, err, tc.expectedError)
|
||||
assert.Equal(t, tc.expectedUser, tc.cmd.FetchedUser)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDPIntentCheckCommand_Execute(t *testing.T) {
|
||||
t.Parallel()
|
||||
deleteErr := errors.New("delete error")
|
||||
|
||||
tt := []struct {
|
||||
testName string
|
||||
idpIntentRepo func(ctrl *gomock.Controller) domain.IDPIntentRepository
|
||||
cmd *domain.IDPIntentCheckCommand
|
||||
expectedError error
|
||||
expectComplete bool
|
||||
}{
|
||||
{
|
||||
testName: "when CheckIntent is nil should return no error and not mark complete",
|
||||
cmd: &domain.IDPIntentCheckCommand{},
|
||||
expectedError: nil,
|
||||
expectComplete: false,
|
||||
},
|
||||
{
|
||||
testName: "when intent deletion fails should return error",
|
||||
cmd: domain.NewIDPIntentCheckCommand(&domain.CheckIDPIntentType{ID: "intent-123"}, "session-1", "instance-1", nil),
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Delete(gomock.Any(), gomock.Any(), repo.PrimaryKeyCondition("instance-1", "intent-123")).
|
||||
Return(int64(0), deleteErr)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(deleteErr, "DOM-j1s5Eu", "failed deleting IDP intent"),
|
||||
expectComplete: false,
|
||||
},
|
||||
{
|
||||
testName: "when intent deletion returns unexpected row count should return error",
|
||||
cmd: domain.NewIDPIntentCheckCommand(&domain.CheckIDPIntentType{ID: "intent-123"}, "session-1", "instance-1", nil),
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Delete(gomock.Any(), gomock.Any(), repo.PrimaryKeyCondition("instance-1", "intent-123")).
|
||||
Return(int64(0), nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: zerrors.ThrowInternal(domain.NewRowsReturnedMismatchError(1, 0), "DOM-3CBpdB", "unexpected number of rows deleted"),
|
||||
expectComplete: false,
|
||||
},
|
||||
{
|
||||
testName: "when intent is successfully deleted should mark complete",
|
||||
cmd: domain.NewIDPIntentCheckCommand(&domain.CheckIDPIntentType{ID: "intent-123"}, "session-1", "instance-1", nil),
|
||||
idpIntentRepo: func(ctrl *gomock.Controller) domain.IDPIntentRepository {
|
||||
repo := domainmock.NewIDPIntentRepo(ctrl)
|
||||
repo.EXPECT().
|
||||
Delete(gomock.Any(), gomock.Any(), repo.PrimaryKeyCondition("instance-1", "intent-123")).
|
||||
Return(int64(1), nil)
|
||||
return repo
|
||||
},
|
||||
expectedError: nil,
|
||||
expectComplete: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// Given
|
||||
ctrl := gomock.NewController(t)
|
||||
ctx := authz.NewMockContext(tc.cmd.InstanceID, "", "")
|
||||
|
||||
opts := &domain.InvokeOpts{
|
||||
Invoker: domain.NewTransactionInvoker(nil),
|
||||
}
|
||||
domain.WithQueryExecutor(new(noopdb.Pool))(opts)
|
||||
|
||||
if tc.idpIntentRepo != nil {
|
||||
domain.WithIDPIntentRepo(tc.idpIntentRepo(ctrl))(opts)
|
||||
}
|
||||
|
||||
// Test
|
||||
err := tc.cmd.Execute(ctx, opts)
|
||||
|
||||
// Verify
|
||||
assert.ErrorIs(t, err, tc.expectedError)
|
||||
assert.Equal(t, tc.expectComplete, tc.cmd.IsCheckComplete)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -570,6 +570,11 @@ func TestDeleteIDPIntent(t *testing.T) {
|
||||
),
|
||||
expectedDeletedCount: 2,
|
||||
},
|
||||
{
|
||||
testName: "when condition matches no record should not delete anything",
|
||||
inputConditions: idpIntentRepo.PrimaryKeyCondition(instanceID, "not found"),
|
||||
expectedDeletedCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
|
||||
@@ -209,6 +209,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
|
||||
|
||||
new_domain.SetLegacyEventstore(eventstoreClient)
|
||||
new_domain.SetSystemConfig(config.SystemDefaults)
|
||||
new_domain.SetIDPEncryptionAlgorithm(keys.IDPConfig)
|
||||
|
||||
sessionTokenVerifier := internal_authz.SessionTokenVerifier(keys.OIDC)
|
||||
cacheConnectors, err := connector.StartConnectors(config.Caches, dbClient)
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
type MockGenerator struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockGeneratorMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockGeneratorMockRecorder is the mock recorder for MockGenerator.
|
||||
|
||||
@@ -9,37 +9,14 @@ import (
|
||||
)
|
||||
|
||||
func CreateMockEncryptionAlg(ctrl *gomock.Controller) EncryptionAlgorithm {
|
||||
return createMockEncryptionAlgorithm(
|
||||
ctrl,
|
||||
func(code []byte) ([]byte, error) {
|
||||
return code, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// CreateMockEncryptionAlgWithCode compares the length of the value to be encrypted with the length of the provided code.
|
||||
// It will return an error if they do not match.
|
||||
// The provided code will be used to encrypt in favor of the value passed to the encryption.
|
||||
// This function is intended to be used where the passed value is not in control, but where the returned encryption requires a static value.
|
||||
func CreateMockEncryptionAlgWithCode(ctrl *gomock.Controller, code string) EncryptionAlgorithm {
|
||||
return createMockEncryptionAlgorithm(
|
||||
ctrl,
|
||||
func(c []byte) ([]byte, error) {
|
||||
if len(c) != len(code) {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "id", "invalid code length - expected %d, got %d", len(code), len(c))
|
||||
}
|
||||
return []byte(code), nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func createMockEncryptionAlgorithm(ctrl *gomock.Controller, encryptFunction func(c []byte) ([]byte, error)) *MockEncryptionAlgorithm {
|
||||
mCrypto := NewMockEncryptionAlgorithm(ctrl)
|
||||
mCrypto.EXPECT().Algorithm().AnyTimes().Return("enc")
|
||||
mCrypto.EXPECT().EncryptionKeyID().AnyTimes().Return("id")
|
||||
mCrypto.EXPECT().DecryptionKeyIDs().AnyTimes().Return([]string{"id"})
|
||||
mCrypto.EXPECT().Encrypt(gomock.Any()).AnyTimes().DoAndReturn(
|
||||
encryptFunction,
|
||||
func(code []byte) ([]byte, error) {
|
||||
return code, nil
|
||||
},
|
||||
)
|
||||
mCrypto.EXPECT().DecryptString(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(
|
||||
func(code []byte, keyID string) (string, error) {
|
||||
|
||||
@@ -14,6 +14,8 @@ const (
|
||||
TypeHash // Depcrecated: use [passwap.Swapper] instead
|
||||
)
|
||||
|
||||
//go:generate mockgen -typed -package crypto -destination ./crypto.mock.go . EncryptionAlgorithm
|
||||
|
||||
type EncryptionAlgorithm interface {
|
||||
Algorithm() string
|
||||
EncryptionKeyID() string
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/zitadel/zitadel/internal/crypto (interfaces: EncryptionAlgorithm)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -typed -package crypto -destination ./crypto.mock.go . EncryptionAlgorithm
|
||||
//
|
||||
|
||||
// Package crypto is a generated GoMock package.
|
||||
package crypto
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockEncryptionAlgorithm is a mock of EncryptionAlgorithm interface.
|
||||
type MockEncryptionAlgorithm struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockEncryptionAlgorithmMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmMockRecorder is the mock recorder for MockEncryptionAlgorithm.
|
||||
type MockEncryptionAlgorithmMockRecorder struct {
|
||||
mock *MockEncryptionAlgorithm
|
||||
}
|
||||
|
||||
// NewMockEncryptionAlgorithm creates a new mock instance.
|
||||
func NewMockEncryptionAlgorithm(ctrl *gomock.Controller) *MockEncryptionAlgorithm {
|
||||
mock := &MockEncryptionAlgorithm{ctrl: ctrl}
|
||||
mock.recorder = &MockEncryptionAlgorithmMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockEncryptionAlgorithm) EXPECT() *MockEncryptionAlgorithmMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Algorithm mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Algorithm() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Algorithm")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Algorithm indicates an expected call of Algorithm.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Algorithm() *MockEncryptionAlgorithmAlgorithmCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Algorithm", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Algorithm))
|
||||
return &MockEncryptionAlgorithmAlgorithmCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmAlgorithmCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmAlgorithmCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmAlgorithmCall) Return(arg0 string) *MockEncryptionAlgorithmAlgorithmCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmAlgorithmCall) Do(f func() string) *MockEncryptionAlgorithmAlgorithmCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmAlgorithmCall) DoAndReturn(f func() string) *MockEncryptionAlgorithmAlgorithmCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// Decrypt mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Decrypt(hashed []byte, keyID string) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Decrypt", hashed, keyID)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Decrypt indicates an expected call of Decrypt.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Decrypt(hashed, keyID any) *MockEncryptionAlgorithmDecryptCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decrypt", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Decrypt), hashed, keyID)
|
||||
return &MockEncryptionAlgorithmDecryptCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmDecryptCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmDecryptCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmDecryptCall) Return(arg0 []byte, arg1 error) *MockEncryptionAlgorithmDecryptCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmDecryptCall) Do(f func([]byte, string) ([]byte, error)) *MockEncryptionAlgorithmDecryptCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmDecryptCall) DoAndReturn(f func([]byte, string) ([]byte, error)) *MockEncryptionAlgorithmDecryptCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DecryptString mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) DecryptString(hashed []byte, keyID string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecryptString", hashed, keyID)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DecryptString indicates an expected call of DecryptString.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) DecryptString(hashed, keyID any) *MockEncryptionAlgorithmDecryptStringCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptString", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).DecryptString), hashed, keyID)
|
||||
return &MockEncryptionAlgorithmDecryptStringCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmDecryptStringCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmDecryptStringCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmDecryptStringCall) Return(arg0 string, arg1 error) *MockEncryptionAlgorithmDecryptStringCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmDecryptStringCall) Do(f func([]byte, string) (string, error)) *MockEncryptionAlgorithmDecryptStringCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmDecryptStringCall) DoAndReturn(f func([]byte, string) (string, error)) *MockEncryptionAlgorithmDecryptStringCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DecryptionKeyIDs mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) DecryptionKeyIDs() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecryptionKeyIDs")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DecryptionKeyIDs indicates an expected call of DecryptionKeyIDs.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) DecryptionKeyIDs() *MockEncryptionAlgorithmDecryptionKeyIDsCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptionKeyIDs", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).DecryptionKeyIDs))
|
||||
return &MockEncryptionAlgorithmDecryptionKeyIDsCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmDecryptionKeyIDsCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmDecryptionKeyIDsCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmDecryptionKeyIDsCall) Return(arg0 []string) *MockEncryptionAlgorithmDecryptionKeyIDsCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmDecryptionKeyIDsCall) Do(f func() []string) *MockEncryptionAlgorithmDecryptionKeyIDsCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmDecryptionKeyIDsCall) DoAndReturn(f func() []string) *MockEncryptionAlgorithmDecryptionKeyIDsCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// Encrypt mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Encrypt(value []byte) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Encrypt", value)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Encrypt indicates an expected call of Encrypt.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Encrypt(value any) *MockEncryptionAlgorithmEncryptCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Encrypt", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Encrypt), value)
|
||||
return &MockEncryptionAlgorithmEncryptCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmEncryptCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmEncryptCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmEncryptCall) Return(arg0 []byte, arg1 error) *MockEncryptionAlgorithmEncryptCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmEncryptCall) Do(f func([]byte) ([]byte, error)) *MockEncryptionAlgorithmEncryptCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmEncryptCall) DoAndReturn(f func([]byte) ([]byte, error)) *MockEncryptionAlgorithmEncryptCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// EncryptionKeyID mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) EncryptionKeyID() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EncryptionKeyID")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EncryptionKeyID indicates an expected call of EncryptionKeyID.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) EncryptionKeyID() *MockEncryptionAlgorithmEncryptionKeyIDCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptionKeyID", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).EncryptionKeyID))
|
||||
return &MockEncryptionAlgorithmEncryptionKeyIDCall{Call: call}
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmEncryptionKeyIDCall wrap *gomock.Call
|
||||
type MockEncryptionAlgorithmEncryptionKeyIDCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockEncryptionAlgorithmEncryptionKeyIDCall) Return(arg0 string) *MockEncryptionAlgorithmEncryptionKeyIDCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockEncryptionAlgorithmEncryptionKeyIDCall) Do(f func() string) *MockEncryptionAlgorithmEncryptionKeyIDCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockEncryptionAlgorithmEncryptionKeyIDCall) DoAndReturn(f func() string) *MockEncryptionAlgorithmEncryptionKeyIDCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: crypto.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source crypto.go -destination ./crypto_mock.go -package crypto
|
||||
//
|
||||
|
||||
// Package crypto is a generated GoMock package.
|
||||
package crypto
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockEncryptionAlgorithm is a mock of EncryptionAlgorithm interface.
|
||||
type MockEncryptionAlgorithm struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockEncryptionAlgorithmMockRecorder
|
||||
}
|
||||
|
||||
// MockEncryptionAlgorithmMockRecorder is the mock recorder for MockEncryptionAlgorithm.
|
||||
type MockEncryptionAlgorithmMockRecorder struct {
|
||||
mock *MockEncryptionAlgorithm
|
||||
}
|
||||
|
||||
// NewMockEncryptionAlgorithm creates a new mock instance.
|
||||
func NewMockEncryptionAlgorithm(ctrl *gomock.Controller) *MockEncryptionAlgorithm {
|
||||
mock := &MockEncryptionAlgorithm{ctrl: ctrl}
|
||||
mock.recorder = &MockEncryptionAlgorithmMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockEncryptionAlgorithm) EXPECT() *MockEncryptionAlgorithmMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Algorithm mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Algorithm() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Algorithm")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Algorithm indicates an expected call of Algorithm.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Algorithm() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Algorithm", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Algorithm))
|
||||
}
|
||||
|
||||
// Decrypt mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Decrypt(hashed []byte, keyID string) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Decrypt", hashed, keyID)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Decrypt indicates an expected call of Decrypt.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Decrypt(hashed, keyID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Decrypt", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Decrypt), hashed, keyID)
|
||||
}
|
||||
|
||||
// DecryptString mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) DecryptString(hashed []byte, keyID string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecryptString", hashed, keyID)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// DecryptString indicates an expected call of DecryptString.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) DecryptString(hashed, keyID any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptString", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).DecryptString), hashed, keyID)
|
||||
}
|
||||
|
||||
// DecryptionKeyIDs mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) DecryptionKeyIDs() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DecryptionKeyIDs")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DecryptionKeyIDs indicates an expected call of DecryptionKeyIDs.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) DecryptionKeyIDs() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecryptionKeyIDs", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).DecryptionKeyIDs))
|
||||
}
|
||||
|
||||
// Encrypt mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) Encrypt(value []byte) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Encrypt", value)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Encrypt indicates an expected call of Encrypt.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) Encrypt(value any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Encrypt", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).Encrypt), value)
|
||||
}
|
||||
|
||||
// EncryptionKeyID mocks base method.
|
||||
func (m *MockEncryptionAlgorithm) EncryptionKeyID() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EncryptionKeyID")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EncryptionKeyID indicates an expected call of EncryptionKeyID.
|
||||
func (mr *MockEncryptionAlgorithmMockRecorder) EncryptionKeyID() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EncryptionKeyID", reflect.TypeOf((*MockEncryptionAlgorithm)(nil).EncryptionKeyID))
|
||||
}
|
||||
@@ -2018,7 +2018,7 @@ func expectTemplateWithNotifyUserQueriesSMS(queries *mock.MockQueries) {
|
||||
queries.EXPECT().CustomTextListByTemplate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2).Return(&query.CustomTexts{}, nil)
|
||||
}
|
||||
|
||||
func cryptoValue(t *testing.T, ctrl *gomock.Controller, value string) (*crypto.MockEncryptionAlgorithm, *crypto.CryptoValue) {
|
||||
func cryptoValue(t *testing.T, ctrl *gomock.Controller, value string) (crypto.EncryptionAlgorithm, *crypto.CryptoValue) {
|
||||
encAlg := crypto.NewMockEncryptionAlgorithm(ctrl)
|
||||
encAlg.EXPECT().Algorithm().AnyTimes().Return("enc")
|
||||
encAlg.EXPECT().EncryptionKeyID().AnyTimes().Return("id")
|
||||
|
||||
Reference in New Issue
Block a user