From 3903355d18a7e72fa4c4e33779220b8450def56e Mon Sep 17 00:00:00 2001 From: Gayathri Vijayan <66356931+grvijayan@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:33:19 +0100 Subject: [PATCH] feat(settings): add secret generator type to settings RT implementation (#11152) # Which Problems Are Solved The `SecretGenerators` setting is missing among the instance settings in the new relational model. # How the Problems Are Solved This PR adds: * `SettingTypeSecretGenerator` type to the settings model * `SecretGeneratorSettingsRepository` and `secretGeneratorSettingsJSONChanges` interfaces to set, retrieve, and delete `secret_generator` settings, and corresponding unit tests. * projection reducers to reduce the following events: * `SecretGeneratorAddedEvent` * `SecretGeneratorChangedEvent` * `SecretGeneratorRemovedEvent` * integration tests to test that the events get reduced correctly # Additional Changes N/A # Additional Context - Part of https://github.com/zitadel/zitadel/issues/10207 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Marco A. --- .../mock/secret_generator_settings.mock.go | 1198 +++++++++++++++++ backend/v3/domain/settings.go | 87 ++ backend/v3/domain/settingtype_enumer.go | 52 +- .../migration/009_settings_table/up.sql | 3 +- backend/v3/storage/database/errors.go | 3 +- .../events_testing/settings_instance_test.go | 148 ++ .../storage/database/repository/settings.go | 179 +++ .../database/repository/settings_test.go | 372 +++++ .../query/projection/settings_relational.go | 216 ++- 9 files changed, 2209 insertions(+), 49 deletions(-) create mode 100644 backend/v3/domain/mock/secret_generator_settings.mock.go diff --git a/backend/v3/domain/mock/secret_generator_settings.mock.go b/backend/v3/domain/mock/secret_generator_settings.mock.go new file mode 100644 index 000000000..244f2c895 --- /dev/null +++ b/backend/v3/domain/mock/secret_generator_settings.mock.go @@ -0,0 +1,1198 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/zitadel/zitadel/backend/v3/domain (interfaces: SecretGeneratorSettingsRepository) +// +// Generated by this command: +// +// mockgen -typed -package domainmock -destination ./mock/secret_generator_settings.mock.go . SecretGeneratorSettingsRepository +// + +// Package domainmock is a generated GoMock package. +package domainmock + +import ( + context "context" + reflect "reflect" + time "time" + + domain "github.com/zitadel/zitadel/backend/v3/domain" + database "github.com/zitadel/zitadel/backend/v3/storage/database" + json "github.com/zitadel/zitadel/backend/v3/storage/database/json" + gomock "go.uber.org/mock/gomock" +) + +// MockSecretGeneratorSettingsRepository is a mock of SecretGeneratorSettingsRepository interface. +type MockSecretGeneratorSettingsRepository struct { + ctrl *gomock.Controller + recorder *MockSecretGeneratorSettingsRepositoryMockRecorder + isgomock struct{} +} + +// MockSecretGeneratorSettingsRepositoryMockRecorder is the mock recorder for MockSecretGeneratorSettingsRepository. +type MockSecretGeneratorSettingsRepositoryMockRecorder struct { + mock *MockSecretGeneratorSettingsRepository +} + +// NewMockSecretGeneratorSettingsRepository creates a new mock instance. +func NewMockSecretGeneratorSettingsRepository(ctrl *gomock.Controller) *MockSecretGeneratorSettingsRepository { + mock := &MockSecretGeneratorSettingsRepository{ctrl: ctrl} + mock.recorder = &MockSecretGeneratorSettingsRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSecretGeneratorSettingsRepository) EXPECT() *MockSecretGeneratorSettingsRepositoryMockRecorder { + return m.recorder +} + +// CreatedAtColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) CreatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// CreatedAtColumn indicates an expected call of CreatedAtColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) CreatedAtColumn() *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatedAtColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).CreatedAtColumn)) + return &MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryCreatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Delete mocks base method. +func (m *MockSecretGeneratorSettingsRepository) Delete(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", ctx, client, condition) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) Delete(ctx, client, condition any) *MockSecretGeneratorSettingsRepositoryDeleteCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).Delete), ctx, client, condition) + return &MockSecretGeneratorSettingsRepositoryDeleteCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryDeleteCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryDeleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryDeleteCall) Return(arg0 int64, arg1 error) *MockSecretGeneratorSettingsRepositoryDeleteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryDeleteCall) Do(f func(context.Context, database.QueryExecutor, database.Condition) (int64, error)) *MockSecretGeneratorSettingsRepositoryDeleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryDeleteCall) DoAndReturn(f func(context.Context, database.QueryExecutor, database.Condition) (int64, error)) *MockSecretGeneratorSettingsRepositoryDeleteCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Get mocks base method. +func (m *MockSecretGeneratorSettingsRepository) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.SecretGeneratorSettings, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, client} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Get", varargs...) + ret0, _ := ret[0].(*domain.SecretGeneratorSettings) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) Get(ctx, client any, opts ...any) *MockSecretGeneratorSettingsRepositoryGetCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, client}, opts...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).Get), varargs...) + return &MockSecretGeneratorSettingsRepositoryGetCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryGetCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryGetCall) Return(arg0 *domain.SecretGeneratorSettings, arg1 error) *MockSecretGeneratorSettingsRepositoryGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryGetCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.SecretGeneratorSettings, error)) *MockSecretGeneratorSettingsRepositoryGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryGetCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.SecretGeneratorSettings, error)) *MockSecretGeneratorSettingsRepositoryGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IDColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) IDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// IDColumn indicates an expected call of IDColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) IDColumn() *MockSecretGeneratorSettingsRepositoryIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).IDColumn)) + return &MockSecretGeneratorSettingsRepositoryIDColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryIDColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryIDColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryIDColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryIDColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IDCondition mocks base method. +func (m *MockSecretGeneratorSettingsRepository) IDCondition(id string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDCondition", id) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// IDCondition indicates an expected call of IDCondition. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) IDCondition(id any) *MockSecretGeneratorSettingsRepositoryIDConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDCondition", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).IDCondition), id) + return &MockSecretGeneratorSettingsRepositoryIDConditionCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryIDConditionCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryIDConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryIDConditionCall) Return(arg0 database.Condition) *MockSecretGeneratorSettingsRepositoryIDConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryIDConditionCall) Do(f func(string) database.Condition) *MockSecretGeneratorSettingsRepositoryIDConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryIDConditionCall) DoAndReturn(f func(string) database.Condition) *MockSecretGeneratorSettingsRepositoryIDConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// InstanceIDColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) InstanceIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InstanceIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// InstanceIDColumn indicates an expected call of InstanceIDColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) InstanceIDColumn() *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).InstanceIDColumn)) + return &MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryInstanceIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// InstanceIDCondition mocks base method. +func (m *MockSecretGeneratorSettingsRepository) InstanceIDCondition(id string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InstanceIDCondition", id) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// InstanceIDCondition indicates an expected call of InstanceIDCondition. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) InstanceIDCondition(id any) *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDCondition", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).InstanceIDCondition), id) + return &MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall) Return(arg0 database.Condition) *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall) Do(f func(string) database.Condition) *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall) DoAndReturn(f func(string) database.Condition) *MockSecretGeneratorSettingsRepositoryInstanceIDConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// List mocks base method. +func (m *MockSecretGeneratorSettingsRepository) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.SecretGeneratorSettings, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, client} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) + ret0, _ := ret[0].([]*domain.SecretGeneratorSettings) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) List(ctx, client any, opts ...any) *MockSecretGeneratorSettingsRepositoryListCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, client}, opts...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).List), varargs...) + return &MockSecretGeneratorSettingsRepositoryListCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryListCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryListCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryListCall) Return(arg0 []*domain.SecretGeneratorSettings, arg1 error) *MockSecretGeneratorSettingsRepositoryListCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryListCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.SecretGeneratorSettings, error)) *MockSecretGeneratorSettingsRepositoryListCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryListCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.SecretGeneratorSettings, error)) *MockSecretGeneratorSettingsRepositoryListCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OrganizationIDColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) OrganizationIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OrganizationIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// OrganizationIDColumn indicates an expected call of OrganizationIDColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) OrganizationIDColumn() *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OrganizationIDColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).OrganizationIDColumn)) + return &MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryOrganizationIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// OrganizationIDCondition mocks base method. +func (m *MockSecretGeneratorSettingsRepository) OrganizationIDCondition(id *string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OrganizationIDCondition", id) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// OrganizationIDCondition indicates an expected call of OrganizationIDCondition. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) OrganizationIDCondition(id any) *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OrganizationIDCondition", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).OrganizationIDCondition), id) + return &MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall) Return(arg0 database.Condition) *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall) Do(f func(*string) database.Condition) *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall) DoAndReturn(f func(*string) database.Condition) *MockSecretGeneratorSettingsRepositoryOrganizationIDConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyColumns mocks base method. +func (m *MockSecretGeneratorSettingsRepository) PrimaryKeyColumns() []database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyColumns") + ret0, _ := ret[0].([]database.Column) + return ret0 +} + +// PrimaryKeyColumns indicates an expected call of PrimaryKeyColumns. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) PrimaryKeyColumns() *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyColumns", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).PrimaryKeyColumns)) + return &MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall) Return(arg0 []database.Column) *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall) Do(f func() []database.Column) *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall) DoAndReturn(f func() []database.Column) *MockSecretGeneratorSettingsRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyCondition mocks base method. +func (m *MockSecretGeneratorSettingsRepository) PrimaryKeyCondition(instanceID, id string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyCondition", instanceID, id) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// PrimaryKeyCondition indicates an expected call of PrimaryKeyCondition. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) PrimaryKeyCondition(instanceID, id any) *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyCondition", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).PrimaryKeyCondition), instanceID, id) + return &MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall) Return(arg0 database.Condition) *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall) Do(f func(string, string) database.Condition) *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall) DoAndReturn(f func(string, string) database.Condition) *MockSecretGeneratorSettingsRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Set mocks base method. +func (m *MockSecretGeneratorSettingsRepository) Set(ctx context.Context, client database.QueryExecutor, settings *domain.SecretGeneratorSettings) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Set", ctx, client, settings) + ret0, _ := ret[0].(error) + return ret0 +} + +// Set indicates an expected call of Set. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) Set(ctx, client, settings any) *MockSecretGeneratorSettingsRepositorySetCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).Set), ctx, client, settings) + return &MockSecretGeneratorSettingsRepositorySetCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetCall) Return(arg0 error) *MockSecretGeneratorSettingsRepositorySetCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetCall) Do(f func(context.Context, database.QueryExecutor, *domain.SecretGeneratorSettings) error) *MockSecretGeneratorSettingsRepositorySetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetCall) DoAndReturn(f func(context.Context, database.QueryExecutor, *domain.SecretGeneratorSettings) error) *MockSecretGeneratorSettingsRepositorySetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetClientSecret mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetClientSecret(value domain.ClientSecretAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetClientSecret", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetClientSecret indicates an expected call of SetClientSecret. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetClientSecret(value any) *MockSecretGeneratorSettingsRepositorySetClientSecretCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClientSecret", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetClientSecret), value) + return &MockSecretGeneratorSettingsRepositorySetClientSecretCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetClientSecretCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetClientSecretCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetClientSecretCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetClientSecretCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetClientSecretCall) Do(f func(domain.ClientSecretAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetClientSecretCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetClientSecretCall) DoAndReturn(f func(domain.ClientSecretAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetClientSecretCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetDomainVerification mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetDomainVerification(value domain.DomainVerificationAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDomainVerification", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetDomainVerification indicates an expected call of SetDomainVerification. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetDomainVerification(value any) *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDomainVerification", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetDomainVerification), value) + return &MockSecretGeneratorSettingsRepositorySetDomainVerificationCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetDomainVerificationCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetDomainVerificationCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall) Do(f func(domain.DomainVerificationAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall) DoAndReturn(f func(domain.DomainVerificationAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetDomainVerificationCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetEmailVerificationCode mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetEmailVerificationCode(value domain.EmailVerificationCodeAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetEmailVerificationCode", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetEmailVerificationCode indicates an expected call of SetEmailVerificationCode. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetEmailVerificationCode(value any) *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetEmailVerificationCode", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetEmailVerificationCode), value) + return &MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall) Do(f func(domain.EmailVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall) DoAndReturn(f func(domain.EmailVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetEmailVerificationCodeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetInitializeUserCode mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetInitializeUserCode(value domain.InitializeUserCodeAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetInitializeUserCode", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetInitializeUserCode indicates an expected call of SetInitializeUserCode. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetInitializeUserCode(value any) *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetInitializeUserCode", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetInitializeUserCode), value) + return &MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall) Do(f func(domain.InitializeUserCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall) DoAndReturn(f func(domain.InitializeUserCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetInitializeUserCodeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetOTPEmail mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetOTPEmail(value domain.OTPEmailAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetOTPEmail", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetOTPEmail indicates an expected call of SetOTPEmail. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetOTPEmail(value any) *MockSecretGeneratorSettingsRepositorySetOTPEmailCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOTPEmail", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetOTPEmail), value) + return &MockSecretGeneratorSettingsRepositorySetOTPEmailCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetOTPEmailCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetOTPEmailCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetOTPEmailCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPEmailCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetOTPEmailCall) Do(f func(domain.OTPEmailAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPEmailCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetOTPEmailCall) DoAndReturn(f func(domain.OTPEmailAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPEmailCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetOTPSMS mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetOTPSMS(value domain.OTPSMSAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetOTPSMS", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetOTPSMS indicates an expected call of SetOTPSMS. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetOTPSMS(value any) *MockSecretGeneratorSettingsRepositorySetOTPSMSCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOTPSMS", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetOTPSMS), value) + return &MockSecretGeneratorSettingsRepositorySetOTPSMSCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetOTPSMSCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetOTPSMSCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetOTPSMSCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPSMSCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetOTPSMSCall) Do(f func(domain.OTPSMSAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPSMSCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetOTPSMSCall) DoAndReturn(f func(domain.OTPSMSAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetOTPSMSCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetPasswordVerificationCode mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetPasswordVerificationCode(value domain.PasswordVerificationCodeAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPasswordVerificationCode", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetPasswordVerificationCode indicates an expected call of SetPasswordVerificationCode. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetPasswordVerificationCode(value any) *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPasswordVerificationCode", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetPasswordVerificationCode), value) + return &MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall) Do(f func(domain.PasswordVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall) DoAndReturn(f func(domain.PasswordVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordVerificationCodeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetPasswordlessInitCode mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetPasswordlessInitCode(value domain.PasswordlessInitCodeAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPasswordlessInitCode", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetPasswordlessInitCode indicates an expected call of SetPasswordlessInitCode. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetPasswordlessInitCode(value any) *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPasswordlessInitCode", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetPasswordlessInitCode), value) + return &MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall) Do(f func(domain.PasswordlessInitCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall) DoAndReturn(f func(domain.PasswordlessInitCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPasswordlessInitCodeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetPhoneVerificationCode mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetPhoneVerificationCode(value domain.PhoneVerificationCodeAttributes) json.JsonUpdate { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPhoneVerificationCode", value) + ret0, _ := ret[0].(json.JsonUpdate) + return ret0 +} + +// SetPhoneVerificationCode indicates an expected call of SetPhoneVerificationCode. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetPhoneVerificationCode(value any) *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPhoneVerificationCode", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetPhoneVerificationCode), value) + return &MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall) Return(arg0 json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall) Do(f func(domain.PhoneVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall) DoAndReturn(f func(domain.PhoneVerificationCodeAttributes) json.JsonUpdate) *MockSecretGeneratorSettingsRepositorySetPhoneVerificationCodeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetSettingFields mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetSettingFields(value domain.SecretGeneratorSettingsAttributes) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetSettingFields", value) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetSettingFields indicates an expected call of SetSettingFields. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetSettingFields(value any) *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSettingFields", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetSettingFields), value) + return &MockSecretGeneratorSettingsRepositorySetSettingFieldsCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetSettingFieldsCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetSettingFieldsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall) Return(arg0 database.Change) *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall) Do(f func(domain.SecretGeneratorSettingsAttributes) database.Change) *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall) DoAndReturn(f func(domain.SecretGeneratorSettingsAttributes) database.Change) *MockSecretGeneratorSettingsRepositorySetSettingFieldsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetUpdatedAt mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SetUpdatedAt(updatedAt *time.Time) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetUpdatedAt", updatedAt) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetUpdatedAt indicates an expected call of SetUpdatedAt. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SetUpdatedAt(updatedAt any) *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUpdatedAt", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SetUpdatedAt), updatedAt) + return &MockSecretGeneratorSettingsRepositorySetUpdatedAtCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySetUpdatedAtCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySetUpdatedAtCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall) Return(arg0 database.Change) *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall) Do(f func(*time.Time) database.Change) *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall) DoAndReturn(f func(*time.Time) database.Change) *MockSecretGeneratorSettingsRepositorySetUpdatedAtCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SettingsColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) SettingsColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SettingsColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// SettingsColumn indicates an expected call of SettingsColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) SettingsColumn() *MockSecretGeneratorSettingsRepositorySettingsColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SettingsColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).SettingsColumn)) + return &MockSecretGeneratorSettingsRepositorySettingsColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositorySettingsColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositorySettingsColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositorySettingsColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositorySettingsColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositorySettingsColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositorySettingsColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositorySettingsColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositorySettingsColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// StateColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) StateColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// StateColumn indicates an expected call of StateColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) StateColumn() *MockSecretGeneratorSettingsRepositoryStateColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).StateColumn)) + return &MockSecretGeneratorSettingsRepositoryStateColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryStateColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryStateColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryStateColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryStateColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryStateColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryStateColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryStateColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryStateColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TypeColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) TypeColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TypeColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// TypeColumn indicates an expected call of TypeColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) TypeColumn() *MockSecretGeneratorSettingsRepositoryTypeColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TypeColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).TypeColumn)) + return &MockSecretGeneratorSettingsRepositoryTypeColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryTypeColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryTypeColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryTypeColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryTypeColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryTypeColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryTypeColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryTypeColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryTypeColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UniqueColumns mocks base method. +func (m *MockSecretGeneratorSettingsRepository) UniqueColumns() []database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UniqueColumns") + ret0, _ := ret[0].([]database.Column) + return ret0 +} + +// UniqueColumns indicates an expected call of UniqueColumns. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) UniqueColumns() *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UniqueColumns", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).UniqueColumns)) + return &MockSecretGeneratorSettingsRepositoryUniqueColumnsCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryUniqueColumnsCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryUniqueColumnsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall) Return(arg0 []database.Column) *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall) Do(f func() []database.Column) *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall) DoAndReturn(f func() []database.Column) *MockSecretGeneratorSettingsRepositoryUniqueColumnsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UniqueCondition mocks base method. +func (m *MockSecretGeneratorSettingsRepository) UniqueCondition(instanceID string, orgID *string, typ domain.SettingType, state domain.SettingState) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UniqueCondition", instanceID, orgID, typ, state) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// UniqueCondition indicates an expected call of UniqueCondition. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) UniqueCondition(instanceID, orgID, typ, state any) *MockSecretGeneratorSettingsRepositoryUniqueConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UniqueCondition", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).UniqueCondition), instanceID, orgID, typ, state) + return &MockSecretGeneratorSettingsRepositoryUniqueConditionCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryUniqueConditionCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryUniqueConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryUniqueConditionCall) Return(arg0 database.Condition) *MockSecretGeneratorSettingsRepositoryUniqueConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryUniqueConditionCall) Do(f func(string, *string, domain.SettingType, domain.SettingState) database.Condition) *MockSecretGeneratorSettingsRepositoryUniqueConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryUniqueConditionCall) DoAndReturn(f func(string, *string, domain.SettingType, domain.SettingState) database.Condition) *MockSecretGeneratorSettingsRepositoryUniqueConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdatedAtColumn mocks base method. +func (m *MockSecretGeneratorSettingsRepository) UpdatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// UpdatedAtColumn indicates an expected call of UpdatedAtColumn. +func (mr *MockSecretGeneratorSettingsRepositoryMockRecorder) UpdatedAtColumn() *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedAtColumn", reflect.TypeOf((*MockSecretGeneratorSettingsRepository)(nil).UpdatedAtColumn)) + return &MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall{Call: call} +} + +// MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall wrap *gomock.Call +type MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall) Return(arg0 database.Column) *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall) Do(f func() database.Column) *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall) DoAndReturn(f func() database.Column) *MockSecretGeneratorSettingsRepositoryUpdatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/backend/v3/domain/settings.go b/backend/v3/domain/settings.go index 2edc06c2d..e60ad650b 100644 --- a/backend/v3/domain/settings.go +++ b/backend/v3/domain/settings.go @@ -23,6 +23,7 @@ const ( SettingTypeOrganization SettingTypeNotification SettingTypeLegalAndSupport + SettingTypeSecretGenerator ) //go:generate enumer -type SettingState -transform snake -trimprefix SettingState -sql @@ -428,3 +429,89 @@ type LegalAndSupportSettingsRepository interface { settingsRepository[LegalAndSupportSettings] legalAndSupportSettingsJSONChanges } + +type SecretGeneratorSettings struct { + Settings + SecretGeneratorSettingsAttributes +} + +//go:generate mockgen -typed -package domainmock -destination ./mock/secret_generator_settings.mock.go . SecretGeneratorSettingsRepository +type SecretGeneratorSettingsRepository interface { + settingsRepository[SecretGeneratorSettings] + secretGeneratorSettingsJSONChanges +} + +type secretGeneratorSettingsJSONChanges interface { + SetSettingFields(value SecretGeneratorSettingsAttributes) database.Change + + SetClientSecret(value ClientSecretAttributes) db_json.JsonUpdate + SetInitializeUserCode(value InitializeUserCodeAttributes) db_json.JsonUpdate + SetEmailVerificationCode(value EmailVerificationCodeAttributes) db_json.JsonUpdate + SetPhoneVerificationCode(value PhoneVerificationCodeAttributes) db_json.JsonUpdate + SetPasswordVerificationCode(value PasswordVerificationCodeAttributes) db_json.JsonUpdate + SetPasswordlessInitCode(value PasswordlessInitCodeAttributes) db_json.JsonUpdate + SetDomainVerification(value DomainVerificationAttributes) db_json.JsonUpdate + SetOTPSMS(value OTPSMSAttributes) db_json.JsonUpdate + SetOTPEmail(value OTPEmailAttributes) db_json.JsonUpdate +} + +type SecretGeneratorSettingsAttributes struct { + ClientSecret *ClientSecretAttributes `json:"clientSecret,omitempty"` + InitializeUserCode *InitializeUserCodeAttributes `json:"initializeUserCode,omitempty"` + EmailVerificationCode *EmailVerificationCodeAttributes `json:"emailVerificationCode,omitempty"` + PhoneVerificationCode *PhoneVerificationCodeAttributes `json:"phoneVerificationCode,omitempty"` + PasswordVerificationCode *PasswordVerificationCodeAttributes `json:"passwordVerificationCode,omitempty"` + PasswordlessInitCode *PasswordlessInitCodeAttributes `json:"passwordlessInitCode,omitempty"` + DomainVerification *DomainVerificationAttributes `json:"domainVerification,omitempty"` + OTPSMS *OTPSMSAttributes `json:"otpSms,omitempty"` + OTPEmail *OTPEmailAttributes `json:"otpEmail,omitempty"` +} + +type ClientSecretAttributes struct { + SecretGeneratorAttrs +} + +type InitializeUserCodeAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type EmailVerificationCodeAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type PhoneVerificationCodeAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type PasswordVerificationCodeAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type PasswordlessInitCodeAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type DomainVerificationAttributes struct { + SecretGeneratorAttrs +} + +type OTPSMSAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type OTPEmailAttributes struct { + SecretGeneratorAttrsWithExpiry +} + +type SecretGeneratorAttrs struct { + Length *uint `json:"length,omitempty"` + IncludeLowerLetters *bool `json:"includeLowerLetters,omitempty"` + IncludeUpperLetters *bool `json:"includeUpperLetters,omitempty"` + IncludeDigits *bool `json:"includeDigits,omitempty"` + IncludeSymbols *bool `json:"includeSymbols,omitempty"` +} + +type SecretGeneratorAttrsWithExpiry struct { + Expiry *time.Duration `json:"expiry,omitempty"` + SecretGeneratorAttrs +} diff --git a/backend/v3/domain/settingtype_enumer.go b/backend/v3/domain/settingtype_enumer.go index cb668be68..ee76a73a8 100644 --- a/backend/v3/domain/settingtype_enumer.go +++ b/backend/v3/domain/settingtype_enumer.go @@ -8,11 +8,11 @@ import ( "strings" ) -const _SettingTypeName = "loginbrandingpassword_complexitypassword_expirydomainlockoutsecurityorganizationnotificationlegal_and_support" +const _SettingTypeName = "loginbrandingpassword_complexitypassword_expirydomainlockoutsecurityorganizationnotificationlegal_and_supportsecret_generator" -var _SettingTypeIndex = [...]uint8{0, 5, 13, 32, 47, 53, 60, 68, 80, 92, 109} +var _SettingTypeIndex = [...]uint8{0, 5, 13, 32, 47, 53, 60, 68, 80, 92, 109, 125} -const _SettingTypeLowerName = "loginbrandingpassword_complexitypassword_expirydomainlockoutsecurityorganizationnotificationlegal_and_support" +const _SettingTypeLowerName = "loginbrandingpassword_complexitypassword_expirydomainlockoutsecurityorganizationnotificationlegal_and_supportsecret_generator" func (i SettingType) String() string { if i >= SettingType(len(_SettingTypeIndex)-1) { @@ -35,31 +35,34 @@ func _SettingTypeNoOp() { _ = x[SettingTypeOrganization-(7)] _ = x[SettingTypeNotification-(8)] _ = x[SettingTypeLegalAndSupport-(9)] + _ = x[SettingTypeSecretGenerator-(10)] } -var _SettingTypeValues = []SettingType{SettingTypeLogin, SettingTypeBranding, SettingTypePasswordComplexity, SettingTypePasswordExpiry, SettingTypeDomain, SettingTypeLockout, SettingTypeSecurity, SettingTypeOrganization, SettingTypeNotification, SettingTypeLegalAndSupport} +var _SettingTypeValues = []SettingType{SettingTypeLogin, SettingTypeBranding, SettingTypePasswordComplexity, SettingTypePasswordExpiry, SettingTypeDomain, SettingTypeLockout, SettingTypeSecurity, SettingTypeOrganization, SettingTypeNotification, SettingTypeLegalAndSupport, SettingTypeSecretGenerator} var _SettingTypeNameToValueMap = map[string]SettingType{ - _SettingTypeName[0:5]: SettingTypeLogin, - _SettingTypeLowerName[0:5]: SettingTypeLogin, - _SettingTypeName[5:13]: SettingTypeBranding, - _SettingTypeLowerName[5:13]: SettingTypeBranding, - _SettingTypeName[13:32]: SettingTypePasswordComplexity, - _SettingTypeLowerName[13:32]: SettingTypePasswordComplexity, - _SettingTypeName[32:47]: SettingTypePasswordExpiry, - _SettingTypeLowerName[32:47]: SettingTypePasswordExpiry, - _SettingTypeName[47:53]: SettingTypeDomain, - _SettingTypeLowerName[47:53]: SettingTypeDomain, - _SettingTypeName[53:60]: SettingTypeLockout, - _SettingTypeLowerName[53:60]: SettingTypeLockout, - _SettingTypeName[60:68]: SettingTypeSecurity, - _SettingTypeLowerName[60:68]: SettingTypeSecurity, - _SettingTypeName[68:80]: SettingTypeOrganization, - _SettingTypeLowerName[68:80]: SettingTypeOrganization, - _SettingTypeName[80:92]: SettingTypeNotification, - _SettingTypeLowerName[80:92]: SettingTypeNotification, - _SettingTypeName[92:109]: SettingTypeLegalAndSupport, - _SettingTypeLowerName[92:109]: SettingTypeLegalAndSupport, + _SettingTypeName[0:5]: SettingTypeLogin, + _SettingTypeLowerName[0:5]: SettingTypeLogin, + _SettingTypeName[5:13]: SettingTypeBranding, + _SettingTypeLowerName[5:13]: SettingTypeBranding, + _SettingTypeName[13:32]: SettingTypePasswordComplexity, + _SettingTypeLowerName[13:32]: SettingTypePasswordComplexity, + _SettingTypeName[32:47]: SettingTypePasswordExpiry, + _SettingTypeLowerName[32:47]: SettingTypePasswordExpiry, + _SettingTypeName[47:53]: SettingTypeDomain, + _SettingTypeLowerName[47:53]: SettingTypeDomain, + _SettingTypeName[53:60]: SettingTypeLockout, + _SettingTypeLowerName[53:60]: SettingTypeLockout, + _SettingTypeName[60:68]: SettingTypeSecurity, + _SettingTypeLowerName[60:68]: SettingTypeSecurity, + _SettingTypeName[68:80]: SettingTypeOrganization, + _SettingTypeLowerName[68:80]: SettingTypeOrganization, + _SettingTypeName[80:92]: SettingTypeNotification, + _SettingTypeLowerName[80:92]: SettingTypeNotification, + _SettingTypeName[92:109]: SettingTypeLegalAndSupport, + _SettingTypeLowerName[92:109]: SettingTypeLegalAndSupport, + _SettingTypeName[109:125]: SettingTypeSecretGenerator, + _SettingTypeLowerName[109:125]: SettingTypeSecretGenerator, } var _SettingTypeNames = []string{ @@ -73,6 +76,7 @@ var _SettingTypeNames = []string{ _SettingTypeName[68:80], _SettingTypeName[80:92], _SettingTypeName[92:109], + _SettingTypeName[109:125], } // SettingTypeString retrieves an enum value from the enum constants string name. diff --git a/backend/v3/storage/database/dialect/postgres/migration/009_settings_table/up.sql b/backend/v3/storage/database/dialect/postgres/migration/009_settings_table/up.sql index 17b16fd92..fb3b6314a 100644 --- a/backend/v3/storage/database/dialect/postgres/migration/009_settings_table/up.sql +++ b/backend/v3/storage/database/dialect/postgres/migration/009_settings_table/up.sql @@ -8,7 +8,8 @@ CREATE TYPE zitadel.settings_type AS ENUM ( 'security', 'organization', 'notification', - 'legal_and_support' + 'legal_and_support', + 'secret_generator' ); CREATE TYPE zitadel.settings_state AS ENUM ( diff --git a/backend/v3/storage/database/errors.go b/backend/v3/storage/database/errors.go index de6cb794c..921bdd86e 100644 --- a/backend/v3/storage/database/errors.go +++ b/backend/v3/storage/database/errors.go @@ -6,7 +6,8 @@ import ( ) var ( - ErrNoChanges = errors.New("update must contain a change") + ErrNoChanges = errors.New("update must contain a change") + ErrInvalidChangeTarget = errors.New("change target must not be nil") ) type MissingConditionError struct { diff --git a/backend/v3/storage/database/events_testing/settings_instance_test.go b/backend/v3/storage/database/events_testing/settings_instance_test.go index 239626ad5..9984a4393 100644 --- a/backend/v3/storage/database/events_testing/settings_instance_test.go +++ b/backend/v3/storage/database/events_testing/settings_instance_test.go @@ -26,6 +26,7 @@ import ( "github.com/zitadel/zitadel/pkg/grpc/admin" instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" "github.com/zitadel/zitadel/pkg/grpc/policy" + settings_pb "github.com/zitadel/zitadel/pkg/grpc/settings" ) //go:embed picture.png @@ -1387,3 +1388,150 @@ func TestServer_TestInstanceLegalAndSupportSettingsReduces(t *testing.T) { }, retryDuration, tick) }) } + +func TestServer_TestInstanceSecretGeneratorSettingsReduces(t *testing.T) { + t.Parallel() + settingsRepo := repository.SecretGeneratorSettingsRepository() + newInstance := integration.NewInstance(t.Context()) + + IAMCTX := newInstance.WithAuthorizationToken(t.Context(), integration.UserTypeIAMOwner) + + t.Run("test secret generator settings set", func(t *testing.T) { + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(IAMCTX, time.Second*20) + assert.EventuallyWithT(t, func(collect *assert.CollectT) { + setting, err := settingsRepo.Get( + IAMCTX, pool, + database.WithCondition( + settingsRepo.UniqueCondition(newInstance.ID(), nil, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + ), + ) + require.NoError(collect, err) + // ClientSecret + assert.Equal(collect, uint(64), *setting.ClientSecret.Length) + assert.Equal(collect, true, *setting.ClientSecret.IncludeLowerLetters) + assert.Equal(collect, true, *setting.ClientSecret.IncludeUpperLetters) + assert.Equal(collect, true, *setting.ClientSecret.IncludeDigits) + assert.Equal(collect, false, *setting.ClientSecret.IncludeSymbols) + + // InitializeUserCode + assert.Equal(collect, uint(6), *setting.InitializeUserCode.Length) + assert.Equal(collect, 72*time.Hour, *setting.InitializeUserCode.Expiry) + assert.Equal(collect, false, *setting.InitializeUserCode.IncludeLowerLetters) + assert.Equal(collect, true, *setting.InitializeUserCode.IncludeUpperLetters) + assert.Equal(collect, true, *setting.InitializeUserCode.IncludeDigits) + assert.Equal(collect, false, *setting.InitializeUserCode.IncludeSymbols) + + // EmailVerificationCode + assert.Equal(collect, uint(6), *setting.EmailVerificationCode.Length) + assert.Equal(collect, 1*time.Hour, *setting.EmailVerificationCode.Expiry) + assert.Equal(collect, false, *setting.EmailVerificationCode.IncludeLowerLetters) + assert.Equal(collect, true, *setting.EmailVerificationCode.IncludeUpperLetters) + assert.Equal(collect, true, *setting.EmailVerificationCode.IncludeDigits) + assert.Equal(collect, false, *setting.EmailVerificationCode.IncludeSymbols) + + // PhoneVerificationCode + assert.Equal(collect, uint(6), *setting.PhoneVerificationCode.Length) + assert.Equal(collect, 1*time.Hour, *setting.PhoneVerificationCode.Expiry) + assert.Equal(collect, false, *setting.PhoneVerificationCode.IncludeLowerLetters) + assert.Equal(collect, true, *setting.PhoneVerificationCode.IncludeUpperLetters) + assert.Equal(collect, true, *setting.PhoneVerificationCode.IncludeDigits) + assert.Equal(collect, false, *setting.PhoneVerificationCode.IncludeSymbols) + + // PasswordVerificationCode + assert.Equal(collect, uint(6), *setting.PasswordVerificationCode.Length) + assert.Equal(collect, 1*time.Hour, *setting.PasswordVerificationCode.Expiry) + assert.Equal(collect, false, *setting.PasswordVerificationCode.IncludeLowerLetters) + assert.Equal(collect, true, *setting.PasswordVerificationCode.IncludeUpperLetters) + assert.Equal(collect, true, *setting.PasswordVerificationCode.IncludeDigits) + assert.Equal(collect, false, *setting.PasswordVerificationCode.IncludeSymbols) + + // PasswordlessInitCode + assert.Equal(collect, uint(12), *setting.PasswordlessInitCode.Length) + assert.Equal(collect, 1*time.Hour, *setting.PasswordlessInitCode.Expiry) + assert.Equal(collect, true, *setting.PasswordlessInitCode.IncludeLowerLetters) + assert.Equal(collect, true, *setting.PasswordlessInitCode.IncludeUpperLetters) + assert.Equal(collect, true, *setting.PasswordlessInitCode.IncludeDigits) + assert.Equal(collect, false, *setting.PasswordlessInitCode.IncludeSymbols) + + // DomainVerification + assert.Equal(collect, uint(32), *setting.DomainVerification.Length) + assert.Equal(collect, true, *setting.DomainVerification.IncludeLowerLetters) + assert.Equal(collect, true, *setting.DomainVerification.IncludeUpperLetters) + assert.Equal(collect, true, *setting.DomainVerification.IncludeDigits) + assert.Equal(collect, false, *setting.DomainVerification.IncludeSymbols) + + // OTPSMS + assert.Equal(collect, uint(8), *setting.OTPSMS.Length) + assert.Equal(collect, 5*time.Minute, *setting.OTPSMS.Expiry) + assert.Equal(collect, false, *setting.OTPSMS.IncludeLowerLetters) + assert.Equal(collect, false, *setting.OTPSMS.IncludeUpperLetters) + assert.Equal(collect, true, *setting.OTPSMS.IncludeDigits) + assert.Equal(collect, false, *setting.OTPSMS.IncludeSymbols) + + // OTPEmail + assert.Equal(collect, uint(8), *setting.OTPEmail.Length) + assert.Equal(collect, 5*time.Minute, *setting.OTPEmail.Expiry) + assert.Equal(collect, false, *setting.OTPEmail.IncludeLowerLetters) + assert.Equal(collect, false, *setting.OTPEmail.IncludeUpperLetters) + assert.Equal(collect, true, *setting.OTPEmail.IncludeDigits) + assert.Equal(collect, false, *setting.OTPEmail.IncludeSymbols) + }, retryDuration, tick) + }) + + t.Run("test secret generator settings update", func(t *testing.T) { + before := time.Now() + _, err := newInstance.Client.Admin.UpdateSecretGenerator(IAMCTX, &admin.UpdateSecretGeneratorRequest{ + GeneratorType: settings_pb.SecretGeneratorType_SECRET_GENERATOR_TYPE_INIT_CODE, + IncludeLowerLetters: true, + Expiry: durationpb.New(24 * time.Hour), + Length: uint32(8), + }) + require.NoError(t, err) + after := time.Now() + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(IAMCTX, time.Second*20) + assert.EventuallyWithT(t, func(collect *assert.CollectT) { + setting, err := settingsRepo.Get( + IAMCTX, pool, + database.WithCondition( + settingsRepo.UniqueCondition(newInstance.ID(), nil, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + ), + ) + require.NoError(t, err) + assert.Equal(collect, uint(8), *setting.InitializeUserCode.Length) + assert.Equal(collect, 24*time.Hour, *setting.InitializeUserCode.Expiry) + assert.Equal(collect, true, *setting.InitializeUserCode.IncludeLowerLetters) + assert.WithinRange(collect, setting.UpdatedAt, before, after) + }, retryDuration, tick) + }) + + t.Run("test delete instance reduces", func(t *testing.T) { + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(IAMCTX, time.Second*20) + assert.EventuallyWithT(t, func(collect *assert.CollectT) { + setting, err := settingsRepo.Get( + IAMCTX, pool, + database.WithCondition( + settingsRepo.UniqueCondition(newInstance.ID(), nil, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + ), + ) + require.NoError(collect, err) + require.NotNil(collect, setting) + }, retryDuration, tick) + + _, err := newInstance.Client.InstanceV2Beta.DeleteInstance(CTX, &instance.DeleteInstanceRequest{ + InstanceId: newInstance.ID(), + }) + require.NoError(t, err) + + retryDuration, tick = integration.WaitForAndTickWithMaxDuration(IAMCTX, time.Second*20) + assert.EventuallyWithT(t, func(collect *assert.CollectT) { + _, err := settingsRepo.Get( + IAMCTX, pool, + database.WithCondition( + settingsRepo.UniqueCondition(newInstance.ID(), nil, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + ), + ) + require.ErrorIs(collect, err, new(database.NoRowFoundError)) + }, retryDuration, tick) + }) +} diff --git a/backend/v3/storage/database/repository/settings.go b/backend/v3/storage/database/repository/settings.go index 0af22e94e..326cf8f70 100644 --- a/backend/v3/storage/database/repository/settings.go +++ b/backend/v3/storage/database/repository/settings.go @@ -149,6 +149,10 @@ func (s settings) list(ctx context.Context, client database.QueryExecutor, opts } func (s settings) set(ctx context.Context, client database.QueryExecutor, settings *domain.Settings, changes ...database.Change) error { + if settings == nil { + return database.ErrInvalidChangeTarget + } + var ( id, createdAt, updatedAt any = database.DefaultInstruction, database.DefaultInstruction, database.DefaultInstruction ) @@ -378,6 +382,10 @@ func LoginSettingsRepository() domain.LoginSettingsRepository { var _ domain.LoginSettingsRepository = (*loginSettings)(nil) func (s loginSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LoginSettings) error { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeLogin settings.State = domain.SettingStateActive @@ -572,6 +580,10 @@ func BrandingSettingsRepository() domain.BrandingSettingsRepository { var _ domain.BrandingSettingsRepository = (*brandingSettings)(nil) func (s brandingSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.BrandingSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeBranding settings.State = domain.SettingStatePreview @@ -719,6 +731,10 @@ func PasswordComplexitySettingsRepository() domain.PasswordComplexitySettingsRep var _ domain.PasswordComplexitySettingsRepository = (*passwordComplexitySettings)(nil) func (s passwordComplexitySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.PasswordComplexitySettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypePasswordComplexity settings.State = domain.SettingStateActive @@ -801,6 +817,10 @@ func PasswordExpirySettingsRepository() domain.PasswordExpirySettingsRepository } func (s passwordExpirySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.PasswordExpirySettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypePasswordExpiry settings.State = domain.SettingStateActive @@ -889,6 +909,10 @@ func LockoutSettingsRepository() domain.LockoutSettingsRepository { var _ domain.LockoutSettingsRepository = (*lockoutSettings)(nil) func (s lockoutSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LockoutSettings) error { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeLockout settings.State = domain.SettingStateActive @@ -977,6 +1001,10 @@ func SecuritySettingsRepository() domain.SecuritySettingsRepository { var _ domain.SecuritySettingsRepository = (*securitySettings)(nil) func (s securitySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.SecuritySettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeSecurity settings.State = domain.SettingStateActive @@ -1065,6 +1093,10 @@ func DomainSettingsRepository() domain.DomainSettingsRepository { var _ domain.DomainSettingsRepository = (*domainSettings)(nil) func (s domainSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.DomainSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeDomain settings.State = domain.SettingStateActive @@ -1139,6 +1171,10 @@ func OrganizationSettingsRepository() domain.OrganizationSettingsRepository { var _ domain.OrganizationSettingsRepository = (*organizationSettings)(nil) func (s organizationSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.OrganizationSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeOrganization settings.State = domain.SettingStateActive @@ -1213,6 +1249,10 @@ func NotificationSettingsRepository() domain.NotificationSettingsRepository { var _ domain.NotificationSettingsRepository = (*notificationSettings)(nil) func (s notificationSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.NotificationSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeNotification settings.State = domain.SettingStateActive @@ -1329,6 +1369,10 @@ func LegalAndSupportSettingsRepository() domain.LegalAndSupportSettingsRepositor var _ domain.LegalAndSupportSettingsRepository = (*legalAndSupportSettings)(nil) func (s legalAndSupportSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LegalAndSupportSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + settings.Type = domain.SettingTypeLegalAndSupport settings.State = domain.SettingStateActive @@ -1375,6 +1419,141 @@ func (s legalAndSupportSettings) Get(ctx context.Context, client database.QueryE return item, nil } +// ------------------------------------------------------------- +// secret generators +// ------------------------------------------------------------- + +type secretGeneratorSettings struct { + settings +} + +func (s secretGeneratorSettings) SetSettingFields(value domain.SecretGeneratorSettingsAttributes) database.Change { + changes := make([]db_json.JsonUpdate, 0, 11) + if value.ClientSecret != nil { + changes = append(changes, s.SetClientSecret(*value.ClientSecret)) + } + if value.InitializeUserCode != nil { + changes = append(changes, s.SetInitializeUserCode(*value.InitializeUserCode)) + } + if value.EmailVerificationCode != nil { + changes = append(changes, s.SetEmailVerificationCode(*value.EmailVerificationCode)) + } + if value.PhoneVerificationCode != nil { + changes = append(changes, s.SetPhoneVerificationCode(*value.PhoneVerificationCode)) + } + if value.PasswordVerificationCode != nil { + changes = append(changes, s.SetPasswordVerificationCode(*value.PasswordVerificationCode)) + } + if value.PasswordlessInitCode != nil { + changes = append(changes, s.SetPasswordlessInitCode(*value.PasswordlessInitCode)) + } + if value.DomainVerification != nil { + changes = append(changes, s.SetDomainVerification(*value.DomainVerification)) + } + if value.OTPSMS != nil { + changes = append(changes, s.SetOTPSMS(*value.OTPSMS)) + } + if value.OTPEmail != nil { + changes = append(changes, s.SetOTPEmail(*value.OTPEmail)) + } + return db_json.NewJsonChanges(s.SettingsColumn(), changes...) +} + +func (s secretGeneratorSettings) SetClientSecret(value domain.ClientSecretAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"clientSecret"}, value) +} + +func (s secretGeneratorSettings) SetInitializeUserCode(value domain.InitializeUserCodeAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"initializeUserCode"}, value) +} + +func (s secretGeneratorSettings) SetEmailVerificationCode(value domain.EmailVerificationCodeAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"emailVerificationCode"}, value) +} + +func (s secretGeneratorSettings) SetPhoneVerificationCode(value domain.PhoneVerificationCodeAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"phoneVerificationCode"}, value) +} + +func (s secretGeneratorSettings) SetPasswordVerificationCode(value domain.PasswordVerificationCodeAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"passwordVerificationCode"}, value) +} + +func (s secretGeneratorSettings) SetPasswordlessInitCode(value domain.PasswordlessInitCodeAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"passwordlessInitCode"}, value) +} + +func (s secretGeneratorSettings) SetDomainVerification(value domain.DomainVerificationAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"domainVerification"}, value) +} + +func (s secretGeneratorSettings) SetOTPSMS(value domain.OTPSMSAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"otpSms"}, value) +} + +func (s secretGeneratorSettings) SetOTPEmail(value domain.OTPEmailAttributes) db_json.JsonUpdate { + return db_json.NewFieldChange([]string{"otpEmail"}, value) +} + +func SecretGeneratorSettingsRepository() domain.SecretGeneratorSettingsRepository { + return &secretGeneratorSettings{ + settings{}, + } +} + +var _ domain.SecretGeneratorSettingsRepository = (*secretGeneratorSettings)(nil) + +func (s secretGeneratorSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.SecretGeneratorSettings) (err error) { + if settings == nil { + return database.ErrInvalidChangeTarget + } + + settings.Type = domain.SettingTypeSecretGenerator + settings.State = domain.SettingStateActive + + settingsJSON, err := json.Marshal(settings.SecretGeneratorSettingsAttributes) + if err != nil { + return err + } + settings.Settings.Settings = settingsJSON + if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.SecretGeneratorSettingsAttributes)); err != nil { + return err + } + settings.Settings.Settings = nil + return nil +} + +func (s secretGeneratorSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.SecretGeneratorSettings, error) { + settings, err := s.list(ctx, client, opts...) + if err != nil { + return nil, err + } + + list := make([]*domain.SecretGeneratorSettings, len(settings)) + for i := range settings { + list[i] = &domain.SecretGeneratorSettings{Settings: *settings[i]} + if err := json.Unmarshal(list[i].Settings.Settings, &list[i].SecretGeneratorSettingsAttributes); err != nil { + return nil, err + } + list[i].Settings.Settings = nil + } + return list, nil +} + +func (s secretGeneratorSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.SecretGeneratorSettings, error) { + settings, err := s.get(ctx, client, opts...) + if err != nil { + return nil, err + } + + item := &domain.SecretGeneratorSettings{Settings: *settings} + if err = json.Unmarshal(item.Settings.Settings, &item.SecretGeneratorSettingsAttributes); err != nil { + return nil, err + } + item.Settings.Settings = nil + return item, nil +} + // ------------------------------------------------------------- // helpers // ------------------------------------------------------------- diff --git a/backend/v3/storage/database/repository/settings_test.go b/backend/v3/storage/database/repository/settings_test.go index 5c51da1d6..39c724445 100644 --- a/backend/v3/storage/database/repository/settings_test.go +++ b/backend/v3/storage/database/repository/settings_test.go @@ -498,6 +498,11 @@ func TestSetLoginSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1167,6 +1172,11 @@ func TestSetBrandingSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1912,6 +1922,11 @@ func TestSetPasswordComplexitySettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -2300,6 +2315,11 @@ func TestSetPasswordExpirySettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -2695,6 +2715,11 @@ func TestSetLockoutSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -3092,6 +3117,11 @@ func TestSetSecuritySettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -3489,6 +3519,11 @@ func TestSetDomainSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -3860,6 +3895,11 @@ func TestSetOrganizationSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -4227,6 +4267,11 @@ func TestSetNotificationSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -4672,6 +4717,11 @@ func TestSetLegalAndSupportSettings(t *testing.T) { }, wantErr: new(database.ForeignKeyError), }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -4774,3 +4824,325 @@ func TestDeleteLegalAndSupportSettings(t *testing.T) { }) } } + +func TestGetSecretGeneratorSettings(t *testing.T) { + tx, rollback := transactionForRollback(t) + defer rollback() + + firstInstanceID := createInstance(t, tx) + secondInstanceID := createInstance(t, tx) + firstOrgID := createOrganization(t, tx, firstInstanceID) + secondOrgID := createOrganization(t, tx, secondInstanceID) + repo := repository.SecretGeneratorSettingsRepository() + + settings := []*domain.SecretGeneratorSettings{ + createSecretGeneratorSettings(firstInstanceID, nil), + createSecretGeneratorSettings(secondInstanceID, nil), + createSecretGeneratorSettings(firstInstanceID, gu.Ptr(firstOrgID)), + createSecretGeneratorSettings(secondInstanceID, gu.Ptr(secondOrgID)), + } + + for _, setting := range settings { + err := repo.Set(t.Context(), tx, setting) + require.NoError(t, err) + } + + tests := []struct { + name string + condition database.Condition + want *domain.SecretGeneratorSettings + wantErr error + }{ + { + name: "incomplete condition", + condition: repo.IDCondition(settings[0].ID), + wantErr: database.NewMissingConditionError(repo.IDColumn()), + }, + { + name: "not found", + condition: repo.PrimaryKeyCondition(firstInstanceID, "nix"), + wantErr: database.NewNoRowFoundError(nil), + }, + { + name: "too many", + condition: repo.InstanceIDCondition(firstInstanceID), + wantErr: database.NewMultipleRowsFoundError(nil), + }, + { + name: "ok, instance", + condition: repo.PrimaryKeyCondition(firstInstanceID, settings[0].ID), + want: settings[0], + }, + { + name: "ok, organization", + condition: repo.PrimaryKeyCondition(secondInstanceID, settings[3].ID), + want: settings[3], + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := repo.Get(t.Context(), tx, database.WithCondition(tt.condition)) + require.ErrorIs(t, err, tt.wantErr) + assert.EqualExportedValues(t, tt.want, got) + }) + } +} + +func TestListSecretGeneratorSettings(t *testing.T) { + tx, rollback := transactionForRollback(t) + defer rollback() + + firstInstanceID := createInstance(t, tx) + secondInstanceID := createInstance(t, tx) + firstOrgID := createOrganization(t, tx, firstInstanceID) + secondOrgID := createOrganization(t, tx, secondInstanceID) + repo := repository.SecretGeneratorSettingsRepository() + + settings := []*domain.SecretGeneratorSettings{ + createSecretGeneratorSettings(firstInstanceID, nil), + createSecretGeneratorSettings(secondInstanceID, nil), + createSecretGeneratorSettings(firstInstanceID, gu.Ptr(firstOrgID)), + createSecretGeneratorSettings(secondInstanceID, gu.Ptr(secondOrgID)), + } + + for _, setting := range settings { + err := repo.Set(t.Context(), tx, setting) + require.NoError(t, err) + } + + tests := []struct { + name string + condition database.Condition + want []*domain.SecretGeneratorSettings + wantErr error + }{ + { + name: "incomplete condition", + condition: repo.OrganizationIDCondition(gu.Ptr(firstOrgID)), + wantErr: database.NewMissingConditionError(repo.IDColumn()), + }, + { + name: "no results, ok", + condition: repo.PrimaryKeyCondition(firstInstanceID, "nix"), + want: []*domain.SecretGeneratorSettings{}, + }, + { + name: "all from instance", + condition: repo.InstanceIDCondition(firstInstanceID), + want: []*domain.SecretGeneratorSettings{settings[2], settings[0]}, + }, + { + name: "only from instance", + condition: database.And( + repo.InstanceIDCondition(firstInstanceID), + repo.OrganizationIDCondition(nil), + ), + want: []*domain.SecretGeneratorSettings{settings[0]}, + }, + { + name: "all from first org", + condition: database.And( + repo.InstanceIDCondition(firstInstanceID), + repo.OrganizationIDCondition(gu.Ptr(firstOrgID)), + ), + want: []*domain.SecretGeneratorSettings{settings[2]}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := repo.List(t.Context(), tx, + database.WithCondition(tt.condition), + database.WithOrderByAscending(repo.InstanceIDColumn(), repo.OrganizationIDColumn()), + ) + require.ErrorIs(t, err, tt.wantErr) + assert.EqualExportedValues(t, tt.want, got) + }) + } +} + +func TestSetSecretGeneratorSettings(t *testing.T) { + tx, rollback := transactionForRollback(t) + defer rollback() + + instanceID := createInstance(t, tx) + orgID := createOrganization(t, tx, instanceID) + repo := repository.SecretGeneratorSettingsRepository() + + existingSettings := createSecretGeneratorSettings(instanceID, gu.Ptr(orgID)) + + err := repo.Set(t.Context(), tx, existingSettings) + require.NoError(t, err) + + tests := []struct { + name string + settings *domain.SecretGeneratorSettings + wantErr error + }{ + { + name: "create instance", + settings: createSecretGeneratorSettings(instanceID, nil), + }, + { + name: "update organization", + settings: createSecretGeneratorSettings(instanceID, gu.Ptr(orgID)), + }, + { + name: "non-existing instance", + settings: createSecretGeneratorSettings("foo", nil), + wantErr: new(database.ForeignKeyError), + }, + { + name: "non-existing org", + settings: createSecretGeneratorSettings(instanceID, gu.Ptr("foo")), + wantErr: new(database.ForeignKeyError), + }, + { + name: "nil settings", + settings: nil, + wantErr: database.ErrInvalidChangeTarget, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + savepoint, rollback := savepointForRollback(t, tx) + defer rollback() + err := repo.Set(t.Context(), savepoint, tt.settings) + require.ErrorIs(t, err, tt.wantErr) + }) + } +} + +func TestDeleteSecretGeneratorSettings(t *testing.T) { + tx, rollback := transactionForRollback(t) + defer rollback() + + instanceID := createInstance(t, tx) + orgID := createOrganization(t, tx, instanceID) + repo := repository.SecretGeneratorSettingsRepository() + + existingInstanceSettings := createSecretGeneratorSettings(instanceID, nil) + err := repo.Set(t.Context(), tx, existingInstanceSettings) + require.NoError(t, err) + + existingOrganizationSettings := createSecretGeneratorSettings(instanceID, gu.Ptr(orgID)) + err = repo.Set(t.Context(), tx, existingOrganizationSettings) + require.NoError(t, err) + + tests := []struct { + name string + condition database.Condition + wantRowsAffected int64 + wantErr error + }{ + { + name: "incomplete condition", + condition: repo.InstanceIDCondition(instanceID), + wantRowsAffected: 0, + wantErr: database.NewMissingConditionError(repo.IDColumn()), + }, + { + name: "not found", + condition: repo.UniqueCondition(existingInstanceSettings.InstanceID, gu.Ptr("foo"), domain.SettingTypeSecretGenerator, domain.SettingStateActive), + wantRowsAffected: 0, + }, + { + name: "delete instance", + condition: repo.UniqueCondition(existingInstanceSettings.InstanceID, existingInstanceSettings.OrganizationID, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + wantRowsAffected: 1, + }, + { + name: "delete instance twice", + condition: repo.UniqueCondition(existingInstanceSettings.InstanceID, existingInstanceSettings.OrganizationID, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + wantRowsAffected: 0, + }, + { + name: "delete organization", + condition: repo.UniqueCondition(existingOrganizationSettings.InstanceID, existingOrganizationSettings.OrganizationID, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + wantRowsAffected: 1, + }, + { + name: "delete organization twice", + condition: repo.UniqueCondition(existingOrganizationSettings.InstanceID, existingOrganizationSettings.OrganizationID, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + wantRowsAffected: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rowsAffected, err := repo.Delete(t.Context(), tx, tt.condition) + require.ErrorIs(t, err, tt.wantErr) + assert.Equal(t, tt.wantRowsAffected, rowsAffected) + }) + } +} + +func createDefaultSecretGeneratorAttrs() domain.SecretGeneratorAttrs { + return domain.SecretGeneratorAttrs{ + Length: gu.Ptr(uint(32)), + IncludeUpperLetters: gu.Ptr(true), + IncludeLowerLetters: gu.Ptr(true), + IncludeDigits: gu.Ptr(true), + IncludeSymbols: gu.Ptr(false), + } +} + +func createDefaultSecretGeneratorAttrsWithExpiry(expiry time.Duration) domain.SecretGeneratorAttrsWithExpiry { + return domain.SecretGeneratorAttrsWithExpiry{ + Expiry: gu.Ptr(expiry), + SecretGeneratorAttrs: domain.SecretGeneratorAttrs{ + Length: gu.Ptr(uint(32)), + IncludeUpperLetters: gu.Ptr(true), + IncludeLowerLetters: gu.Ptr(true), + IncludeDigits: gu.Ptr(true), + IncludeSymbols: gu.Ptr(false), + }, + } +} + +func createDefaultSecretGeneratorSettingsAttributes() domain.SecretGeneratorSettingsAttributes { + attrs := createDefaultSecretGeneratorAttrs() + oneDay := 24 * time.Hour + thirtyMinutes := 30 * time.Minute + tenMinutes := 10 * time.Minute + + return domain.SecretGeneratorSettingsAttributes{ + ClientSecret: &domain.ClientSecretAttributes{ + SecretGeneratorAttrs: attrs, + }, + InitializeUserCode: &domain.InitializeUserCodeAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(oneDay), + }, + EmailVerificationCode: &domain.EmailVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(thirtyMinutes), + }, + PhoneVerificationCode: &domain.PhoneVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(thirtyMinutes), + }, + PasswordVerificationCode: &domain.PasswordVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(thirtyMinutes), + }, + PasswordlessInitCode: &domain.PasswordlessInitCodeAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(tenMinutes), + }, + DomainVerification: &domain.DomainVerificationAttributes{ + SecretGeneratorAttrs: attrs, + }, + OTPSMS: &domain.OTPSMSAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(thirtyMinutes), + }, + OTPEmail: &domain.OTPEmailAttributes{ + SecretGeneratorAttrsWithExpiry: createDefaultSecretGeneratorAttrsWithExpiry(thirtyMinutes), + }, + } +} + +func createSecretGeneratorSettings(instanceID string, organizationID *string) *domain.SecretGeneratorSettings { + return &domain.SecretGeneratorSettings{ + Settings: domain.Settings{ + InstanceID: instanceID, + OrganizationID: organizationID, + }, + SecretGeneratorSettingsAttributes: createDefaultSecretGeneratorSettingsAttributes(), + } +} diff --git a/internal/query/projection/settings_relational.go b/internal/query/projection/settings_relational.go index 2b7dffefd..27812de5c 100644 --- a/internal/query/projection/settings_relational.go +++ b/internal/query/projection/settings_relational.go @@ -4,12 +4,14 @@ import ( "context" "database/sql" "net/url" + "time" "github.com/muhlemmer/gu" "github.com/zitadel/zitadel/backend/v3/domain" v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql" "github.com/zitadel/zitadel/backend/v3/storage/database/repository" + legacy_domain "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/repository/instance" @@ -358,6 +360,19 @@ func (s *settingsRelationalProjection) Reducers() []handler.AggregateReducer { Event: instance.PrivacyPolicyChangedEventType, Reduce: s.reducePrivacyPolicyChanged, }, + // Secret Generator + { + Event: instance.SecretGeneratorAddedEventType, + Reduce: s.reduceSecretGeneratorAdded, + }, + { + Event: instance.SecretGeneratorChangedEventType, + Reduce: s.reduceSecretGeneratorChanged, + }, + { + Event: instance.SecretGeneratorRemovedEventType, + Reduce: s.reduceSecretGeneratorRemoved, + }, }, }, } @@ -772,7 +787,7 @@ func (s *settingsRelationalProjection) reduceLabelActivated(event eventstore.Eve }), nil } -func (p *settingsRelationalProjection) reduceLogoAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLogoAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyLogoAddedEvent switch e := event.(type) { @@ -810,7 +825,7 @@ func (p *settingsRelationalProjection) reduceLogoAdded(event eventstore.Event) ( }), nil } -func (p *settingsRelationalProjection) reduceLogoDarkAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLogoDarkAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyLogoDarkAddedEvent switch e := event.(type) { @@ -849,7 +864,7 @@ func (p *settingsRelationalProjection) reduceLogoDarkAdded(event eventstore.Even }), nil } -func (p *settingsRelationalProjection) reduceLogoRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLogoRemoved(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyLogoRemovedEvent switch e := event.(type) { @@ -883,7 +898,7 @@ func (p *settingsRelationalProjection) reduceLogoRemoved(event eventstore.Event) }), nil } -func (p *settingsRelationalProjection) reduceLogoDarkRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLogoDarkRemoved(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyLogoDarkRemovedEvent switch e := event.(type) { @@ -916,7 +931,7 @@ func (p *settingsRelationalProjection) reduceLogoDarkRemoved(event eventstore.Ev }), nil } -func (p *settingsRelationalProjection) reduceIconAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceIconAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyIconAddedEvent switch e := event.(type) { @@ -955,7 +970,7 @@ func (p *settingsRelationalProjection) reduceIconAdded(event eventstore.Event) ( }), nil } -func (p *settingsRelationalProjection) reduceIconDarkAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceIconDarkAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyIconDarkAddedEvent switch e := event.(type) { @@ -994,7 +1009,7 @@ func (p *settingsRelationalProjection) reduceIconDarkAdded(event eventstore.Even }), nil } -func (p *settingsRelationalProjection) reduceIconRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceIconRemoved(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyIconRemovedEvent switch e := event.(type) { @@ -1028,7 +1043,7 @@ func (p *settingsRelationalProjection) reduceIconRemoved(event eventstore.Event) }), nil } -func (p *settingsRelationalProjection) reduceIconDarkRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceIconDarkRemoved(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyIconDarkRemovedEvent switch e := event.(type) { @@ -1062,7 +1077,7 @@ func (p *settingsRelationalProjection) reduceIconDarkRemoved(event eventstore.Ev }), nil } -func (p *settingsRelationalProjection) reduceFontAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceFontAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyFontAddedEvent switch e := event.(type) { @@ -1101,7 +1116,7 @@ func (p *settingsRelationalProjection) reduceFontAdded(event eventstore.Event) ( }), nil } -func (p *settingsRelationalProjection) reduceFontRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceFontRemoved(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LabelPolicyFontRemovedEvent switch e := event.(type) { @@ -1135,7 +1150,7 @@ func (p *settingsRelationalProjection) reduceFontRemoved(event eventstore.Event) }), nil } -func (p *settingsRelationalProjection) reducePasswordComplexityAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reducePasswordComplexityAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.PasswordComplexityPolicyAddedEvent switch e := event.(type) { @@ -1232,7 +1247,7 @@ func (s *settingsRelationalProjection) reducePasswordComplexityRemoved(event eve }), nil } -func (p *settingsRelationalProjection) reducePasswordPolicyAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reducePasswordPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.PasswordAgePolicyAddedEvent switch e := event.(type) { @@ -1268,7 +1283,7 @@ func (p *settingsRelationalProjection) reducePasswordPolicyAdded(event eventstor }), nil } -func (p *settingsRelationalProjection) reducePasswordPolicyChanged(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reducePasswordPolicyChanged(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.PasswordAgePolicyChangedEvent switch e := event.(type) { @@ -1302,7 +1317,7 @@ func (p *settingsRelationalProjection) reducePasswordPolicyChanged(event eventst }), nil } -func (p *settingsRelationalProjection) reducePasswordPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reducePasswordPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.PasswordAgePolicyRemovedEvent) if !ok { return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-EtHWB", "reduce.wrong.event.type %s", org.PasswordAgePolicyRemovedEventType) @@ -1321,7 +1336,7 @@ func (p *settingsRelationalProjection) reducePasswordPolicyRemoved(event eventst }), nil } -func (p *settingsRelationalProjection) reduceOrgLockoutPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceOrgLockoutPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.LockoutPolicyRemovedEvent) if !ok { return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-Bqut9", "reduce.wrong.event.type %s", org.LockoutPolicyRemovedEventType) @@ -1340,7 +1355,7 @@ func (p *settingsRelationalProjection) reduceOrgLockoutPolicyRemoved(event event }), nil } -func (p *settingsRelationalProjection) reduceLockoutPolicyAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLockoutPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LockoutPolicyAddedEvent switch e := event.(type) { @@ -1376,7 +1391,7 @@ func (p *settingsRelationalProjection) reduceLockoutPolicyAdded(event eventstore }), nil } -func (p *settingsRelationalProjection) reduceLockoutPolicyChanged(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceLockoutPolicyChanged(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.LockoutPolicyChangedEvent switch e := event.(type) { @@ -1413,7 +1428,7 @@ func (p *settingsRelationalProjection) reduceLockoutPolicyChanged(event eventsto }), nil } -func (p *settingsRelationalProjection) reduceDomainPolicyAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceDomainPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.DomainPolicyAddedEvent switch e := event.(type) { @@ -1486,7 +1501,7 @@ func (s *settingsRelationalProjection) reduceDomainPolicyChanged(event eventstor }), nil } -func (p *settingsRelationalProjection) reduceOrgDomainPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceOrgDomainPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.DomainPolicyRemovedEvent) if !ok { return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-Bqut9", "reduce.wrong.event.type %s", org.LockoutPolicyRemovedEventType) @@ -1505,7 +1520,7 @@ func (p *settingsRelationalProjection) reduceOrgDomainPolicyRemoved(event events }), nil } -func (p *settingsRelationalProjection) reduceNotificationPolicyAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceNotificationPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.NotificationPolicyAddedEvent switch e := event.(type) { @@ -1575,7 +1590,7 @@ func (s *settingsRelationalProjection) reduceNotificationPolicyChanged(event eve }), nil } -func (p *settingsRelationalProjection) reduceOrgNotificationPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceOrgNotificationPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.NotificationPolicyRemovedEvent) if !ok { return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-Bqut9", "reduce.wrong.event.type %s", org.NotificationPolicyRemovedEventType) @@ -1594,7 +1609,7 @@ func (p *settingsRelationalProjection) reduceOrgNotificationPolicyRemoved(event }), nil } -func (p *settingsRelationalProjection) reducePrivacyPolicyAdded(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reducePrivacyPolicyAdded(event eventstore.Event) (*handler.Statement, error) { var orgId *string var policyEvent policy.PrivacyPolicyAddedEvent switch e := event.(type) { @@ -1680,7 +1695,7 @@ func (s *settingsRelationalProjection) reducePrivacyPolicyChanged(event eventsto }), nil } -func (p *settingsRelationalProjection) reduceOrgPrivacyPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { +func (s *settingsRelationalProjection) reduceOrgPrivacyPolicyRemoved(event eventstore.Event) (*handler.Statement, error) { policyEvent, ok := event.(*org.PrivacyPolicyRemovedEvent) if !ok { return nil, zerrors.ThrowInvalidArgumentf(nil, "PROJE-Bqut9", "reduce.wrong.event.type %s", org.PrivacyPolicyRemovedEventType) @@ -1781,3 +1796,158 @@ func (s *settingsRelationalProjection) reduceOrganizationSettingsRemoved(event e return err }), nil } + +func (s *settingsRelationalProjection) reduceSecretGeneratorAdded(event eventstore.Event) (*handler.Statement, error) { + e, ok := event.(*instance.SecretGeneratorAddedEvent) + if !ok { + return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-yTuWKA", "reduce.wrong.event.type %s", instance.SecretGeneratorAddedEventType) + } + + return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error { + tx, ok := ex.(*sql.Tx) + if !ok { + return zerrors.ThrowInvalidArgumentf(nil, "HANDL-jNhP6P", "reduce.wrong.db.pool %T", ex) + } + + settingsRepo := repository.SecretGeneratorSettingsRepository() + secretGeneratorAttrs, err := setSecretGeneratorSettingsAttrs( + e.GeneratorType, + &e.Length, + &e.IncludeLowerLetters, + &e.IncludeUpperLetters, + &e.IncludeDigits, + &e.IncludeSymbols, + &e.Expiry, + ) + if err != nil { + return err + } + settings := domain.SecretGeneratorSettings{ + Settings: domain.Settings{ + InstanceID: event.Aggregate().InstanceID, + OrganizationID: nil, + CreatedAt: e.Creation, + UpdatedAt: e.Creation, + }, + SecretGeneratorSettingsAttributes: secretGeneratorAttrs, + } + return settingsRepo.Set(ctx, v3_sql.SQLTx(tx), &settings) + }), nil +} + +func (s *settingsRelationalProjection) reduceSecretGeneratorChanged(event eventstore.Event) (*handler.Statement, error) { + e, ok := event.(*instance.SecretGeneratorChangedEvent) + if !ok { + return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-HhaZbQ", "reduce.wrong.event.type %s", instance.SecretGeneratorChangedEventType) + } + + return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error { + tx, ok := ex.(*sql.Tx) + if !ok { + return zerrors.ThrowInvalidArgumentf(nil, "HANDL-3SidEv", "reduce.wrong.db.pool %T", ex) + } + + settingsRepo := repository.SecretGeneratorSettingsRepository() + secretGeneratorAttrs, err := setSecretGeneratorSettingsAttrs( + e.GeneratorType, + e.Length, + e.IncludeLowerLetters, + e.IncludeUpperLetters, + e.IncludeDigits, + e.IncludeSymbols, + e.Expiry, + ) + if err != nil { + return err + } + settings := domain.SecretGeneratorSettings{ + Settings: domain.Settings{ + InstanceID: event.Aggregate().InstanceID, + OrganizationID: nil, + UpdatedAt: e.Creation, + }, + SecretGeneratorSettingsAttributes: secretGeneratorAttrs, + } + return settingsRepo.Set(ctx, v3_sql.SQLTx(tx), &settings) + }), nil +} + +func (s *settingsRelationalProjection) reduceSecretGeneratorRemoved(event eventstore.Event) (*handler.Statement, error) { + e, ok := event.(*instance.SecretGeneratorRemovedEvent) + if !ok { + return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-fmiIf", "reduce.wrong.event.type %s", instance.SecretGeneratorRemovedEventType) + } + + return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error { + tx, ok := ex.(*sql.Tx) + if !ok { + return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xOUC9O", "reduce.wrong.db.pool %T", ex) + } + + settingsRepo := repository.SecretGeneratorSettingsRepository() + _, err := settingsRepo.Delete(ctx, v3_sql.SQLTx(tx), + settingsRepo.UniqueCondition(e.Aggregate().InstanceID, nil, domain.SettingTypeSecretGenerator, domain.SettingStateActive), + ) + return err + }), nil +} + +func setSecretGeneratorSettingsAttrs(generatorType legacy_domain.SecretGeneratorType, length *uint, includeLowerLetters, includeUpperLetters, includeDigits, includeSymbols *bool, expiry *time.Duration) (domain.SecretGeneratorSettingsAttributes, error) { + var secretGeneratorSettingsAttrs domain.SecretGeneratorSettingsAttributes + attrs := domain.SecretGeneratorAttrs{ + Length: length, + IncludeLowerLetters: includeLowerLetters, + IncludeUpperLetters: includeUpperLetters, + IncludeDigits: includeDigits, + IncludeSymbols: includeSymbols, + } + attrsWithExpiry := domain.SecretGeneratorAttrsWithExpiry{ + SecretGeneratorAttrs: attrs, + Expiry: expiry, + } + switch generatorType { + case legacy_domain.SecretGeneratorTypeAppSecret: + secretGeneratorSettingsAttrs.ClientSecret = &domain.ClientSecretAttributes{ + SecretGeneratorAttrs: attrs, + } + case legacy_domain.SecretGeneratorTypeInitCode: + secretGeneratorSettingsAttrs.InitializeUserCode = &domain.InitializeUserCodeAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypeVerifyEmailCode: + secretGeneratorSettingsAttrs.EmailVerificationCode = &domain.EmailVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypeVerifyPhoneCode: + secretGeneratorSettingsAttrs.PhoneVerificationCode = &domain.PhoneVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypePasswordlessInitCode: + secretGeneratorSettingsAttrs.PasswordlessInitCode = &domain.PasswordlessInitCodeAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypePasswordResetCode: + secretGeneratorSettingsAttrs.PasswordVerificationCode = &domain.PasswordVerificationCodeAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypeVerifyDomain: + secretGeneratorSettingsAttrs.DomainVerification = &domain.DomainVerificationAttributes{ + SecretGeneratorAttrs: attrs, + } + case legacy_domain.SecretGeneratorTypeOTPSMS: + secretGeneratorSettingsAttrs.OTPSMS = &domain.OTPSMSAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypeOTPEmail: + secretGeneratorSettingsAttrs.OTPEmail = &domain.OTPEmailAttributes{ + SecretGeneratorAttrsWithExpiry: attrsWithExpiry, + } + case legacy_domain.SecretGeneratorTypeInviteCode, legacy_domain.SecretGeneratorTypeSigningKey: + // do nothing as these secret generators are not persisted in the settings + case legacy_domain.SecretGeneratorTypeUnspecified: + return domain.SecretGeneratorSettingsAttributes{}, zerrors.ThrowInvalidArgumentf(nil, "HANDL-2n3fK", "unspecified secret generator type") + default: + return domain.SecretGeneratorSettingsAttributes{}, zerrors.ThrowInvalidArgumentf(nil, "HANDL-9mG7f", "unknown secret generator type %s", generatorType) + } + return secretGeneratorSettingsAttrs, nil +}