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:
Marco A.
2026-03-17 10:50:47 +00:00
committed by GitHub
parent 3fdac54878
commit aa4432dc99
16 changed files with 1422 additions and 157 deletions
+1
View File
@@ -20,6 +20,7 @@ import (
type MockGenerator struct {
ctrl *gomock.Controller
recorder *MockGeneratorMockRecorder
isgomock struct{}
}
// MockGeneratorMockRecorder is the mock recorder for MockGenerator.
+3 -26
View File
@@ -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) {
+2
View File
@@ -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
+271
View File
@@ -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
}
-126
View File
@@ -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")