Files
zitadel/backend/v3/storage/database/repository/settings.go
T
b4732579cb fix(RT): correct restricting null columns (#11123)
# Which Problems Are Solved

`IS NULL` and `IS NOT NULL` conditions were incorrectly marked as
restricting columns,
and currently fails unit tests. The restricting columns are mostly used
to ensure single row selection during DELETE and UPDATE . When a `IS NOT
NULL` condition is passed, the filter may (unintentionally) apply to all
rows, while still allowing the query to execute.

Settings and other repositories (still to be done) have unified tables
for instance-level settings and organization-level settings. In those
cases the organization ID may be null or have a value. The unique
condition is a compound of multiple columns, in which case `IS NULL` is
valid as part of the other restricting columns.

# How the Problems Are Solved

In order to prevent unsafe usage of null related filters and not break
settings:

- null conditions are no longer considered restricting columns
- A function to force the restricting column state on a condition is
provided
- The settings unique condition function forces restricting column state
on the returned condition.

# Additional Changes

- add `backend/v3` to the NX build.

# Additional Context

- [pipeline
failures](https://github.com/zitadel/zitadel/actions/runs/19852295780/job/56881654340?pr=11115#step:13:3197)

---------

Co-authored-by: Elio Bischof <[email protected]>
2025-12-03 16:15:49 +00:00

1406 lines
48 KiB
Go

package repository
import (
"context"
"encoding/json"
"net/url"
"time"
"github.com/zitadel/zitadel/backend/v3/domain"
"github.com/zitadel/zitadel/backend/v3/storage/database"
db_json "github.com/zitadel/zitadel/backend/v3/storage/database/json"
)
type settings struct{}
func (s settings) qualifiedTableName() string {
return "zitadel." + s.unqualifiedTableName()
}
func (settings) unqualifiedTableName() string {
return "settings"
}
// -------------------------------------------------------------
// columns
// -------------------------------------------------------------
// PrimaryKeyColumns implements [domain.Repository].
func (s settings) PrimaryKeyColumns() []database.Column {
return []database.Column{
s.InstanceIDColumn(),
s.IDColumn(),
}
}
func (s settings) UniqueColumns() []database.Column {
return []database.Column{
s.InstanceIDColumn(),
s.OrganizationIDColumn(),
s.TypeColumn(),
s.StateColumn(),
}
}
func (s settings) IDColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "id")
}
func (s settings) InstanceIDColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "instance_id")
}
func (s settings) OrganizationIDColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "organization_id")
}
func (s settings) TypeColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "type")
}
func (s settings) StateColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "state")
}
func (s settings) SettingsColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "settings")
}
func (s settings) CreatedAtColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "created_at")
}
func (s settings) UpdatedAtColumn() database.Column {
return database.NewColumn(s.unqualifiedTableName(), "updated_at")
}
// -------------------------------------------------------------
// conditions
// -------------------------------------------------------------
func (s settings) PrimaryKeyCondition(instanceID, id string) database.Condition {
return database.And(
s.InstanceIDCondition(instanceID),
s.IDCondition(id),
)
}
func (s settings) UniqueCondition(instanceID string, orgID *string, typ domain.SettingType, state domain.SettingState) database.Condition {
return database.ForceRestrictingColumn(
database.And(
s.InstanceIDCondition(instanceID),
s.OrganizationIDCondition(orgID),
s.TypeCondition(typ),
s.StateCondition(state),
),
true,
)
}
func (s settings) InstanceIDCondition(id string) database.Condition {
return database.NewTextCondition(s.InstanceIDColumn(), database.TextOperationEqual, id)
}
func (s settings) OrganizationIDCondition(id *string) database.Condition {
if id == nil {
return database.IsNull(s.OrganizationIDColumn())
}
return database.NewTextCondition(s.OrganizationIDColumn(), database.TextOperationEqual, *id)
}
func (s settings) IDCondition(id string) database.Condition {
return database.NewTextCondition(s.IDColumn(), database.TextOperationEqual, id)
}
func (s settings) TypeCondition(typ domain.SettingType) database.Condition {
return database.NewTextCondition(s.TypeColumn(), database.TextOperationEqual, typ.String())
}
func (s settings) StateCondition(typ domain.SettingState) database.Condition {
return database.NewTextCondition(s.StateColumn(), database.TextOperationEqual, typ.String())
}
// -------------------------------------------------------------
// changes
// -------------------------------------------------------------
// func (s settings) SetSettings(settings string) database.Change {
// return database.NewChange(s.SettingsColumn(), settings)
// }
func (s settings) SetUpdatedAt(updatedAt *time.Time) database.Change {
return database.NewChangePtr(s.UpdatedAtColumn(), updatedAt)
}
func (s settings) get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.Settings, error) {
builder, err := s.prepareQuery(opts)
if err != nil {
return nil, err
}
return getOne[domain.Settings](ctx, client, builder)
}
func (s settings) list(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.Settings, error) {
builder, err := s.prepareQuery(opts)
if err != nil {
return nil, err
}
return getMany[domain.Settings](ctx, client, builder)
}
func (s settings) set(ctx context.Context, client database.QueryExecutor, settings *domain.Settings, changes ...database.Change) error {
var (
id, createdAt, updatedAt any = database.DefaultInstruction, database.DefaultInstruction, database.DefaultInstruction
)
if settings.ID != "" {
id = settings.ID
}
if !settings.CreatedAt.IsZero() {
createdAt = settings.CreatedAt
}
if !settings.UpdatedAt.IsZero() {
updatedAt = settings.UpdatedAt
changes = append(changes, s.SetUpdatedAt(&settings.UpdatedAt))
}
builder := database.NewStatementBuilder(`INSERT INTO ` + s.qualifiedTableName())
builder.WriteString(` (id, instance_id, organization_id, type, state, settings, created_at, updated_at) VALUES (`)
builder.WriteArgs(
id,
settings.InstanceID,
settings.OrganizationID,
settings.Type.String(),
settings.State.String(),
settings.Settings,
createdAt,
updatedAt,
)
builder.WriteString(`) ON CONFLICT (instance_id, organization_id, type, state) DO UPDATE SET `)
err := database.Changes(changes).Write(builder)
if err != nil {
return err
}
builder.WriteString(` RETURNING id, created_at, updated_at`)
return client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(&settings.ID, &settings.CreatedAt, &settings.UpdatedAt)
}
func (s settings) Delete(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) {
if err := checkRestrictingColumns(condition, s.UniqueColumns()...); err != nil {
return 0, err
}
var builder database.StatementBuilder
builder.WriteString(`DELETE FROM ` + s.qualifiedTableName())
writeCondition(&builder, condition)
return client.Exec(ctx, builder.String(), builder.Args()...)
}
// -------------------------------------------------------------
// login
// -------------------------------------------------------------
type loginSettings struct {
settings
}
func (l loginSettings) SetSettingFields(value domain.LoginSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.AllowUserNamePassword != nil {
changes = append(changes, l.SetAllowUserNamePassword(*value.AllowUserNamePassword))
}
if value.AllowRegister != nil {
changes = append(changes, l.SetAllowRegister(*value.AllowRegister))
}
if value.AllowExternalIDP != nil {
changes = append(changes, l.SetAllowExternalIDP(*value.AllowExternalIDP))
}
if value.ForceMFA != nil {
changes = append(changes, l.SetForceMFA(*value.ForceMFA))
}
if value.ForceMFALocalOnly != nil {
changes = append(changes, l.SetForceMFALocalOnly(*value.ForceMFALocalOnly))
}
if value.HidePasswordReset != nil {
changes = append(changes, l.SetHidePasswordReset(*value.HidePasswordReset))
}
if value.IgnoreUnknownUsernames != nil {
changes = append(changes, l.SetIgnoreUnknownUsernames(*value.IgnoreUnknownUsernames))
}
if value.AllowDomainDiscovery != nil {
changes = append(changes, l.SetAllowDomainDiscovery(*value.AllowDomainDiscovery))
}
if value.DisableLoginWithEmail != nil {
changes = append(changes, l.SetDisableLoginWithEmail(*value.DisableLoginWithEmail))
}
if value.DisableLoginWithPhone != nil {
changes = append(changes, l.SetDisableLoginWithPhone(*value.DisableLoginWithPhone))
}
if value.PasswordlessType != nil {
changes = append(changes, l.SetPasswordlessType(*value.PasswordlessType))
}
if value.DefaultRedirectURI != nil {
changes = append(changes, l.SetDefaultRedirectURI(*value.DefaultRedirectURI))
}
if value.PasswordCheckLifetime != nil {
changes = append(changes, l.SetPasswordCheckLifetime(*value.PasswordCheckLifetime))
}
if value.ExternalLoginCheckLifetime != nil {
changes = append(changes, l.SetExternalLoginCheckLifetime(*value.ExternalLoginCheckLifetime))
}
if value.MFAInitSkipLifetime != nil {
changes = append(changes, l.SetMFAInitSkipLifetime(*value.MFAInitSkipLifetime))
}
if value.SecondFactorCheckLifetime != nil {
changes = append(changes, l.SetSecondFactorCheckLifetime(*value.SecondFactorCheckLifetime))
}
if value.MultiFactorCheckLifetime != nil {
changes = append(changes, l.SetMultiFactorCheckLifetime(*value.MultiFactorCheckLifetime))
}
if value.DisableLoginWithEmail != nil {
changes = append(changes, l.SetDisableLoginWithEmail(*value.DisableLoginWithEmail))
}
if value.MFAType != nil {
changes = append(changes, l.SetMFAType(value.MFAType))
}
if value.SecondFactorTypes != nil {
changes = append(changes, l.SetSecondFactorTypes(value.SecondFactorTypes))
}
return db_json.NewJsonChanges(l.SettingsColumn(), changes...)
}
func (loginSettings) SetAllowUserNamePassword(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"allowUsernamePassword"}, value)
}
func (loginSettings) SetAllowRegister(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"allowRegister"}, value)
}
func (loginSettings) SetAllowExternalIDP(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"allowExternalIdp"}, value)
}
func (loginSettings) SetForceMFA(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"forceMfa"}, value)
}
func (loginSettings) SetForceMFALocalOnly(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"forceMfaLocalOnly"}, value)
}
func (loginSettings) SetHidePasswordReset(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hidePasswordReset"}, value)
}
func (loginSettings) SetIgnoreUnknownUsernames(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"ignoreUnknownUsernames"}, value)
}
func (loginSettings) SetAllowDomainDiscovery(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"allowDomainDiscovery"}, value)
}
func (loginSettings) SetDisableLoginWithEmail(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"disableLoginWithEmail"}, value)
}
func (loginSettings) SetDisableLoginWithPhone(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"disableLoginWithPhone"}, value)
}
func (loginSettings) SetPasswordlessType(value domain.PasswordlessType) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"passwordlessType"}, value)
}
func (loginSettings) SetDefaultRedirectURI(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"defaultRedirectUri"}, value)
}
func (loginSettings) SetPasswordCheckLifetime(value time.Duration) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"passwordCheckLifetime"}, value)
}
func (loginSettings) SetExternalLoginCheckLifetime(value time.Duration) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"externalLoginCheckLifetime"}, value)
}
func (loginSettings) SetMFAInitSkipLifetime(value time.Duration) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"mfaInitSkipLifetime"}, value)
}
func (loginSettings) SetSecondFactorCheckLifetime(value time.Duration) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"secondFactorCheckLifetime"}, value)
}
func (loginSettings) SetMultiFactorCheckLifetime(value time.Duration) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"multiFactorCheckLifetime"}, value)
}
func (loginSettings) SetMFAType(values []domain.MultiFactorType) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"mfaType"}, values)
}
func (l loginSettings) AddMFAType(value domain.MultiFactorType) database.Change {
return db_json.NewJsonChanges(l.SettingsColumn(),
db_json.NewArrayChange([]string{"mfaType"}, value, false),
)
}
func (l loginSettings) RemoveMFAType(value domain.MultiFactorType) database.Change {
return db_json.NewJsonChanges(l.SettingsColumn(),
db_json.NewArrayChange([]string{"mfaType"}, value, true),
)
}
func (loginSettings) SetSecondFactorTypes(values []domain.SecondFactorType) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"secondFactors"}, values)
}
func (l loginSettings) AddSecondFactorTypes(value domain.SecondFactorType) database.Change {
return db_json.NewJsonChanges(l.SettingsColumn(),
db_json.NewArrayChange([]string{"secondFactors"}, value, false),
)
}
func (l loginSettings) RemoveSecondFactorTypes(value domain.SecondFactorType) database.Change {
return db_json.NewJsonChanges(l.SettingsColumn(),
db_json.NewArrayChange([]string{"secondFactors"}, value, true),
)
}
func LoginSettingsRepository() domain.LoginSettingsRepository {
return &loginSettings{
settings{},
}
}
var _ domain.LoginSettingsRepository = (*loginSettings)(nil)
func (s loginSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LoginSettings) error {
settings.Type = domain.SettingTypeLogin
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.LoginSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.LoginSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s loginSettings) SetColumns(ctx context.Context, client database.QueryExecutor, settings *domain.Settings, changes ...database.Change) error {
settings.Type = domain.SettingTypeLogin
settings.State = domain.SettingStateActive
return s.set(ctx, client, settings, changes...)
}
func (s loginSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.LoginSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.LoginSettings, len(settings))
for i := range settings {
list[i] = &domain.LoginSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].LoginSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s loginSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.LoginSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
loginSettings := &domain.LoginSettings{Settings: *settings}
if err = json.Unmarshal(loginSettings.Settings.Settings, &loginSettings.LoginSettingsAttributes); err != nil {
return nil, err
}
loginSettings.Settings.Settings = nil
return loginSettings, nil
}
// -------------------------------------------------------------
// branding
// -------------------------------------------------------------
type brandingSettings struct {
settings
}
func (b brandingSettings) SetSettingFields(value domain.BrandingSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.PrimaryColorLight != nil {
changes = append(changes, b.SetPrimaryColorLight(*value.PrimaryColorLight))
}
if value.BackgroundColorLight != nil {
changes = append(changes, b.SetBackgroundColorLight(*value.BackgroundColorLight))
}
if value.WarnColorLight != nil {
changes = append(changes, b.SetWarnColorLight(*value.WarnColorLight))
}
if value.FontColorLight != nil {
changes = append(changes, b.SetFontColorLight(*value.FontColorLight))
}
if value.PrimaryColorDark != nil {
changes = append(changes, b.SetPrimaryColorDark(*value.PrimaryColorDark))
}
if value.BackgroundColorDark != nil {
changes = append(changes, b.SetBackgroundColorDark(*value.BackgroundColorDark))
}
if value.WarnColorDark != nil {
changes = append(changes, b.SetWarnColorDark(*value.WarnColorDark))
}
if value.FontColorDark != nil {
changes = append(changes, b.SetFontColorDark(*value.FontColorDark))
}
if value.HideLoginNameSuffix != nil {
changes = append(changes, b.SetHideLoginNameSuffix(*value.HideLoginNameSuffix))
}
if value.ErrorMsgPopup != nil {
changes = append(changes, b.SetErrorMsgPopup(*value.ErrorMsgPopup))
}
if value.DisableWatermark != nil {
changes = append(changes, b.SetDisableWatermark(*value.DisableWatermark))
}
if value.ThemeMode != nil {
changes = append(changes, b.SetThemeMode(*value.ThemeMode))
}
if value.LogoURLLight != nil {
changes = append(changes, b.SetLogoURLLight(*value.LogoURLLight))
}
if value.LogoURLDark != nil {
changes = append(changes, b.SetLogoURLDark(*value.LogoURLDark))
}
if value.IconURLLight != nil {
changes = append(changes, b.SetIconURLLight(*value.IconURLLight))
}
if value.IconURLDark != nil {
changes = append(changes, b.SetIconURLDark(*value.IconURLDark))
}
if value.FontURL != nil {
changes = append(changes, b.SetFontURL(*value.FontURL))
}
return db_json.NewJsonChanges(b.SettingsColumn(), changes...)
}
func (brandingSettings) SetPrimaryColorLight(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"primaryColorLight"}, value)
}
func (brandingSettings) SetBackgroundColorLight(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"backgroundColorLight"}, value)
}
func (brandingSettings) SetWarnColorLight(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"warnColorLight"}, value)
}
func (brandingSettings) SetFontColorLight(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"fontColorLight"}, value)
}
func (brandingSettings) SetPrimaryColorDark(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"primaryColorDark"}, value)
}
func (brandingSettings) SetBackgroundColorDark(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"backgroundColorDark"}, value)
}
func (brandingSettings) SetWarnColorDark(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"warnColorDark"}, value)
}
func (brandingSettings) SetFontColorDark(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"fontColorDark"}, value)
}
func (brandingSettings) SetHideLoginNameSuffix(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hideLoginNameSuffix"}, value)
}
func (brandingSettings) SetErrorMsgPopup(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"errorMsgPopup"}, value)
}
func (brandingSettings) SetDisableWatermark(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"disableMsgPopup"}, value)
}
func (brandingSettings) SetThemeMode(value domain.BrandingPolicyThemeMode) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"themeMode"}, value)
}
func (brandingSettings) SetLogoURLLight(value url.URL) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"logoURLLight"}, value)
}
func (brandingSettings) SetLogoURLDark(value url.URL) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"logoUrlDark"}, value)
}
func (brandingSettings) SetIconURLLight(value url.URL) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"iconUrlLight"}, value)
}
func (brandingSettings) SetIconURLDark(value url.URL) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"iconUrlDark"}, value)
}
func (brandingSettings) SetFontURL(value url.URL) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"fontUrl"}, value)
}
func BrandingSettingsRepository() domain.BrandingSettingsRepository {
return &brandingSettings{
settings{},
}
}
var _ domain.BrandingSettingsRepository = (*brandingSettings)(nil)
func (s brandingSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.BrandingSettings) (err error) {
settings.Type = domain.SettingTypeBranding
settings.State = domain.SettingStatePreview
settingsJSON, err := json.Marshal(settings.BrandingSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.BrandingSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s brandingSettings) SetColumns(ctx context.Context, client database.QueryExecutor, settings *domain.Settings, changes ...database.Change) error {
settings.Type = domain.SettingTypeBranding
settings.State = domain.SettingStatePreview
return s.set(ctx, client, settings, changes...)
}
func (s brandingSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.BrandingSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.BrandingSettings, len(settings))
for i := range settings {
list[i] = &domain.BrandingSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].BrandingSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s brandingSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.BrandingSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
brandingSettings := &domain.BrandingSettings{Settings: *settings}
if err = json.Unmarshal(brandingSettings.Settings.Settings, &brandingSettings.BrandingSettingsAttributes); err != nil {
return nil, err
}
brandingSettings.Settings.Settings = nil
return brandingSettings, nil
}
const queryActivateBrandingSettingsStmt = `SELECT instance_id, organization_id, id, type, created_at, updated_at, settings FROM `
func (s brandingSettings) Activate(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) {
return s.activateAt(ctx, client, condition, time.Now())
}
func (s brandingSettings) ActivateAt(ctx context.Context, client database.QueryExecutor, condition database.Condition, updatedAt time.Time) (int64, error) {
return s.activateAt(ctx, client, condition, updatedAt)
}
func (s brandingSettings) activateAt(ctx context.Context, client database.QueryExecutor, condition database.Condition, updatedAt time.Time) (int64, error) {
// if you want to update the roles you have to have a unique condition, otherwise multiple branding settings get activated
if err := checkRestrictingColumns(condition, s.UniqueColumns()...); err != nil {
return 0, err
}
// the statement begins with getting settings in preview state
builder := database.NewStatementBuilder("WITH preview AS (")
builder.WriteString(queryActivateBrandingSettingsStmt + s.qualifiedTableName())
writeCondition(builder, condition)
builder.WriteString(" ) ")
// insert or update settings as active
builder.WriteString(`INSERT INTO ` + s.qualifiedTableName())
builder.WriteString(` (instance_id, organization_id, id, type, state, created_at, updated_at, settings)`)
builder.WriteString(` SELECT preview.instance_id, preview.organization_id, preview.id, preview.type, `)
builder.WriteArg(domain.SettingStateActive)
builder.WriteString(`, preview.created_at, `)
builder.WriteArg(updatedAt)
builder.WriteString(`, preview.settings FROM preview`)
builder.WriteString(` ON CONFLICT (instance_id, organization_id, type, state) DO UPDATE SET settings = EXCLUDED.settings, updated_at = `)
builder.WriteArg(updatedAt)
return client.Exec(ctx, builder.String(), builder.Args()...)
}
// -------------------------------------------------------------
// password complexity
// -------------------------------------------------------------
type passwordComplexitySettings struct {
settings
}
func (s passwordComplexitySettings) SetSettingFields(value domain.PasswordComplexitySettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.MinLength != nil {
changes = append(changes, s.SetMinLength(*value.MinLength))
}
if value.HasLowercase != nil {
changes = append(changes, s.SetHasLowercase(*value.HasLowercase))
}
if value.HasUppercase != nil {
changes = append(changes, s.SetHasUppercase(*value.HasUppercase))
}
if value.HasNumber != nil {
changes = append(changes, s.SetHasNumber(*value.HasNumber))
}
if value.HasSymbol != nil {
changes = append(changes, s.SetHasSymbol(*value.HasSymbol))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (passwordComplexitySettings) SetMinLength(value uint64) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"minLength"}, value)
}
func (passwordComplexitySettings) SetHasLowercase(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hasLowercase"}, value)
}
func (passwordComplexitySettings) SetHasUppercase(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hasUppercase"}, value)
}
func (passwordComplexitySettings) SetHasNumber(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hasNumber"}, value)
}
func (passwordComplexitySettings) SetHasSymbol(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"hasSymbol"}, value)
}
func PasswordComplexitySettingsRepository() domain.PasswordComplexitySettingsRepository {
return &passwordComplexitySettings{
settings{},
}
}
var _ domain.PasswordComplexitySettingsRepository = (*passwordComplexitySettings)(nil)
func (s passwordComplexitySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.PasswordComplexitySettings) (err error) {
settings.Type = domain.SettingTypePasswordComplexity
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.PasswordComplexitySettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.PasswordComplexitySettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s passwordComplexitySettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.PasswordComplexitySettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.PasswordComplexitySettings, len(settings))
for i := range settings {
list[i] = &domain.PasswordComplexitySettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].PasswordComplexitySettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s passwordComplexitySettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.PasswordComplexitySettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.PasswordComplexitySettings{Settings: *settings}
if err := json.Unmarshal(item.Settings.Settings, &item.PasswordComplexitySettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// password expiry
// -------------------------------------------------------------
type passwordExpirySettings struct {
settings
}
func (s passwordExpirySettings) SetSettingFields(value domain.PasswordExpirySettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.ExpireWarnDays != nil {
changes = append(changes, s.SetExpireWarnDays(*value.ExpireWarnDays))
}
if value.MaxAgeDays != nil {
changes = append(changes, s.SetMaxAgeDays(*value.MaxAgeDays))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (passwordExpirySettings) SetExpireWarnDays(value uint64) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"expireWarnDays"}, value)
}
func (passwordExpirySettings) SetMaxAgeDays(value uint64) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"maxAgeDays"}, value)
}
var _ domain.PasswordExpirySettingsRepository = (*passwordExpirySettings)(nil)
func PasswordExpirySettingsRepository() domain.PasswordExpirySettingsRepository {
return &passwordExpirySettings{
settings{},
}
}
func (s passwordExpirySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.PasswordExpirySettings) (err error) {
settings.Type = domain.SettingTypePasswordExpiry
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.PasswordExpirySettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.PasswordExpirySettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s passwordExpirySettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.PasswordExpirySettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.PasswordExpirySettings, len(settings))
for i := range settings {
list[i] = &domain.PasswordExpirySettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].PasswordExpirySettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s passwordExpirySettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.PasswordExpirySettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.PasswordExpirySettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.PasswordExpirySettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// lockout
// -------------------------------------------------------------
type lockoutSettings struct {
settings
}
func (s lockoutSettings) SetSettingFields(value domain.LockoutSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.MaxPasswordAttempts != nil {
changes = append(changes, s.SetMaxPasswordAttempts(*value.MaxPasswordAttempts))
}
if value.MaxOTPAttempts != nil {
changes = append(changes, s.SetMaxOTPAttempts(*value.MaxOTPAttempts))
}
if value.ShowLockOutFailures != nil {
changes = append(changes, s.SetShowLockOutFailures(*value.ShowLockOutFailures))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (lockoutSettings) SetMaxPasswordAttempts(value uint64) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"maxPasswordAttempts"}, value)
}
func (lockoutSettings) SetMaxOTPAttempts(value uint64) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"maxOtpAttempts"}, value)
}
func (lockoutSettings) SetShowLockOutFailures(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"showLockOutFailures"}, value)
}
func LockoutSettingsRepository() domain.LockoutSettingsRepository {
return &lockoutSettings{
settings{},
}
}
var _ domain.LockoutSettingsRepository = (*lockoutSettings)(nil)
func (s lockoutSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LockoutSettings) error {
settings.Type = domain.SettingTypeLockout
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.LockoutSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.LockoutSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s lockoutSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.LockoutSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.LockoutSettings, len(settings))
for i := range settings {
list[i] = &domain.LockoutSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].LockoutSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s lockoutSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.LockoutSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.LockoutSettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.LockoutSettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// security
// -------------------------------------------------------------
type securitySettings struct {
settings
}
func (s securitySettings) SetSettingFields(value domain.SecuritySettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.EnableIframeEmbedding != nil {
changes = append(changes, s.SetEnableIframeEmbedding(*value.EnableIframeEmbedding))
}
if value.AllowedOrigins != nil {
changes = append(changes, s.SetAllowedOrigins(value.AllowedOrigins))
}
if value.EnableImpersonation != nil {
changes = append(changes, s.SetEnableImpersonation(*value.EnableImpersonation))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (securitySettings) SetEnableIframeEmbedding(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"enableIframeEmbedding"}, value)
}
func (securitySettings) SetAllowedOrigins(value []string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"allowedOrigins"}, value)
}
func (securitySettings) SetEnableImpersonation(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"enableImpersonation"}, value)
}
func SecuritySettingsRepository() domain.SecuritySettingsRepository {
return &securitySettings{
settings{},
}
}
var _ domain.SecuritySettingsRepository = (*securitySettings)(nil)
func (s securitySettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.SecuritySettings) (err error) {
settings.Type = domain.SettingTypeSecurity
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.SecuritySettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.SecuritySettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s securitySettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.SecuritySettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.SecuritySettings, len(settings))
for i := range settings {
list[i] = &domain.SecuritySettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].SecuritySettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s securitySettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.SecuritySettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.SecuritySettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.SecuritySettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// domain
// -------------------------------------------------------------
type domainSettings struct {
settings
}
func (s domainSettings) SetSettingFields(value domain.DomainSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.LoginNameIncludesDomain != nil {
changes = append(changes, s.SetLoginNameIncludesDomain(*value.LoginNameIncludesDomain))
}
if value.RequireOrgDomainVerification != nil {
changes = append(changes, s.SetRequireOrgDomainVerification(*value.RequireOrgDomainVerification))
}
if value.SMTPSenderAddressMatchesInstanceDomain != nil {
changes = append(changes, s.SetSMTPSenderAddressMatchesInstanceDomain(*value.SMTPSenderAddressMatchesInstanceDomain))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (domainSettings) SetLoginNameIncludesDomain(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"loginNameIncludesDomain"}, value)
}
func (domainSettings) SetRequireOrgDomainVerification(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"requireOrgDomainVerification"}, value)
}
func (domainSettings) SetSMTPSenderAddressMatchesInstanceDomain(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"smtpSenderAddressMatchesInstanceDomain"}, value)
}
func DomainSettingsRepository() domain.DomainSettingsRepository {
return &domainSettings{
settings{},
}
}
var _ domain.DomainSettingsRepository = (*domainSettings)(nil)
func (s domainSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.DomainSettings) (err error) {
settings.Type = domain.SettingTypeDomain
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.DomainSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.DomainSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s domainSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.DomainSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.DomainSettings, len(settings))
for i := range settings {
list[i] = &domain.DomainSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].DomainSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s domainSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.DomainSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.DomainSettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.DomainSettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// organization
// -------------------------------------------------------------
type organizationSettings struct {
settings
}
func (s organizationSettings) SetSettingFields(value domain.OrganizationSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.OrganizationScopedUsernames != nil {
changes = append(changes, s.SetOrganizationScopedUsernames(*value.OrganizationScopedUsernames))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (l organizationSettings) SetOrganizationScopedUsernames(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"organizationScopedUsernames"}, value)
}
func OrganizationSettingsRepository() domain.OrganizationSettingsRepository {
return &organizationSettings{
settings{},
}
}
var _ domain.OrganizationSettingsRepository = (*organizationSettings)(nil)
func (s organizationSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.OrganizationSettings) (err error) {
settings.Type = domain.SettingTypeOrganization
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.OrganizationSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.OrganizationSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s organizationSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.OrganizationSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.OrganizationSettings, len(settings))
for i := range settings {
list[i] = &domain.OrganizationSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].OrganizationSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s organizationSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.OrganizationSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.OrganizationSettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.OrganizationSettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// notification
// -------------------------------------------------------------
type notificationSettings struct {
settings
}
func (s notificationSettings) SetSettingFields(value domain.NotificationSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.PasswordChange != nil {
changes = append(changes, s.SetPasswordChange(*value.PasswordChange))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (s notificationSettings) SetPasswordChange(value bool) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"passwordChange"}, value)
}
func NotificationSettingsRepository() domain.NotificationSettingsRepository {
return &notificationSettings{
settings{},
}
}
var _ domain.NotificationSettingsRepository = (*notificationSettings)(nil)
func (s notificationSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.NotificationSettings) (err error) {
settings.Type = domain.SettingTypeNotification
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.NotificationSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.NotificationSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s notificationSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.NotificationSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.NotificationSettings, len(settings))
for i := range settings {
list[i] = &domain.NotificationSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].NotificationSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s notificationSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.NotificationSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.NotificationSettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.NotificationSettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// legal and support
// -------------------------------------------------------------
type legalAndSupportSettings struct {
settings
}
func (s legalAndSupportSettings) SetSettingFields(value domain.LegalAndSupportSettingsAttributes) database.Change {
changes := make([]db_json.JsonUpdate, 0)
if value.TOSLink != nil {
changes = append(changes, s.SetTOSLink(*value.TOSLink))
}
if value.PrivacyPolicyLink != nil {
changes = append(changes, s.SetPrivacyPolicyLink(*value.PrivacyPolicyLink))
}
if value.HelpLink != nil {
changes = append(changes, s.SetHelpLink(*value.HelpLink))
}
if value.SupportEmail != nil {
changes = append(changes, s.SetSupportEmail(*value.SupportEmail))
}
if value.DocsLink != nil {
changes = append(changes, s.SetDocsLink(*value.DocsLink))
}
if value.CustomLink != nil {
changes = append(changes, s.SetCustomLink(*value.CustomLink))
}
if value.CustomLinkText != nil {
changes = append(changes, s.SetCustomLinkText(*value.CustomLinkText))
}
return db_json.NewJsonChanges(s.SettingsColumn(), changes...)
}
func (s legalAndSupportSettings) SetTOSLink(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"tosLink"}, value)
}
func (s legalAndSupportSettings) SetPrivacyPolicyLink(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"privacyPolicyLink"}, value)
}
func (s legalAndSupportSettings) SetHelpLink(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"helpLink"}, value)
}
func (s legalAndSupportSettings) SetSupportEmail(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"supportEmail"}, value)
}
func (s legalAndSupportSettings) SetDocsLink(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"docsLink"}, value)
}
func (s legalAndSupportSettings) SetCustomLink(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"customLink"}, value)
}
func (s legalAndSupportSettings) SetCustomLinkText(value string) db_json.JsonUpdate {
return db_json.NewFieldChange([]string{"customLinkText"}, value)
}
func LegalAndSupportSettingsRepository() domain.LegalAndSupportSettingsRepository {
return &legalAndSupportSettings{
settings{},
}
}
var _ domain.LegalAndSupportSettingsRepository = (*legalAndSupportSettings)(nil)
func (s legalAndSupportSettings) Set(ctx context.Context, client database.QueryExecutor, settings *domain.LegalAndSupportSettings) (err error) {
settings.Type = domain.SettingTypeLegalAndSupport
settings.State = domain.SettingStateActive
settingsJSON, err := json.Marshal(settings.LegalAndSupportSettingsAttributes)
if err != nil {
return err
}
settings.Settings.Settings = settingsJSON
if err := s.set(ctx, client, &settings.Settings, s.SetSettingFields(settings.LegalAndSupportSettingsAttributes)); err != nil {
return err
}
settings.Settings.Settings = nil
return nil
}
func (s legalAndSupportSettings) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.LegalAndSupportSettings, error) {
settings, err := s.list(ctx, client, opts...)
if err != nil {
return nil, err
}
list := make([]*domain.LegalAndSupportSettings, len(settings))
for i := range settings {
list[i] = &domain.LegalAndSupportSettings{Settings: *settings[i]}
if err := json.Unmarshal(list[i].Settings.Settings, &list[i].LegalAndSupportSettingsAttributes); err != nil {
return nil, err
}
list[i].Settings.Settings = nil
}
return list, nil
}
func (s legalAndSupportSettings) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.LegalAndSupportSettings, error) {
settings, err := s.get(ctx, client, opts...)
if err != nil {
return nil, err
}
item := &domain.LegalAndSupportSettings{Settings: *settings}
if err = json.Unmarshal(item.Settings.Settings, &item.LegalAndSupportSettingsAttributes); err != nil {
return nil, err
}
item.Settings.Settings = nil
return item, nil
}
// -------------------------------------------------------------
// helpers
// -------------------------------------------------------------
const querySettingsStmt = `SELECT
settings.instance_id,
settings.organization_id,
settings.id,
settings.type,
settings.state,
settings.settings,
settings.created_at,
settings.updated_at
FROM `
func (s settings) prepareQuery(opts []database.QueryOption) (*database.StatementBuilder, error) {
options := new(database.QueryOpts)
for _, opt := range opts {
opt(options)
}
if err := checkRestrictingColumns(options.Condition, s.InstanceIDColumn()); err != nil {
return nil, err
}
builder := database.NewStatementBuilder(querySettingsStmt + s.qualifiedTableName())
options.Write(builder)
return builder, nil
}