mirror of
https://github.com/zitadel/zitadel.git
synced 2025-04-07 17:24:32 +00:00
new pkg structure (#1150)
* fix: split command query side * fix: split command query side * fix: members in correct pkg structure * fix: label policy in correct pkg structure * fix: structure * fix: structure of login policy * fix: identityprovider structure * fix: org iam policy structure * fix: password age policy structure * fix: password complexity policy structure * fix: password lockout policy structure * fix: idp structure * fix: user events structure * fix: user write model * fix: profile email changed command * fix: address changed command * fix: user states * fix: user * fix: org structure and add human * begin iam setup command side * setup * step2 * step2 * fix: add user * step2 * isvalid * fix: folder structure v2 business Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
This commit is contained in:
parent
762941f0ea
commit
21ffe1b0cb
@ -161,8 +161,8 @@ func startSetup(configPaths []string, localDevMode bool) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
setup, err := setup.StartSetup(conf.Eventstore, conf.SystemDefaults)
|
||||
setup, err := setup.StartSetupV2(conf.Eventstore, conf.SystemDefaults)
|
||||
logging.Log("SERVE-fD252").OnError(err).Panic("failed to start setup")
|
||||
err = setup.Execute(ctx, conf.SetUp)
|
||||
err = setup.ExecuteV2(ctx, conf.SetUp)
|
||||
logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup")
|
||||
}
|
||||
|
@ -26,53 +26,53 @@ SetUp:
|
||||
Step1:
|
||||
GlobalOrg: 'Global'
|
||||
IAMProject: 'Zitadel'
|
||||
DefaultLoginPolicy:
|
||||
AllowUsernamePassword: true
|
||||
AllowRegister: true
|
||||
AllowExternalIdp: true
|
||||
Orgs:
|
||||
- Name: 'Global'
|
||||
Domain: 'global.caos.ch'
|
||||
Default: true
|
||||
OrgIamPolicy: true
|
||||
Users:
|
||||
- FirstName: 'Global Org'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-global-org-admin@caos.ch'
|
||||
Email: 'zitadel-global-org-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-global-org-admin@caos.ch'
|
||||
- Name: 'CAOS AG'
|
||||
Domain: 'caos.ch'
|
||||
Users:
|
||||
- FirstName: 'Zitadel'
|
||||
LastName: 'Administrator'
|
||||
UserName: 'zitadel-admin'
|
||||
Email: 'zitadel-admin@caos.ch'
|
||||
Password: 'Password1!'
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
||||
Projects:
|
||||
- Name: 'Zitadel'
|
||||
OIDCApps:
|
||||
- Name: 'Management-API'
|
||||
- Name: 'Auth-API'
|
||||
- Name: 'Admin-API'
|
||||
- Name: 'Zitadel Console'
|
||||
RedirectUris:
|
||||
- '$ZITADEL_CONSOLE/auth/callback'
|
||||
PostLogoutRedirectUris:
|
||||
- '$ZITADEL_CONSOLE/signedout'
|
||||
ResponseTypes:
|
||||
- $ZITADEL_CONSOLE_RESPONSE_TYPE
|
||||
GrantTypes:
|
||||
- $ZITADEL_CONSOLE_GRANT_TYPE
|
||||
ApplicationType: 'USER_AGENT'
|
||||
AuthMethodType: 'NONE'
|
||||
DevMode: $ZITADEL_CONSOLE_DEV_MODE
|
||||
Owners:
|
||||
- 'zitadel-admin@caos.ch'
|
||||
# DefaultLoginPolicy:
|
||||
# AllowUsernamePassword: true
|
||||
# AllowRegister: true
|
||||
# AllowExternalIdp: true
|
||||
# Orgs:
|
||||
# - Name: 'Global'
|
||||
# Domain: 'global.caos.ch'
|
||||
# Default: true
|
||||
# OrgIamPolicy: true
|
||||
# Users:
|
||||
# - FirstName: 'Global Org'
|
||||
# LastName: 'Administrator'
|
||||
# UserName: 'zitadel-global-org-admin@caos.ch'
|
||||
# Email: 'zitadel-global-org-admin@caos.ch'
|
||||
# Password: 'Password1!'
|
||||
# Owners:
|
||||
# - 'zitadel-global-org-admin@caos.ch'
|
||||
# - Name: 'CAOS AG'
|
||||
# Domain: 'caos.ch'
|
||||
# Users:
|
||||
# - FirstName: 'Zitadel'
|
||||
# LastName: 'Administrator'
|
||||
# UserName: 'zitadel-admin'
|
||||
# Email: 'zitadel-admin@caos.ch'
|
||||
# Password: 'Password1!'
|
||||
# Owners:
|
||||
# - 'zitadel-admin@caos.ch'
|
||||
# Projects:
|
||||
# - Name: 'Zitadel'
|
||||
# OIDCApps:
|
||||
# - Name: 'Management-API'
|
||||
# - Name: 'Auth-API'
|
||||
# - Name: 'Admin-API'
|
||||
# - Name: 'Zitadel Console'
|
||||
# RedirectUris:
|
||||
# - '$ZITADEL_CONSOLE/auth/callback'
|
||||
# PostLogoutRedirectUris:
|
||||
# - '$ZITADEL_CONSOLE/signedout'
|
||||
# ResponseTypes:
|
||||
# - $ZITADEL_CONSOLE_RESPONSE_TYPE
|
||||
# GrantTypes:
|
||||
# - $ZITADEL_CONSOLE_GRANT_TYPE
|
||||
# ApplicationType: 'USER_AGENT'
|
||||
# AuthMethodType: 'NONE'
|
||||
# DevMode: $ZITADEL_CONSOLE_DEV_MODE
|
||||
# Owners:
|
||||
# - 'zitadel-admin@caos.ch'
|
||||
Step2:
|
||||
DefaultPasswordComplexityPolicy:
|
||||
MinLength: 8
|
||||
|
@ -2,6 +2,7 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
"strings"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
@ -18,7 +19,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type IAMRepository struct {
|
||||
@ -30,7 +31,8 @@ type IAMRepository struct {
|
||||
SystemDefaults systemdefaults.SystemDefaults
|
||||
Roles []string
|
||||
|
||||
IAMV2 *iam_business.Repository
|
||||
IAMV2Command *command.CommandSide
|
||||
IAMV2Query *query.QuerySide
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID string) (*iam_model.IAMMemberView, error) {
|
||||
@ -43,24 +45,24 @@ func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID stri
|
||||
|
||||
func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
member.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddMember(ctx, member)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddIAMMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.AddIAMMember(ctx, member)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
member.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeMember(ctx, member)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeIAMMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeIAMMember(ctx, member)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error {
|
||||
member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID)
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.RemoveMember(ctx, member)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.RemoveIAMMember(ctx, member)
|
||||
}
|
||||
return repo.IAMEventstore.RemoveIAMMember(ctx, member)
|
||||
}
|
||||
@ -97,8 +99,8 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string {
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.IDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Query.DefaultIDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
}
|
||||
|
||||
idp, err := repo.View.IDPConfigByID(idpConfigID)
|
||||
@ -110,37 +112,37 @@ func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string
|
||||
|
||||
func (repo *IAMRepository) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
idp.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddIDPConfig(ctx, idp)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultIDPConfig(ctx, idp)
|
||||
}
|
||||
return repo.IAMEventstore.AddIDPConfig(ctx, idp)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
idp.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeIDPConfig(ctx, idp)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultIDPConfig(ctx, idp)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeIDPConfig(ctx, idp)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) DeactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.DeactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.DeactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
}
|
||||
return repo.IAMEventstore.DeactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ReactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ReactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
}
|
||||
return repo.IAMEventstore.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error {
|
||||
// if repo.IAMV2 != nil {
|
||||
// return repo.IAMV2.
|
||||
// if repo.IAMV2Command != nil {
|
||||
// return repo.IAMV2Command.
|
||||
// }
|
||||
aggregates := make([]*es_models.Aggregate, 0)
|
||||
idp := iam_model.NewIDPConfig(repo.SystemDefaults.IamID, idpConfigID)
|
||||
@ -184,8 +186,8 @@ func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID stri
|
||||
|
||||
func (repo *IAMRepository) ChangeOidcIDPConfig(ctx context.Context, oidcConfig *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) {
|
||||
oidcConfig.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeIDPOIDCConfig(ctx, oidcConfig)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultIDPOIDCConfig(ctx, oidcConfig)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeIDPOIDCConfig(ctx, oidcConfig)
|
||||
}
|
||||
@ -238,16 +240,16 @@ func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_mode
|
||||
|
||||
func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddLabelPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultLabelPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddLabelPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeLabelPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultLabelPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeLabelPolicy(ctx, policy)
|
||||
}
|
||||
@ -279,16 +281,16 @@ func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode
|
||||
|
||||
func (repo *IAMRepository) AddDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddLoginPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultLoginPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddLoginPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeLoginPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultLoginPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeLoginPolicy(ctx, policy)
|
||||
}
|
||||
@ -317,8 +319,8 @@ func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, reques
|
||||
|
||||
func (repo *IAMRepository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) {
|
||||
provider.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddIDPProviderToLoginPolicy(ctx, provider)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddIDPProviderToDefaultLoginPolicy(ctx, provider)
|
||||
}
|
||||
return repo.IAMEventstore.AddIDPProviderToLoginPolicy(ctx, provider)
|
||||
}
|
||||
@ -360,15 +362,15 @@ func (repo *IAMRepository) SearchDefaultSecondFactors(ctx context.Context) (*iam
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) AddSecondFactorToLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddSecondFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddSecondFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
return repo.IAMEventstore.AddSecondFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) error {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.RemoveSecondFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
return repo.IAMEventstore.RemoveSecondFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
@ -385,15 +387,15 @@ func (repo *IAMRepository) SearchDefaultMultiFactors(ctx context.Context) (*iam_
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) AddMultiFactorToLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddMultiFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddMultiFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
return repo.IAMEventstore.AddMultiFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) error {
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.RemoveMultiFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
return repo.IAMEventstore.RemoveMultiFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||
}
|
||||
@ -425,16 +427,16 @@ func (repo *IAMRepository) GetDefaultPasswordComplexityPolicy(ctx context.Contex
|
||||
|
||||
func (repo *IAMRepository) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddPasswordComplexityPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultPasswordComplexityPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddPasswordComplexityPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangePasswordComplexityPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultPasswordComplexityPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangePasswordComplexityPolicy(ctx, policy)
|
||||
}
|
||||
@ -466,16 +468,16 @@ func (repo *IAMRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia
|
||||
|
||||
func (repo *IAMRepository) AddDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddPasswordAgePolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultPasswordAgePolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddPasswordAgePolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangePasswordAgePolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultPasswordAgePolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangePasswordAgePolicy(ctx, policy)
|
||||
}
|
||||
@ -507,16 +509,16 @@ func (repo *IAMRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context)
|
||||
|
||||
func (repo *IAMRepository) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddPasswordLockoutPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultPasswordLockoutPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddPasswordLockoutPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangePasswordLockoutPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultPasswordLockoutPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangePasswordLockoutPolicy(ctx, policy)
|
||||
}
|
||||
@ -548,16 +550,16 @@ func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgI
|
||||
|
||||
func (repo *IAMRepository) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.AddOrgIAMPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.AddDefaultOrgIAMPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.AddOrgIAMPolicy(ctx, policy)
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
policy.AggregateID = repo.SystemDefaults.IamID
|
||||
if repo.IAMV2 != nil {
|
||||
return repo.IAMV2.ChangeOrgIAMPolicy(ctx, policy)
|
||||
if repo.IAMV2Command != nil {
|
||||
return repo.IAMV2Command.ChangeDefaultOrgIAMPolicy(ctx, policy)
|
||||
}
|
||||
return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy)
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore"
|
||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler"
|
||||
@ -14,7 +16,6 @@ import (
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -65,7 +66,11 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
iamV2Command, err := command.StartCommandSide(&command.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -90,7 +95,8 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
||||
SystemDefaults: systemDefaults,
|
||||
SearchLimit: conf.SearchLimit,
|
||||
Roles: roles,
|
||||
IAMV2: iamV2,
|
||||
IAMV2Command: iamV2Command,
|
||||
IAMV2Query: iamV2Query,
|
||||
},
|
||||
AdministratorRepo: eventstore.AdministratorRepo{
|
||||
View: view,
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
auth_es "github.com/caos/zitadel/internal/auth/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/telemetry/metrics"
|
||||
"github.com/caos/zitadel/internal/telemetry/metrics/otel"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
view_model "github.com/caos/zitadel/internal/view/model"
|
||||
"go.opentelemetry.io/otel/api/metric"
|
||||
"net/http"
|
||||
@ -98,10 +99,10 @@ func (a *API) healthHandler() http.Handler {
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED")
|
||||
}
|
||||
if iam == nil || iam.SetUpStarted < iam_model.StepCount-1 {
|
||||
if iam == nil || iam.SetUpStarted < domain.StepCount-1 {
|
||||
return errors.ThrowPreconditionFailed(nil, "API-HBfs3", "IAM NOT SET UP")
|
||||
}
|
||||
if iam.SetUpDone < iam_model.StepCount-1 {
|
||||
if iam.SetUpDone < domain.StepCount-1 {
|
||||
return errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING")
|
||||
}
|
||||
return nil
|
||||
|
@ -2,6 +2,7 @@ package management
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
|
||||
@ -14,11 +15,11 @@ func iamFromModel(iam *iam_model.IAM) *management.Iam {
|
||||
}
|
||||
}
|
||||
|
||||
func iamSetupStepFromModel(step iam_model.Step) management.IamSetupStep {
|
||||
func iamSetupStepFromModel(step domain.Step) management.IamSetupStep {
|
||||
switch step {
|
||||
case iam_model.Step1:
|
||||
case domain.Step1:
|
||||
return management.IamSetupStep_iam_setup_step_1
|
||||
case iam_model.Step2:
|
||||
case domain.Step2:
|
||||
return management.IamSetupStep_iam_setup_step_2
|
||||
// case iam_model.Step3:
|
||||
// return management.IamSetupStep_iam_setup_step_3
|
||||
|
@ -2,17 +2,17 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type IAMRepository struct {
|
||||
IAMID string
|
||||
|
||||
IAMV2 *iam_business.Repository
|
||||
IAMV2QuerySide *query.QuerySide
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) GetIAM(ctx context.Context) (*model.IAM, error) {
|
||||
return repo.IAMV2.IAMByID(ctx, repo.IAMID)
|
||||
return repo.IAMV2QuerySide.IAMByID(ctx, repo.IAMID)
|
||||
}
|
||||
|
@ -5,13 +5,13 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
@ -25,6 +25,7 @@ import (
|
||||
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||
grant_es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
type UserGrant struct {
|
||||
@ -308,7 +309,7 @@ func (u *UserGrant) setIamProjectID() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if iam.SetUpDone < iam_model.StepCount-1 {
|
||||
if iam.SetUpDone < domain.StepCount-1 {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done")
|
||||
}
|
||||
u.iamProjectID = iam.IAMProjectID
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -110,7 +110,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -182,8 +182,8 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
|
||||
SystemDefaults: systemDefaults,
|
||||
},
|
||||
eventstore.IAMRepository{
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMV2: iamV2,
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMV2QuerySide: iamV2Query,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -2,17 +2,17 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type IamRepo struct {
|
||||
IAMID string
|
||||
IAMEvents *iam_event.IAMEventstore
|
||||
|
||||
IAMV2 *iam_business.Repository
|
||||
IAMV2Query *query.QuerySide
|
||||
}
|
||||
|
||||
func (repo *IamRepo) Health(ctx context.Context) error {
|
||||
@ -20,5 +20,5 @@ func (repo *IamRepo) Health(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (repo *IamRepo) IamByID(ctx context.Context) (*model.IAM, error) {
|
||||
return repo.IAMV2.IAMByID(ctx, repo.IAMID)
|
||||
return repo.IAMV2Query.IAMByID(ctx, repo.IAMID)
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ import (
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
grant_model "github.com/caos/zitadel/internal/usergrant/model"
|
||||
"github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
type UserGrantRepo struct {
|
||||
@ -72,7 +72,7 @@ func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if iam.SetUpDone < iam_model.StepCount-1 {
|
||||
if iam.SetUpDone < domain.StepCount-1 {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-skiwS", "Setup not done")
|
||||
}
|
||||
repo.IamProjectID = iam.IAMProjectID
|
||||
|
@ -12,12 +12,12 @@ import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
|
||||
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
type UserGrant struct {
|
||||
@ -224,7 +224,7 @@ func (u *UserGrant) setIamProjectID() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if iam.SetUpDone < iam_model.StepCount-1 {
|
||||
if iam.SetUpDone < domain.StepCount-1 {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done")
|
||||
}
|
||||
u.iamProjectID = iam.IAMProjectID
|
||||
|
@ -2,6 +2,7 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
|
||||
@ -19,7 +20,6 @@ import (
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
es_key "github.com/caos/zitadel/internal/key/repository/eventsourcing"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -79,7 +79,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
iamV2, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -96,9 +96,9 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
|
||||
IamEvents: iam,
|
||||
},
|
||||
eventstore.IamRepo{
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMEvents: iam,
|
||||
IAMV2: iamV2,
|
||||
IAMID: systemDefaults.IamID,
|
||||
IAMEvents: iam,
|
||||
IAMV2Query: iamV2,
|
||||
},
|
||||
eventstore.TokenVerifierRepo{
|
||||
//TODO: Add Token Verification Key
|
||||
|
@ -59,7 +59,7 @@ func (data *Data) createTemplate(templateName string, file *os.File) {
|
||||
}
|
||||
|
||||
func readErrorName() (errorName string) {
|
||||
flag.StringVar(&errorName, "Name", "", "Type of the error (e.g. Internal)")
|
||||
flag.StringVar(&errorName, "Name", "", "KeyType of the error (e.g. Internal)")
|
||||
flag.Parse()
|
||||
return errorName
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package eventstore
|
||||
type aggregater interface {
|
||||
//ID returns the aggreagte id
|
||||
ID() string
|
||||
//Type returns the aggregate type
|
||||
//KeyType returns the aggregate type
|
||||
Type() AggregateType
|
||||
//Events returns the events which will be pushed
|
||||
Events() []EventPusher
|
||||
@ -74,7 +74,7 @@ func (a *Aggregate) ID() string {
|
||||
return a.id
|
||||
}
|
||||
|
||||
//Type implements aggregater
|
||||
//KeyType implements aggregater
|
||||
func (a *Aggregate) Type() AggregateType {
|
||||
return a.typ
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ type EventPusher interface {
|
||||
EditorService() string
|
||||
//EditorUser is the user who wants to push the event
|
||||
EditorUser() string
|
||||
//Type must return an event type which should be unique in the aggregate
|
||||
//KeyType must return an event type which should be unique in the aggregate
|
||||
Type() EventType
|
||||
//Data returns the payload of the event. It represent the changed fields by the event
|
||||
// valid types are:
|
||||
@ -25,7 +25,7 @@ type EventReader interface {
|
||||
EditorService() string
|
||||
//EditorUser is the user who pushed the event
|
||||
EditorUser() string
|
||||
//Type is the type of the event
|
||||
//KeyType is the type of the event
|
||||
Type() EventType
|
||||
|
||||
AggregateID() string
|
||||
|
@ -36,7 +36,7 @@ func (e *BaseEvent) EditorUser() string {
|
||||
return e.User
|
||||
}
|
||||
|
||||
//Type implements EventPusher
|
||||
//KeyType implements EventPusher
|
||||
func (e *BaseEvent) Type() EventType {
|
||||
return e.EventType
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"log"
|
||||
)
|
||||
|
||||
//ReadModel is the minimum representation of a View model.
|
||||
//MemberReadModel is the minimum representation of a View model.
|
||||
// it might be saved in a database or in memory
|
||||
type ReadModel struct {
|
||||
ProcessedSequence uint64
|
||||
|
@ -2,7 +2,7 @@ package eventstore
|
||||
|
||||
import "time"
|
||||
|
||||
//ReadModel is the minimum representation of a View model.
|
||||
//MemberReadModel is the minimum representation of a View model.
|
||||
// It implements a basic reducer
|
||||
// it might be saved in a database or in memory
|
||||
type ReadModel struct {
|
||||
|
@ -26,7 +26,7 @@ type Event struct {
|
||||
// time drifts in different services could cause integrity problems
|
||||
CreationDate time.Time
|
||||
|
||||
//Type describes the cause of the event (e.g. user.added)
|
||||
//KeyType describes the cause of the event (e.g. user.added)
|
||||
// it should always be in past-form
|
||||
Type EventType
|
||||
|
||||
|
@ -2,7 +2,7 @@ package eventstore
|
||||
|
||||
import "time"
|
||||
|
||||
//WriteModel is the minimum representation of a command side view model.
|
||||
//MemberWriteModel is the minimum representation of a command side view model.
|
||||
// It implements a basic reducer
|
||||
// it's purpose is to reduce events to create new ones
|
||||
type WriteModel struct {
|
||||
|
@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
type Step int
|
||||
@ -23,8 +24,8 @@ type IAM struct {
|
||||
es_models.ObjectRoot
|
||||
GlobalOrgID string
|
||||
IAMProjectID string
|
||||
SetUpDone Step
|
||||
SetUpStarted Step
|
||||
SetUpDone domain.Step
|
||||
SetUpStarted domain.Step
|
||||
Members []*IAMMember
|
||||
IDPs []*IDPConfig
|
||||
DefaultLoginPolicy *LoginPolicy
|
||||
|
@ -22,6 +22,8 @@ type PasswordComplexityPolicy struct {
|
||||
HasUppercase bool
|
||||
HasNumber bool
|
||||
HasSymbol bool
|
||||
|
||||
Default bool
|
||||
}
|
||||
|
||||
func (p *PasswordComplexityPolicy) IsValid() error {
|
||||
@ -30,3 +32,26 @@ func (p *PasswordComplexityPolicy) IsValid() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PasswordComplexityPolicy) Check(password string) error {
|
||||
if p.MinLength != 0 && uint64(len(password)) < p.MinLength {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "MODEL-HuJf6", "Errors.User.PasswordComplexityPolicy.MinLength")
|
||||
}
|
||||
|
||||
if p.HasLowercase && !hasStringLowerCase(password) {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "MODEL-co3Xw", "Errors.User.PasswordComplexityPolicy.HasLower")
|
||||
}
|
||||
|
||||
if p.HasUppercase && !hasStringUpperCase(password) {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "MODEL-VoaRj", "Errors.User.PasswordComplexityPolicy.HasUpper")
|
||||
}
|
||||
|
||||
if p.HasNumber && !hasNumber(password) {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "MODEL-ZBv4H", "Errors.User.PasswordComplexityPolicy.HasNumber")
|
||||
}
|
||||
|
||||
if p.HasSymbol && !hasSymbol(password) {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "MODEL-ZDLwA", "Errors.User.PasswordComplexityPolicy.HasSymbol")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -73,49 +73,49 @@ func (es *IAMEventstore) IAMEventsByID(ctx context.Context, id string, sequence
|
||||
return es.FilterEvents(ctx, query)
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := es.IAMByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started")
|
||||
}
|
||||
|
||||
if iam == nil {
|
||||
iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}}
|
||||
}
|
||||
iam.SetUpStarted = step
|
||||
repoIAM := model.IAMFromModel(iam)
|
||||
|
||||
createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
es.iamCache.cacheIAM(repoIAM)
|
||||
return model.IAMToModel(repoIAM), nil
|
||||
}
|
||||
|
||||
func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := es.IAMByID(ctx, iamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iam.SetUpDone = step
|
||||
|
||||
repoIam := model.IAMFromModel(iam)
|
||||
createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam)
|
||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
es.iamCache.cacheIAM(repoIam)
|
||||
return model.IAMToModel(repoIam), nil
|
||||
}
|
||||
//func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
// iam, err := es.IAMByID(ctx, iamID)
|
||||
// if err != nil && !caos_errs.IsNotFound(err) {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) {
|
||||
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started")
|
||||
// }
|
||||
//
|
||||
// if iam == nil {
|
||||
// iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}}
|
||||
// }
|
||||
// iam.SetUpStarted = step
|
||||
// repoIAM := model.IAMFromModel(iam)
|
||||
//
|
||||
// createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM)
|
||||
// err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// es.iamCache.cacheIAM(repoIAM)
|
||||
// return model.IAMToModel(repoIAM), nil
|
||||
//}
|
||||
//
|
||||
//func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
// iam, err := es.IAMByID(ctx, iamID)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// iam.SetUpDone = step
|
||||
//
|
||||
// repoIam := model.IAMFromModel(iam)
|
||||
// createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam)
|
||||
// err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// es.iamCache.cacheIAM(repoIam)
|
||||
// return model.IAMToModel(repoIam), nil
|
||||
//}
|
||||
|
||||
func (es *IAMEventstore) PrepareSetupDone(ctx context.Context, iam *model.IAM, aggregate *models.Aggregate, step iam_model.Step) (*model.IAM, *models.Aggregate, func(ctx context.Context, aggregates ...*models.Aggregate) error, error) {
|
||||
iam.SetUpDone = model.Step(step)
|
||||
|
@ -1562,7 +1562,7 @@ func TestAddIdpProviderToLoginPolicy(t *testing.T) {
|
||||
t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID)
|
||||
}
|
||||
if result.Type != tt.res.result.Type {
|
||||
t.Errorf("got wrong result Type: expected: %v, actual: %v ", tt.res.result.Type, result.Type)
|
||||
t.Errorf("got wrong result KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -75,8 +76,8 @@ func IAMToModel(iam *IAM) *model.IAM {
|
||||
idps := IDPConfigsToModel(iam.IDPs)
|
||||
converted := &model.IAM{
|
||||
ObjectRoot: iam.ObjectRoot,
|
||||
SetUpStarted: model.Step(iam.SetUpStarted),
|
||||
SetUpDone: model.Step(iam.SetUpDone),
|
||||
SetUpStarted: domain.Step(iam.SetUpStarted),
|
||||
SetUpDone: domain.Step(iam.SetUpDone),
|
||||
GlobalOrgID: iam.GlobalOrgID,
|
||||
IAMProjectID: iam.IAMProjectID,
|
||||
Members: members,
|
||||
|
@ -2,15 +2,15 @@ package eventstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type IAMRepository struct {
|
||||
IAMV2 *iam_business.Repository
|
||||
IAMV2Query *query.QuerySide
|
||||
}
|
||||
|
||||
func (repo *IAMRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) {
|
||||
return repo.IAMV2.IAMByID(ctx, id)
|
||||
return repo.IAMV2Query.IAMByID(ctx, id)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package eventsourcing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/v2/query"
|
||||
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/config/types"
|
||||
@ -17,7 +18,6 @@ import (
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
es_grant "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing"
|
||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@ -75,7 +75,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -98,7 +98,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
|
||||
UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults},
|
||||
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
|
||||
IAMRepository: eventstore.IAMRepository{
|
||||
IAMV2: iamV2,
|
||||
IAMV2Query: iamV2Query,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ func (msg *EmailMessage) GetContent() string {
|
||||
}
|
||||
|
||||
//default mime-type is html
|
||||
mime := "MIME-version: 1.0;" + lineBreak + "Content-Type: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
mime := "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
if !isHTML(msg.Content) {
|
||||
mime = "MIME-version: 1.0;" + lineBreak + "Content-Type: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
mime = "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak
|
||||
}
|
||||
subject := "Subject: " + msg.Subject + lineBreak
|
||||
message += subject + mime + lineBreak + msg.Content
|
||||
|
@ -2637,7 +2637,7 @@ func TestAddIdpProviderToLoginPolicy(t *testing.T) {
|
||||
t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID)
|
||||
}
|
||||
if result.Type != tt.res.result.Type {
|
||||
t.Errorf("got wrong result Type: expected: %v, actual: %v ", tt.res.result.Type, result.Type)
|
||||
t.Errorf("got wrong result KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ func TestLoginPolicyIdpProviderAddedAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
|
||||
agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx)
|
||||
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
@ -509,7 +509,7 @@ func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
|
||||
agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx)
|
||||
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
@ -682,7 +682,7 @@ func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx)
|
||||
agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx)
|
||||
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||
t.Errorf("got wrong err: %v ", err)
|
||||
return
|
||||
|
@ -7,28 +7,28 @@ import (
|
||||
|
||||
type IAMSetUp struct {
|
||||
Step1 *Step1
|
||||
Step2 *Step2
|
||||
Step3 *Step3
|
||||
Step4 *Step4
|
||||
Step5 *Step5
|
||||
Step6 *Step6
|
||||
Step7 *Step7
|
||||
Step8 *Step8
|
||||
//Step2 *Step2
|
||||
//Step3 *Step3
|
||||
//Step4 *Step4
|
||||
//Step5 *Step5
|
||||
//Step6 *Step6
|
||||
//Step7 *Step7
|
||||
//Step8 *Step8
|
||||
}
|
||||
|
||||
func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]step, error) {
|
||||
steps := make([]step, 0)
|
||||
func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]stepV2, error) {
|
||||
steps := make([]stepV2, 0)
|
||||
missingSteps := make([]iam_model.Step, 0)
|
||||
|
||||
for _, step := range []step{
|
||||
for _, step := range []stepV2{
|
||||
setup.Step1,
|
||||
setup.Step2,
|
||||
setup.Step3,
|
||||
setup.Step4,
|
||||
setup.Step5,
|
||||
setup.Step6,
|
||||
setup.Step7,
|
||||
setup.Step8,
|
||||
//setup.Step2,
|
||||
//setup.Step3,
|
||||
//setup.Step4,
|
||||
//setup.Step5,
|
||||
//setup.Step6,
|
||||
//setup.Step7,
|
||||
//setup.Step8,
|
||||
} {
|
||||
if step.step() <= currentDone {
|
||||
continue
|
||||
|
@ -3,24 +3,12 @@ package setup
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
@ -29,6 +17,8 @@ type Setup struct {
|
||||
OrgEvents *org_event.OrgEventstore
|
||||
UserEvents *usr_event.UserEventstore
|
||||
ProjectEvents *proj_event.ProjectEventstore
|
||||
|
||||
Commands *command.CommandSide
|
||||
}
|
||||
|
||||
const (
|
||||
@ -48,168 +38,169 @@ const (
|
||||
OIDCAuthMethodTypePost = "POST"
|
||||
)
|
||||
|
||||
func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
||||
setup := &Setup{
|
||||
iamID: sd.IamID,
|
||||
}
|
||||
es, err := es_int.Start(esConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd)
|
||||
|
||||
setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return setup, nil
|
||||
}
|
||||
|
||||
func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error {
|
||||
logging.Log("SETUP-hwG32").Info("starting setup")
|
||||
|
||||
iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
if iam != nil && (iam.SetUpDone == iam_model.StepCount-1 || iam.SetUpStarted != iam.SetUpDone) {
|
||||
logging.Log("SETUP-cWEsn").Info("all steps done")
|
||||
return nil
|
||||
}
|
||||
|
||||
if iam == nil {
|
||||
iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}}
|
||||
}
|
||||
|
||||
steps, err := setUpConfig.steps(iam.SetUpDone)
|
||||
if err != nil || len(steps) == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx = setSetUpContextData(ctx, s.iamID)
|
||||
|
||||
for _, step := range steps {
|
||||
step.init(s)
|
||||
if step.step() != iam.SetUpDone+1 {
|
||||
logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order")
|
||||
return errors.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison")
|
||||
}
|
||||
iam, err = s.IamEvents.StartSetup(ctx, s.iamID, step.step())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
iam, err = step.execute(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.validateExecutedStep(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logging.Log("SETUP-ds31h").Info("setup done")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Setup) validateExecutedStep(ctx context.Context) error {
|
||||
iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if iam.SetUpStarted != iam.SetUpDone {
|
||||
return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType {
|
||||
types := make([]proj_model.OIDCResponseType, len(responseTypes))
|
||||
for i, t := range responseTypes {
|
||||
types[i] = getOIDCResponseType(t)
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func getOIDCResponseType(responseType string) proj_model.OIDCResponseType {
|
||||
switch responseType {
|
||||
case OIDCResponseTypeCode:
|
||||
return proj_model.OIDCResponseTypeCode
|
||||
case OIDCResponseTypeIDToken:
|
||||
return proj_model.OIDCResponseTypeIDToken
|
||||
case OIDCResponseTypeToken:
|
||||
return proj_model.OIDCResponseTypeIDTokenToken
|
||||
}
|
||||
return proj_model.OIDCResponseTypeCode
|
||||
}
|
||||
|
||||
func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType {
|
||||
types := make([]proj_model.OIDCGrantType, len(grantTypes))
|
||||
for i, t := range grantTypes {
|
||||
types[i] = getOIDCGrantType(t)
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType {
|
||||
switch grantTypes {
|
||||
case OIDCGrantTypeAuthorizationCode:
|
||||
return proj_model.OIDCGrantTypeAuthorizationCode
|
||||
case OIDCGrantTypeImplicit:
|
||||
return proj_model.OIDCGrantTypeImplicit
|
||||
case OIDCGrantTypeRefreshToken:
|
||||
return proj_model.OIDCGrantTypeRefreshToken
|
||||
}
|
||||
return proj_model.OIDCGrantTypeAuthorizationCode
|
||||
}
|
||||
|
||||
func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType {
|
||||
switch appType {
|
||||
case OIDCApplicationTypeNative:
|
||||
return proj_model.OIDCApplicationTypeNative
|
||||
case OIDCApplicationTypeUserAgent:
|
||||
return proj_model.OIDCApplicationTypeUserAgent
|
||||
case OIDCApplicationTypeWeb:
|
||||
return proj_model.OIDCApplicationTypeWeb
|
||||
}
|
||||
return proj_model.OIDCApplicationTypeWeb
|
||||
}
|
||||
|
||||
func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType {
|
||||
switch authMethod {
|
||||
case OIDCAuthMethodTypeNone:
|
||||
return proj_model.OIDCAuthMethodTypeNone
|
||||
case OIDCAuthMethodTypeBasic:
|
||||
return proj_model.OIDCAuthMethodTypeBasic
|
||||
case OIDCAuthMethodTypePost:
|
||||
return proj_model.OIDCAuthMethodTypePost
|
||||
}
|
||||
return proj_model.OIDCAuthMethodTypeBasic
|
||||
}
|
||||
|
||||
//
|
||||
//func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
||||
// setup := &Setup{
|
||||
// iamID: sd.IamID,
|
||||
// }
|
||||
// es, err := es_int.Start(esConfig)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{
|
||||
// Eventstore: es,
|
||||
// Cache: esConfig.Cache,
|
||||
// }, sd)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd)
|
||||
//
|
||||
// setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{
|
||||
// Eventstore: es,
|
||||
// Cache: esConfig.Cache,
|
||||
// }, sd)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{
|
||||
// Eventstore: es,
|
||||
// Cache: esConfig.Cache,
|
||||
// }, sd)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// return setup, nil
|
||||
//}
|
||||
//
|
||||
//func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error {
|
||||
// logging.Log("SETUP-hwG32").Info("starting setup")
|
||||
//
|
||||
// iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
// if err != nil && !caos_errs.IsNotFound(err) {
|
||||
// return err
|
||||
// }
|
||||
// if iam != nil && (iam.SetUpDone == domain.Step(iam_model.StepCount)-1 || iam.SetUpStarted != iam.SetUpDone) {
|
||||
// logging.Log("SETUP-cWEsn").Info("all steps done")
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// if iam == nil {
|
||||
// iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}}
|
||||
// }
|
||||
//
|
||||
// steps, err := setUpConfig.steps(iam_model.Step(iam.SetUpDone))
|
||||
// if err != nil || len(steps) == 0 {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// ctx = setSetUpContextData(ctx, s.iamID)
|
||||
//
|
||||
// for _, step := range steps {
|
||||
// step.init(s)
|
||||
// if step.step() != iam_model.Step(iam.SetUpDone)+1 {
|
||||
// logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order")
|
||||
// return errors.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison")
|
||||
// }
|
||||
// iam, err = s.IamEvents.StartSetup(ctx, s.iamID, step.step())
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// iam, err = step.execute(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// err = s.validateExecutedStep(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// logging.Log("SETUP-ds31h").Info("setup done")
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (s *Setup) validateExecutedStep(ctx context.Context) error {
|
||||
// iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if iam.SetUpStarted != iam.SetUpDone {
|
||||
// return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done")
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType {
|
||||
// types := make([]proj_model.OIDCResponseType, len(responseTypes))
|
||||
// for i, t := range responseTypes {
|
||||
// types[i] = getOIDCResponseType(t)
|
||||
// }
|
||||
// return types
|
||||
//}
|
||||
//
|
||||
//func getOIDCResponseType(responseType string) proj_model.OIDCResponseType {
|
||||
// switch responseType {
|
||||
// case OIDCResponseTypeCode:
|
||||
// return proj_model.OIDCResponseTypeCode
|
||||
// case OIDCResponseTypeIDToken:
|
||||
// return proj_model.OIDCResponseTypeIDToken
|
||||
// case OIDCResponseTypeToken:
|
||||
// return proj_model.OIDCResponseTypeIDTokenToken
|
||||
// }
|
||||
// return proj_model.OIDCResponseTypeCode
|
||||
//}
|
||||
//
|
||||
//func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType {
|
||||
// types := make([]proj_model.OIDCGrantType, len(grantTypes))
|
||||
// for i, t := range grantTypes {
|
||||
// types[i] = getOIDCGrantType(t)
|
||||
// }
|
||||
// return types
|
||||
//}
|
||||
//
|
||||
//func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType {
|
||||
// switch grantTypes {
|
||||
// case OIDCGrantTypeAuthorizationCode:
|
||||
// return proj_model.OIDCGrantTypeAuthorizationCode
|
||||
// case OIDCGrantTypeImplicit:
|
||||
// return proj_model.OIDCGrantTypeImplicit
|
||||
// case OIDCGrantTypeRefreshToken:
|
||||
// return proj_model.OIDCGrantTypeRefreshToken
|
||||
// }
|
||||
// return proj_model.OIDCGrantTypeAuthorizationCode
|
||||
//}
|
||||
//
|
||||
//func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType {
|
||||
// switch appType {
|
||||
// case OIDCApplicationTypeNative:
|
||||
// return proj_model.OIDCApplicationTypeNative
|
||||
// case OIDCApplicationTypeUserAgent:
|
||||
// return proj_model.OIDCApplicationTypeUserAgent
|
||||
// case OIDCApplicationTypeWeb:
|
||||
// return proj_model.OIDCApplicationTypeWeb
|
||||
// }
|
||||
// return proj_model.OIDCApplicationTypeWeb
|
||||
//}
|
||||
//
|
||||
//func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType {
|
||||
// switch authMethod {
|
||||
// case OIDCAuthMethodTypeNone:
|
||||
// return proj_model.OIDCAuthMethodTypeNone
|
||||
// case OIDCAuthMethodTypeBasic:
|
||||
// return proj_model.OIDCAuthMethodTypeBasic
|
||||
// case OIDCAuthMethodTypePost:
|
||||
// return proj_model.OIDCAuthMethodTypePost
|
||||
// }
|
||||
// return proj_model.OIDCAuthMethodTypeBasic
|
||||
//}
|
||||
//
|
||||
func setSetUpContextData(ctx context.Context, orgID string) context.Context {
|
||||
return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser, OrgID: orgID})
|
||||
}
|
||||
|
104
internal/setup/setup_v2.go
Normal file
104
internal/setup/setup_v2.go
Normal file
@ -0,0 +1,104 @@
|
||||
package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
func StartSetupV2(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
||||
setup := &Setup{
|
||||
iamID: sd.IamID,
|
||||
}
|
||||
es, err := es_int.Start(esConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{
|
||||
Eventstore: es,
|
||||
Cache: esConfig.Cache,
|
||||
}, sd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
setup.Commands, err = command.StartCommandSide(&command.Config{
|
||||
Eventstore: es.V2(),
|
||||
SystemDefaults: sd,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return setup, nil
|
||||
}
|
||||
|
||||
func (s *Setup) ExecuteV2(ctx context.Context, setUpConfig IAMSetUp) error {
|
||||
logging.Log("SETUP-JAK2q").Info("starting setup")
|
||||
|
||||
iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
if iam != nil && (iam.SetUpDone == domain.StepCount-1 || iam.SetUpStarted != iam.SetUpDone) {
|
||||
logging.Log("SETUP-VA2k1").Info("all steps done")
|
||||
return nil
|
||||
}
|
||||
|
||||
if iam == nil {
|
||||
iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}}
|
||||
}
|
||||
|
||||
steps, err := setUpConfig.steps(iam_model.Step(iam.SetUpDone))
|
||||
if err != nil || len(steps) == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx = setSetUpContextData(ctx, s.iamID)
|
||||
|
||||
for _, step := range steps {
|
||||
//step.init(s)
|
||||
if step.step() != iam_model.Step(iam.SetUpDone+1) {
|
||||
logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order")
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison")
|
||||
}
|
||||
iam, err = s.Commands.StartSetup(ctx, s.iamID, domain.Step(step.step()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = step.execute(ctx, iam.AggregateID, *s.Commands)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.validateExecutedStep(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
logging.Log("SETUP-ds31h").Info("setup done")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Setup) validateExecutedStep(ctx context.Context) error {
|
||||
iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if iam.SetUpStarted != iam.SetUpDone {
|
||||
return caos_errs.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done")
|
||||
}
|
||||
return nil
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type step interface {
|
||||
@ -12,3 +13,9 @@ type step interface {
|
||||
init(*Setup)
|
||||
isNil() bool
|
||||
}
|
||||
|
||||
type stepV2 interface {
|
||||
step() iam_model.Step
|
||||
execute(context.Context, string, command.CommandSide) error
|
||||
isNil() bool
|
||||
}
|
||||
|
@ -4,322 +4,287 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
org_model "github.com/caos/zitadel/internal/org/model"
|
||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type Step1 struct {
|
||||
GlobalOrg string
|
||||
IAMProject string
|
||||
DefaultLoginPolicy LoginPolicy
|
||||
Orgs []Org
|
||||
Owners []string
|
||||
//GlobalOrg string
|
||||
//IAMProject string
|
||||
//DefaultLoginPolicy LoginPolicy
|
||||
//Orgs []Org
|
||||
//Owners []string
|
||||
command.Step1
|
||||
|
||||
setup *Setup
|
||||
createdUsers map[string]*usr_model.User
|
||||
createdOrgs map[string]*org_model.Org
|
||||
createdProjects map[string]*proj_model.Project
|
||||
pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
|
||||
//setup *Setup
|
||||
//createdUsers map[string]*usr_model.User
|
||||
//createdOrgs map[string]*org_model.Org
|
||||
//createdProjects map[string]*proj_model.Project
|
||||
//pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
|
||||
}
|
||||
|
||||
func (s *Step1) isNil() bool {
|
||||
return s == nil
|
||||
}
|
||||
|
||||
func (step *Step1) step() iam_model.Step {
|
||||
func (s *Step1) step() iam_model.Step {
|
||||
return iam_model.Step1
|
||||
}
|
||||
|
||||
func (step *Step1) init(setup *Setup) {
|
||||
step.setup = setup
|
||||
step.createdUsers = make(map[string]*usr_model.User)
|
||||
step.createdOrgs = make(map[string]*org_model.Org)
|
||||
step.createdProjects = make(map[string]*proj_model.Project)
|
||||
}
|
||||
//func (s *Step1) init(setup *Setup) {
|
||||
// s.setup = setup
|
||||
// s.createdUsers = make(map[string]*usr_model.User)
|
||||
// s.createdOrgs = make(map[string]*org_model.Org)
|
||||
// s.createdProjects = make(map[string]*proj_model.Project)
|
||||
//}
|
||||
|
||||
func (step *Step1) execute(ctx context.Context) (*iam_model.IAM, error) {
|
||||
err := step.loginPolicy(ctx, step.DefaultLoginPolicy)
|
||||
func (s *Step1) execute(ctx context.Context, iamID string, commands command.CommandSide) error {
|
||||
err := commands.SetupStep1(ctx, iamID, s.Step1)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-Hdu8S").WithError(err).Error("unable to create login policy")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
step.pwComplexityPolicy = new(iam_model.PasswordComplexityPolicyView)
|
||||
|
||||
err = step.orgs(ctx, step.Orgs)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up orgs")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx = setSetUpContextData(ctx, step.setup.iamID)
|
||||
err = step.iamOwners(ctx, step.Owners)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-WHr01").WithError(err).Error("unable to set up iam owners")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = step.setGlobalOrg(ctx, step.GlobalOrg)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-0874m").WithError(err).Error("unable to set global org")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = step.setIamProject(ctx, step.IAMProject)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-kaWjq").WithError(err).Error("unable to set zitadel project")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam, err := step.setup.IamEvents.SetupDone(ctx, step.setup.iamID, step.step())
|
||||
if err != nil {
|
||||
logging.Log("SETUP-de342").WithField("step", step.step()).WithError(err).Error("unable to finish setup")
|
||||
return nil, err
|
||||
}
|
||||
return iam, nil
|
||||
}
|
||||
|
||||
func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error {
|
||||
logging.Log("SETUP-4djul").Info("setting up login policy")
|
||||
loginPolicy := &iam_model.LoginPolicy{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: step.setup.iamID,
|
||||
},
|
||||
AllowRegister: policy.AllowRegister,
|
||||
AllowUsernamePassword: policy.AllowUsernamePassword,
|
||||
AllowExternalIdp: policy.AllowExternalIdp,
|
||||
}
|
||||
_, err := step.setup.IamEvents.AddLoginPolicy(ctx, loginPolicy)
|
||||
return err
|
||||
}
|
||||
|
||||
func (step *Step1) orgs(ctx context.Context, orgs []Org) error {
|
||||
logging.Log("SETUP-dsTh3").Info("setting up orgs")
|
||||
for _, iamOrg := range orgs {
|
||||
org, err := step.org(ctx, iamOrg)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org")
|
||||
return err
|
||||
}
|
||||
step.createdOrgs[iamOrg.Name] = org
|
||||
logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation")
|
||||
|
||||
var policy *iam_model.OrgIAMPolicyView
|
||||
if iamOrg.OrgIamPolicy {
|
||||
policy, err = step.iamorgpolicy(ctx, org)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy")
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
policy = &iam_model.OrgIAMPolicyView{
|
||||
UserLoginMustBeDomain: true,
|
||||
}
|
||||
}
|
||||
|
||||
ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||
err = step.users(ctx, iamOrg.Users, policy)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users")
|
||||
return err
|
||||
}
|
||||
|
||||
err = step.orgOwners(ctx, org, iamOrg.Owners)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners")
|
||||
return err
|
||||
}
|
||||
|
||||
err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects")
|
||||
return err
|
||||
}
|
||||
}
|
||||
logging.Log("SETUP-dgjT4").Info("orgs set up")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) {
|
||||
ctx = setSetUpContextData(ctx, "")
|
||||
createOrg := &org_model.Org{
|
||||
Name: org.Name,
|
||||
Domains: []*org_model.OrgDomain{{Domain: org.Domain}},
|
||||
}
|
||||
return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil)
|
||||
}
|
||||
|
||||
func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) {
|
||||
ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||
policy := &iam_model.OrgIAMPolicy{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||
UserLoginMustBeDomain: false,
|
||||
}
|
||||
createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &iam_model.OrgIAMPolicyView{
|
||||
AggregateID: org.AggregateID,
|
||||
UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (step *Step1) iamOwners(ctx context.Context, owners []string) error {
|
||||
logging.Log("SETUP-dtxfj").Info("setting iam owners")
|
||||
for _, iamOwner := range owners {
|
||||
user, ok := step.createdUsers[iamOwner]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members")
|
||||
}
|
||||
_, err := step.setup.IamEvents.AddIAMMember(ctx, &iam_model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: step.setup.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}})
|
||||
if err != nil {
|
||||
logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner")
|
||||
return err
|
||||
}
|
||||
}
|
||||
logging.Log("SETUP-fg5aq").Info("iam owners set")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error {
|
||||
logging.Log("SETUP-dsj75").Info("setting global org")
|
||||
globalOrg, ok := step.createdOrgs[globalOrgName]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName)
|
||||
}
|
||||
|
||||
if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil {
|
||||
logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam")
|
||||
logging.Log("SETUP-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup")
|
||||
return err
|
||||
}
|
||||
logging.Log("SETUP-d32h1").Info("global org set")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error {
|
||||
logging.Log("SETUP-HE3qa").Info("setting iam project")
|
||||
iamProject, ok := step.createdProjects[iamProjectName]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName)
|
||||
}
|
||||
|
||||
if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil {
|
||||
logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam")
|
||||
return err
|
||||
}
|
||||
logging.Log("SETUP-d7WEU").Info("iam project set")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error {
|
||||
for _, user := range users {
|
||||
created, err := step.user(ctx, user, orgPolicy)
|
||||
if err != nil {
|
||||
logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user")
|
||||
return err
|
||||
}
|
||||
step.createdUsers[user.Email] = created
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) {
|
||||
createUser := &usr_model.User{
|
||||
UserName: user.UserName,
|
||||
Human: &usr_model.Human{
|
||||
Profile: &usr_model.Profile{
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
},
|
||||
Email: &usr_model.Email{
|
||||
EmailAddress: user.Email,
|
||||
IsEmailVerified: true,
|
||||
},
|
||||
Password: &usr_model.Password{
|
||||
SecretString: user.Password,
|
||||
},
|
||||
},
|
||||
}
|
||||
return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy)
|
||||
}
|
||||
|
||||
func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error {
|
||||
for _, orgOwner := range owners {
|
||||
user, ok := step.createdUsers[orgOwner]
|
||||
if !ok {
|
||||
logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members")
|
||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner)
|
||||
}
|
||||
err := step.orgOwner(ctx, org, user)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error {
|
||||
addMember := &org_model.OrgMember{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||
UserID: user.AggregateID,
|
||||
Roles: []string{OrgOwnerRole},
|
||||
}
|
||||
_, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember)
|
||||
return err
|
||||
}
|
||||
|
||||
func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
ctxData.UserID = ownerID
|
||||
projectCtx := authz.SetCtxData(ctx, ctxData)
|
||||
|
||||
for _, project := range projects {
|
||||
createdProject, err := step.project(projectCtx, project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
step.createdProjects[createdProject.Name] = createdProject
|
||||
for _, oidc := range project.OIDCApps {
|
||||
app, err := step.oidcApp(ctx, createdProject, oidc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) {
|
||||
addProject := &proj_model.Project{
|
||||
Name: project.Name,
|
||||
}
|
||||
return step.setup.ProjectEvents.CreateProject(ctx, addProject, false)
|
||||
}
|
||||
|
||||
func (step *Step1) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) {
|
||||
addOIDCApp := &proj_model.Application{
|
||||
ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID},
|
||||
Name: oidc.Name,
|
||||
OIDCConfig: &proj_model.OIDCConfig{
|
||||
RedirectUris: oidc.RedirectUris,
|
||||
ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes),
|
||||
GrantTypes: getOIDCGrantTypes(oidc.GrantTypes),
|
||||
ApplicationType: getOIDCApplicationType(oidc.ApplicationType),
|
||||
AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType),
|
||||
PostLogoutRedirectUris: oidc.PostLogoutRedirectUris,
|
||||
DevMode: oidc.DevMode,
|
||||
},
|
||||
}
|
||||
return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp)
|
||||
}
|
||||
//
|
||||
//func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error {
|
||||
// logging.Log("SETUP-4djul").Info("setting up login policy")
|
||||
// loginPolicy := &iam_model.LoginPolicy{
|
||||
// ObjectRoot: models.ObjectRoot{
|
||||
// AggregateID: step.setup.iamID,
|
||||
// },
|
||||
// AllowRegister: policy.AllowRegister,
|
||||
// AllowUsernamePassword: policy.AllowUsernamePassword,
|
||||
// AllowExternalIdp: policy.AllowExternalIdp,
|
||||
// }
|
||||
// _, err := step.setup.Commands.AddDefaultLoginPolicy(ctx, loginPolicy)
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) orgs(ctx context.Context, orgs []Org) error {
|
||||
// logging.Log("SETUP-dsTh3").Info("setting up orgs")
|
||||
// for _, iamOrg := range orgs {
|
||||
// org, err := step.org(ctx, iamOrg)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org")
|
||||
// return err
|
||||
// }
|
||||
// step.createdOrgs[iamOrg.Name] = org
|
||||
// logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation")
|
||||
//
|
||||
// var policy *iam_model.OrgIAMPolicyView
|
||||
// if iamOrg.OrgIamPolicy {
|
||||
// policy, err = step.iamorgpolicy(ctx, org)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy")
|
||||
// return err
|
||||
// }
|
||||
// } else {
|
||||
// policy = &iam_model.OrgIAMPolicyView{
|
||||
// UserLoginMustBeDomain: true,
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||
// err = step.users(ctx, iamOrg.Users, policy)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users")
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// err = step.orgOwners(ctx, org, iamOrg.Owners)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners")
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects")
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// logging.Log("SETUP-dgjT4").Info("orgs set up")
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) {
|
||||
// ctx = setSetUpContextData(ctx, "")
|
||||
// createOrg := &org_model.Org{
|
||||
// Name: org.Name,
|
||||
// Domains: []*org_model.OrgDomain{{Domain: org.Domain}},
|
||||
// }
|
||||
// return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil)
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) {
|
||||
// ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||
// policy := &iam_model.OrgIAMPolicy{
|
||||
// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||
// UserLoginMustBeDomain: false,
|
||||
// }
|
||||
// createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return &iam_model.OrgIAMPolicyView{
|
||||
// AggregateID: org.AggregateID,
|
||||
// UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain,
|
||||
// }, nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) iamOwners(ctx context.Context, owners []string) error {
|
||||
// logging.Log("SETUP-dtxfj").Info("setting iam owners")
|
||||
// for _, iamOwner := range owners {
|
||||
// user, ok := step.createdUsers[iamOwner]
|
||||
// if !ok {
|
||||
// logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members")
|
||||
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members")
|
||||
// }
|
||||
// _, err := step.setup.Commands.AddIAMMember(ctx, &iam_model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: step.setup.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}})
|
||||
// if err != nil {
|
||||
// logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner")
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// logging.Log("SETUP-fg5aq").Info("iam owners set")
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error {
|
||||
// logging.Log("SETUP-dsj75").Info("setting global org")
|
||||
// globalOrg, ok := step.createdOrgs[globalOrgName]
|
||||
// if !ok {
|
||||
// logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created")
|
||||
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName)
|
||||
// }
|
||||
//
|
||||
// if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil {
|
||||
// logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam")
|
||||
// return err
|
||||
// }
|
||||
// logging.Log("SETUP-d32h1").Info("global org set")
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error {
|
||||
// logging.Log("SETUP-HE3qa").Info("setting iam project")
|
||||
// iamProject, ok := step.createdProjects[iamProjectName]
|
||||
// if !ok {
|
||||
// logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created")
|
||||
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName)
|
||||
// }
|
||||
//
|
||||
// if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil {
|
||||
// logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam")
|
||||
// return err
|
||||
// }
|
||||
// logging.Log("SETUP-d7WEU").Info("iam project set")
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error {
|
||||
// for _, user := range users {
|
||||
// created, err := step.user(ctx, user, orgPolicy)
|
||||
// if err != nil {
|
||||
// logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user")
|
||||
// return err
|
||||
// }
|
||||
// step.createdUsers[user.Email] = created
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) {
|
||||
// createUser := &usr_model.User{
|
||||
// UserName: user.UserName,
|
||||
// Human: &usr_model.Human{
|
||||
// Profile: &usr_model.Profile{
|
||||
// FirstName: user.FirstName,
|
||||
// LastName: user.LastName,
|
||||
// },
|
||||
// Email: &usr_model.Email{
|
||||
// EmailAddress: user.Email,
|
||||
// IsEmailVerified: true,
|
||||
// },
|
||||
// Password: &usr_model.Password{
|
||||
// SecretString: user.Password,
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy)
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error {
|
||||
// for _, orgOwner := range owners {
|
||||
// user, ok := step.createdUsers[orgOwner]
|
||||
// if !ok {
|
||||
// logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members")
|
||||
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner)
|
||||
// }
|
||||
// err := step.orgOwner(ctx, org, user)
|
||||
// if err != nil {
|
||||
// logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org")
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error {
|
||||
// addMember := &org_model.OrgMember{
|
||||
// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||
// UserID: user.AggregateID,
|
||||
// Roles: []string{OrgOwnerRole},
|
||||
// }
|
||||
// _, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember)
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error {
|
||||
// ctxData := authz.GetCtxData(ctx)
|
||||
// ctxData.UserID = ownerID
|
||||
// projectCtx := authz.SetCtxData(ctx, ctxData)
|
||||
//
|
||||
// for _, project := range projects {
|
||||
// createdProject, err := step.project(projectCtx, project)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// step.createdProjects[createdProject.Name] = createdProject
|
||||
// for _, oidc := range project.OIDCApps {
|
||||
// app, err := step.oidcApp(ctx, createdProject, oidc)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application")
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) {
|
||||
// addProject := &proj_model.Project{
|
||||
// Name: project.Name,
|
||||
// }
|
||||
// return step.setup.ProjectEvents.CreateProject(ctx, addProject, false)
|
||||
//}
|
||||
//
|
||||
//func (step *Step1) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) {
|
||||
// addOIDCApp := &proj_model.Application{
|
||||
// ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID},
|
||||
// Name: oidc.Name,
|
||||
// OIDCConfig: &proj_model.OIDCConfig{
|
||||
// RedirectUris: oidc.RedirectUris,
|
||||
// ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes),
|
||||
// GrantTypes: getOIDCGrantTypes(oidc.GrantTypes),
|
||||
// ApplicationType: getOIDCApplicationType(oidc.ApplicationType),
|
||||
// AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType),
|
||||
// PostLogoutRedirectUris: oidc.PostLogoutRedirectUris,
|
||||
// DevMode: oidc.DevMode,
|
||||
// },
|
||||
// }
|
||||
// return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp)
|
||||
//}
|
||||
|
@ -2,11 +2,13 @@ package setup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
"github.com/caos/zitadel/internal/v2/command"
|
||||
)
|
||||
|
||||
type Step2 struct {
|
||||
@ -27,23 +29,25 @@ func (step *Step2) init(setup *Setup) {
|
||||
step.setup = setup
|
||||
}
|
||||
|
||||
func (step *Step2) execute(ctx context.Context) (*iam_model.IAM, error) {
|
||||
iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-Ms9fl").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw complexity policy)")
|
||||
return nil, err
|
||||
}
|
||||
iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step())
|
||||
if err != nil {
|
||||
logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)")
|
||||
return nil, err
|
||||
}
|
||||
err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg)
|
||||
if err != nil {
|
||||
logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup")
|
||||
return nil, err
|
||||
}
|
||||
return iam_es_model.IAMToModel(iam), nil
|
||||
func (step *Step2) execute(ctx context.Context, commands command.CommandSide) error {
|
||||
//commands.SetupStep2(ctx, )
|
||||
//iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy)
|
||||
//if err != nil {
|
||||
// logging.Log("SETUP-Ms9fl").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw complexity policy)")
|
||||
// return nil, err
|
||||
//}
|
||||
//iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step())
|
||||
//if err != nil {
|
||||
// logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)")
|
||||
// return nil, err
|
||||
//}
|
||||
//err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg)
|
||||
//if err != nil {
|
||||
// logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup")
|
||||
// return nil, err
|
||||
//}
|
||||
//return iam_es_model.IAMToModel(iam), nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (step *Step2) passwordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_es_model.IAM, *models.Aggregate, error) {
|
||||
|
@ -17,15 +17,21 @@ Errors:
|
||||
NotLocked: Benutzer ist nicht gesperrt
|
||||
NoChanges: Keine Änderungen gefunden
|
||||
InitCodeNotFound: Kein Initialisierungs Code gefunden
|
||||
ProfileNotFound: Profil nicht gefunden
|
||||
ProfileInvalid: Profildaten sind ungültig
|
||||
EmailNotFound: Email nicht gefunden
|
||||
EmailInvalid: Email ist ungültig
|
||||
EmailAlreadyVerified: Email ist bereits verifiziert
|
||||
Profile:
|
||||
NotFound: Profil nicht gefunden
|
||||
NotChanged: Profile nicht verändert
|
||||
Invalid: Profildaten sind ungültig
|
||||
Email:
|
||||
NotFound: Email nicht gefunden
|
||||
Invalid: Email ist ungültig
|
||||
AlreadyVerified: Email ist bereits verifiziert
|
||||
NotChanged: Email wurde nicht geändert
|
||||
PhoneNotFound: Telfonnummer nicht gefunden
|
||||
PhoneInvalid: Telefonnummer ist ungültig
|
||||
PhoneAlreadyVerified: Telefonnummer bereits verifiziert
|
||||
AddressNotFound: Addresse nicht gefunden
|
||||
Address:
|
||||
NotFound: Addresse nicht gefunden
|
||||
NotChanged: Addresse wurde nicht geändert
|
||||
NotHuman: Der Benutzer muss eine Person sein
|
||||
NotMachine: Der Benutzer muss technisch sein
|
||||
NotAllowedToLink: Der Benutzer darf nicht mit einem externen Login Provider verlinkt werden
|
||||
@ -164,6 +170,8 @@ Errors:
|
||||
GrantHasNotExistingRole: Eine der Rollen existiert nicht auf dem Projekt
|
||||
UserIDMisisng: User ID fehlt
|
||||
IAM:
|
||||
Member:
|
||||
RolesNotChanged: Rollen wurden nicht verändert
|
||||
MemberInvalid: Member ist ungültig
|
||||
MemberAlreadyExisting: Member existiert bereits
|
||||
MemberNotExisting: Member existiert nicht
|
||||
@ -179,6 +187,7 @@ Errors:
|
||||
IdpProviderInvalid: Idp Provider ist ungültig
|
||||
LoginPolicy:
|
||||
NotFound: Default Login Policy konnte nicht gefunden
|
||||
NotChanged: Default Login Policy wurde nicht verändert
|
||||
NotExisting: Default Login Policy existiert nicht
|
||||
AlreadyExists: Default Login Policy existiert bereits
|
||||
IdpProviderAlreadyExisting: Idp Provider existiert bereits
|
||||
@ -187,28 +196,41 @@ Errors:
|
||||
AlreadyExists: Multifaktor existiert bereits
|
||||
NotExisting: Multifaktor existiert nicht
|
||||
Unspecified: Multifaktor ungültig
|
||||
IDP:
|
||||
AlreadyExists: Identitäts Provider existiert bereits
|
||||
NotExisting: Identitäts Provider existiert nicht
|
||||
IDPConfig:
|
||||
AlreadyExists: Identitäts Provider Konfiguration existiert bereits
|
||||
NotExisting: Identitäts Provider Konfiguration existiert nicht
|
||||
NotInactive: Identitäts Provider Konfiguration nicht inaktive
|
||||
NotActive: Identitäts Provider Konfiguration nicht aktive
|
||||
LabelPolicy:
|
||||
NotFound: Default Private Label Policy konnte nicht gefunden
|
||||
NotChanged: Default Private Label Policy wurde nicht verändert
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Default Password Complexity Policy konnte nicht gefunden werden
|
||||
NotExisting: Default Password Complexity Policy existiert nicht
|
||||
AlreadyExists: Default Password Complexity Policy existiert bereits
|
||||
Empty: Default Password Complexity Policy leer
|
||||
NotChanged: Default Password Complexity Policy wurde nicht verändert
|
||||
PasswordAgePolicy:
|
||||
NotFound: Default Password Age Policy konnte nicht gefunden werden
|
||||
NotExisting: Default Password Age Policy existiert nicht
|
||||
AlreadyExists: Default Password Age Policy existiert bereits
|
||||
Empty: Default Password Age Policy leer
|
||||
NotChanged: Default Password Age Policy wurde nicht verändert
|
||||
PasswordLockoutPolicy:
|
||||
NotFound: Default Password Lockout Policy konnte nicht gefunden werden
|
||||
NotExisting: Default Password Lockout Policy existiert nicht
|
||||
AlreadyExists: Default Password Lockout Policy existiert bereits
|
||||
Empty: Default Password Lockout Policy leer
|
||||
NotChanged: Default Password Lockout Policy wurde nicht verändert
|
||||
OrgIAMPolicy:
|
||||
NotFound: Default Org IAM Policy konnte nicht gefunden werden
|
||||
NotExisting: Default Org IAM Policy existiert nicht
|
||||
AlreadyExists: Default Org IAM Policy existiert bereits
|
||||
Empty: Default Org IAM Policy leer
|
||||
NotChanged: Default Org IAM Policy wurde nicht verändert
|
||||
Policy:
|
||||
AlreadyExists: Policy existiert bereits
|
||||
UserGrant:
|
||||
|
@ -17,15 +17,21 @@ Errors:
|
||||
NotLocked: User is not locked
|
||||
NoChanges: No changes found
|
||||
InitCodeNotFound: Initialization Code not found
|
||||
ProfileNotFound: Profile not found
|
||||
ProfileInvalid: Profildata invalid
|
||||
EmailNotFound: Email not found
|
||||
EmailInvalid: Email is invalid
|
||||
EmailAlreadyVerified: Email is alredy verified
|
||||
Profile:
|
||||
NotFound: Profile not found
|
||||
NotChanged: Profile not changed
|
||||
Invalid: Profildata invalid
|
||||
Email:
|
||||
NotFound: Email not found
|
||||
Invalid: Email is invalid
|
||||
AlreadyVerified: Email is alredy verified
|
||||
NotChanged: Email not changed
|
||||
PhoneNotFound: Phone not found
|
||||
PhoneInvalid: Phone is invalid
|
||||
PhoneAlreadyVerified: Phone already verified
|
||||
AddressNotFound: Address not found
|
||||
Address:
|
||||
NotFound: Address not found
|
||||
NotChanged: Address not changed
|
||||
NotHuman: The User must be personal
|
||||
NotMachine: The User must be technical
|
||||
NotAllowedToLink: User is not allowed to link with external login provider
|
||||
@ -164,6 +170,8 @@ Errors:
|
||||
GrantHasNotExistingRole: One role doesn't exist on project
|
||||
UserIDMisisng: User ID missing
|
||||
IAM:
|
||||
Member:
|
||||
RolesNotChanged: Roles habe not been changed
|
||||
MemberInvalid: Member is invalid
|
||||
MemberAlreadyExisting: Member already exists
|
||||
MemberNotExisting: Member does not exist
|
||||
@ -179,6 +187,7 @@ Errors:
|
||||
IdpProviderInvalid: Idp Provider is invalid
|
||||
LoginPolicy:
|
||||
NotFound: Default Login Policy not found
|
||||
NotChanged: Default Login Policy has not been changed
|
||||
NotExisting: Default Login Policy not existig
|
||||
AlreadyExists: Default Login Policy already exists
|
||||
IdpProviderAlreadyExisting: Idp Provider already existing
|
||||
@ -187,28 +196,38 @@ Errors:
|
||||
AlreadyExists: Multifactor already exists
|
||||
NotExisting: Multifactor not existing
|
||||
Unspecified: Multifactor invalid
|
||||
IDPConfig:
|
||||
AlreadyExists: Identity Provider Configuration already exists
|
||||
NotExisting: Identity Provider Configuration doesn't exist
|
||||
NotInactive: Identity Provider Configuration not inactive
|
||||
NotActive: Identity Provider Configuration not active
|
||||
LabelPolicy:
|
||||
NotFound: Default Private Label Policy not found
|
||||
NotChanged: Default Private Label Policy has not been changed
|
||||
PasswordComplexityPolicy:
|
||||
NotFound: Default Private Label Policy not found
|
||||
NotExisting: Default Password Complexity Policy not existing
|
||||
AlreadyExists: Default Password Complexity Policy already existing
|
||||
Empty: Default Password Complexity Policy empty
|
||||
NotChanged: Default Password Complexity Policy has not been changed
|
||||
PasswordAgePolicy:
|
||||
NotFound: Default Password Age Policy not found
|
||||
NotExisting: Default Password Age Policy not existing
|
||||
AlreadyExists: Default Password Age Policy already existing
|
||||
Empty: Default Password Age Policy empty
|
||||
NotChanged: Default Password Age Policy has not been changed
|
||||
PasswordLockoutPolicy:
|
||||
NotFound: Default Password Lockout Policy not found
|
||||
NotExisting: Default Password Lockout Policy not existing
|
||||
AlreadyExists: Default Password Lockout Policy already existing
|
||||
Empty: Default Password Lockout Policy empty
|
||||
NotChanged: Default Password Lockout Policy has not been changed
|
||||
OrgIAMPolicy:
|
||||
NotFound: Org IAM Policy not found
|
||||
Empty: Org IAM Policy is empty
|
||||
NotExisting: Org IAM Policy not existing
|
||||
AlreadyExists: Org IAM Policy already exists
|
||||
NotChanged: Org IAM Policy has not been changed
|
||||
Policy:
|
||||
AlreadyExists: Policy already exists
|
||||
UserGrant:
|
||||
|
@ -2,6 +2,8 @@ package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
@ -11,6 +13,8 @@ import (
|
||||
)
|
||||
|
||||
type Human struct {
|
||||
es_models.ObjectRoot
|
||||
|
||||
*Password
|
||||
*Profile
|
||||
*Email
|
||||
@ -44,6 +48,19 @@ const (
|
||||
GenderDiverse
|
||||
)
|
||||
|
||||
func (u *Human) CheckOrgIAMPolicy(userName string, policy *iam_model.OrgIAMPolicy) error {
|
||||
if policy == nil {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-zSH7j", "Errors.Users.OrgIamPolicyNil")
|
||||
}
|
||||
if policy.UserLoginMustBeDomain && strings.Contains(userName, "@") {
|
||||
return caos_errors.ThrowPreconditionFailed(nil, "MODEL-se4sJ", "Errors.User.EmailAsUsernameNotAllowed")
|
||||
}
|
||||
if !policy.UserLoginMustBeDomain && u.Profile != nil && userName == "" && u.Email != nil {
|
||||
userName = u.EmailAddress
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Human) SetNamesAsDisplayname() {
|
||||
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
|
||||
u.DisplayName = u.FirstName + " " + u.LastName
|
||||
|
@ -862,13 +862,13 @@ func (es *UserEventstore) ProfileByID(ctx context.Context, userID string) (*usr_
|
||||
if user.Profile != nil {
|
||||
return user.Profile, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-dk23f", "Errors.User.ProfileNotFound")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-dk23f", "Errors.User.Profile.NotFound")
|
||||
}
|
||||
|
||||
func (es *UserEventstore) ChangeProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) {
|
||||
profile.SetNamesAsDisplayname()
|
||||
if !profile.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d82i3", "Errors.User.ProfileInvalid")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d82i3", "Errors.User.Profile.Invalid")
|
||||
}
|
||||
user, err := es.HumanByID(ctx, profile.AggregateID)
|
||||
if err != nil {
|
||||
@ -897,12 +897,12 @@ func (es *UserEventstore) EmailByID(ctx context.Context, userID string) (*usr_mo
|
||||
if user.Email != nil {
|
||||
return user.Email, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-dki89", "Errors.User.EmailNotFound")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-dki89", "Errors.User.Email.NotFound")
|
||||
}
|
||||
|
||||
func (es *UserEventstore) ChangeEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) {
|
||||
if !email.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lco09", "Errors.User.EmailInvalid")
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lco09", "Errors.User.Email.Invalid")
|
||||
}
|
||||
user, err := es.HumanByID(ctx, email.AggregateID)
|
||||
if err != nil {
|
||||
@ -975,10 +975,10 @@ func (es *UserEventstore) CreateEmailVerificationCode(ctx context.Context, userI
|
||||
return errors.ThrowPreconditionFailed(nil, "EVENT-E3fbw", "Errors.User.NotInitialised")
|
||||
}
|
||||
if user.Email == nil {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.EmailNotFound")
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.NotFound")
|
||||
}
|
||||
if user.IsEmailVerified {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.EmailAlreadyVerified")
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.AlreadyVerified")
|
||||
}
|
||||
|
||||
emailCode := new(usr_model.EmailCode)
|
||||
@ -1158,7 +1158,7 @@ func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_
|
||||
if user.Address != nil {
|
||||
return user.Address, nil
|
||||
}
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-so9wa", "Errors.User.AddressNotFound")
|
||||
return nil, caos_errs.ThrowNotFound(nil, "EVENT-so9wa", "Errors.User.Address.NotFound")
|
||||
}
|
||||
|
||||
func (es *UserEventstore) ChangeAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) {
|
||||
|
@ -1,280 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/label"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/login"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/login/idpprovider"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
"github.com/caos/zitadel/internal/v2/repository/member"
|
||||
)
|
||||
|
||||
func readModelToIAM(readModel *iam_repo.ReadModel) *model.IAM {
|
||||
return &model.IAM{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel),
|
||||
GlobalOrgID: readModel.GlobalOrgID,
|
||||
IAMProjectID: readModel.ProjectID,
|
||||
SetUpDone: model.Step(readModel.SetUpDone),
|
||||
SetUpStarted: model.Step(readModel.SetUpStarted),
|
||||
Members: readModelToMembers(&readModel.Members),
|
||||
DefaultLabelPolicy: readModelToLabelPolicy(&readModel.DefaultLabelPolicy),
|
||||
DefaultLoginPolicy: readModelToLoginPolicy(&readModel.DefaultLoginPolicy),
|
||||
DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy),
|
||||
DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy),
|
||||
DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy),
|
||||
DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy),
|
||||
IDPs: readModelToIDPConfigs(&readModel.IDPs),
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToMembers(readModel *iam_repo.MembersReadModel) []*model.IAMMember {
|
||||
members := make([]*model.IAMMember, len(readModel.Members))
|
||||
|
||||
for i, member := range readModel.Members {
|
||||
members[i] = &model.IAMMember{
|
||||
ObjectRoot: readModelToObjectRoot(member.ReadModel),
|
||||
Roles: member.Roles,
|
||||
UserID: member.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
return members
|
||||
}
|
||||
|
||||
func readModelToLabelPolicy(readModel *label.ReadModel) *model.LabelPolicy {
|
||||
return &model.LabelPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
PrimaryColor: readModel.PrimaryColor,
|
||||
SecondaryColor: readModel.SecondaryColor,
|
||||
Default: true,
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToLoginPolicy(readModel *login.ReadModel) *model.LoginPolicy {
|
||||
return &model.LoginPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
AllowExternalIdp: readModel.AllowExternalIDP,
|
||||
AllowRegister: readModel.AllowRegister,
|
||||
AllowUsernamePassword: readModel.AllowUserNamePassword,
|
||||
Default: true,
|
||||
//TODO: IDPProviders: []*model.IDPProvider,
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
func readModelToOrgIAMPolicy(readModel *org_iam.ReadModel) *model.OrgIAMPolicy {
|
||||
return &model.OrgIAMPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
UserLoginMustBeDomain: readModel.UserLoginMustBeDomain,
|
||||
Default: true,
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordAgePolicy(readModel *password_age.ReadModel) *model.PasswordAgePolicy {
|
||||
return &model.PasswordAgePolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
ExpireWarnDays: uint64(readModel.ExpireWarnDays),
|
||||
MaxAgeDays: uint64(readModel.MaxAgeDays),
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordComplexityPolicy(readModel *password_complexity.ReadModel) *model.PasswordComplexityPolicy {
|
||||
return &model.PasswordComplexityPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
HasLowercase: readModel.HasLowercase,
|
||||
HasNumber: readModel.HasNumber,
|
||||
HasSymbol: readModel.HasSymbol,
|
||||
HasUppercase: readModel.HasUpperCase,
|
||||
MinLength: uint64(readModel.MinLength),
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
func readModelToPasswordLockoutPolicy(readModel *password_lockout.ReadModel) *model.PasswordLockoutPolicy {
|
||||
return &model.PasswordLockoutPolicy{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel),
|
||||
MaxAttempts: uint64(readModel.MaxAttempts),
|
||||
ShowLockOutFailures: readModel.ShowLockOutFailures,
|
||||
//TODO: State: int32,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToObjectRoot(readModel eventstore.ReadModel) models.ObjectRoot {
|
||||
return models.ObjectRoot{
|
||||
AggregateID: readModel.AggregateID,
|
||||
ChangeDate: readModel.ChangeDate,
|
||||
CreationDate: readModel.CreationDate,
|
||||
ResourceOwner: readModel.ResourceOwner,
|
||||
Sequence: readModel.ProcessedSequence,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToObjectRoot(writeModel eventstore.WriteModel) models.ObjectRoot {
|
||||
return models.ObjectRoot{
|
||||
AggregateID: writeModel.AggregateID,
|
||||
ChangeDate: writeModel.ChangeDate,
|
||||
ResourceOwner: writeModel.ResourceOwner,
|
||||
Sequence: writeModel.ProcessedSequence,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToMember(readModel *member.ReadModel) *model.IAMMember {
|
||||
return &model.IAMMember{
|
||||
ObjectRoot: readModelToObjectRoot(readModel.ReadModel),
|
||||
Roles: readModel.Roles,
|
||||
UserID: readModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToMember(writeModel *iam.MemberWriteModel) *model.IAMMember {
|
||||
return &model.IAMMember{
|
||||
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel.WriteModel),
|
||||
Roles: writeModel.Roles,
|
||||
UserID: writeModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToLoginPolicy(wm *login.WriteModel) *model.LoginPolicy {
|
||||
return &model.LoginPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
AllowUsernamePassword: wm.AllowUserNamePassword,
|
||||
AllowRegister: wm.AllowRegister,
|
||||
AllowExternalIdp: wm.AllowExternalIDP,
|
||||
ForceMFA: wm.ForceMFA,
|
||||
PasswordlessType: model.PasswordlessType(wm.PasswordlessType),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToLabelPolicy(wm *label.WriteModel) *model.LabelPolicy {
|
||||
return &model.LabelPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
PrimaryColor: wm.PrimaryColor,
|
||||
SecondaryColor: wm.SecondaryColor,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToOrgIAMPolicy(wm *org_iam.WriteModel) *model.OrgIAMPolicy {
|
||||
return &model.OrgIAMPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
UserLoginMustBeDomain: wm.UserLoginMustBeDomain,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordAgePolicy(wm *password_age.WriteModel) *model.PasswordAgePolicy {
|
||||
return &model.PasswordAgePolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
MaxAgeDays: wm.MaxAgeDays,
|
||||
ExpireWarnDays: wm.ExpireWarnDays,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordComplexityPolicy(wm *password_complexity.WriteModel) *model.PasswordComplexityPolicy {
|
||||
return &model.PasswordComplexityPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
MinLength: wm.MinLength,
|
||||
HasLowercase: wm.HasLowercase,
|
||||
HasUppercase: wm.HasUpperCase,
|
||||
HasNumber: wm.HasNumber,
|
||||
HasSymbol: wm.HasSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordLockoutPolicy(wm *password_lockout.WriteModel) *model.PasswordLockoutPolicy {
|
||||
return &model.PasswordLockoutPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
MaxAttempts: wm.MaxAttempts,
|
||||
ShowLockOutFailures: wm.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPConfigView(rm *iam.IDPConfigReadModel) *model.IDPConfigView {
|
||||
return &model.IDPConfigView{
|
||||
AggregateID: rm.AggregateID,
|
||||
ChangeDate: rm.ChangeDate,
|
||||
CreationDate: rm.CreationDate,
|
||||
IDPConfigID: rm.ConfigID,
|
||||
IDPProviderType: model.IDPProviderType(rm.ProviderType),
|
||||
IsOIDC: rm.OIDCConfig != nil,
|
||||
Name: rm.Name,
|
||||
OIDCClientID: rm.OIDCConfig.ClientID,
|
||||
OIDCClientSecret: rm.OIDCConfig.ClientSecret,
|
||||
OIDCIDPDisplayNameMapping: model.OIDCMappingField(rm.OIDCConfig.IDPDisplayNameMapping),
|
||||
OIDCIssuer: rm.OIDCConfig.Issuer,
|
||||
OIDCScopes: rm.OIDCConfig.Scopes,
|
||||
OIDCUsernameMapping: model.OIDCMappingField(rm.OIDCConfig.UserNameMapping),
|
||||
Sequence: rm.ProcessedSequence,
|
||||
State: model.IDPConfigState(rm.State),
|
||||
StylingType: model.IDPStylingType(rm.StylingType),
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPConfigs(rm *iam.IDPConfigsReadModel) []*model.IDPConfig {
|
||||
configs := make([]*model.IDPConfig, len(rm.Configs))
|
||||
for i, config := range rm.Configs {
|
||||
configs[i] = readModelToIDPConfig(&iam.IDPConfigReadModel{ConfigReadModel: *config})
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
func readModelToIDPConfig(rm *iam.IDPConfigReadModel) *model.IDPConfig {
|
||||
return &model.IDPConfig{
|
||||
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
|
||||
OIDCConfig: readModelToIDPOIDCConfig(rm.OIDCConfig),
|
||||
IDPConfigID: rm.ConfigID,
|
||||
Name: rm.Name,
|
||||
State: model.IDPConfigState(rm.State),
|
||||
StylingType: model.IDPStylingType(rm.StylingType),
|
||||
}
|
||||
}
|
||||
|
||||
func readModelToIDPOIDCConfig(rm *oidc.ConfigReadModel) *model.OIDCIDPConfig {
|
||||
return &model.OIDCIDPConfig{
|
||||
ObjectRoot: readModelToObjectRoot(rm.ReadModel),
|
||||
ClientID: rm.ClientID,
|
||||
ClientSecret: rm.ClientSecret,
|
||||
ClientSecretString: string(rm.ClientSecret.Crypted),
|
||||
IDPConfigID: rm.IDPConfigID,
|
||||
IDPDisplayNameMapping: model.OIDCMappingField(rm.IDPDisplayNameMapping),
|
||||
Issuer: rm.Issuer,
|
||||
Scopes: rm.Scopes,
|
||||
UsernameMapping: model.OIDCMappingField(rm.UserNameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPConfig(wm *iam.IDPConfigWriteModel) *model.IDPConfig {
|
||||
return &model.IDPConfig{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig),
|
||||
IDPConfigID: wm.ConfigID,
|
||||
Name: wm.Name,
|
||||
State: model.IDPConfigState(wm.State),
|
||||
StylingType: model.IDPStylingType(wm.StylingType),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPOIDCConfig(wm *oidc.ConfigWriteModel) *model.OIDCIDPConfig {
|
||||
return &model.OIDCIDPConfig{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
ClientID: wm.ClientID,
|
||||
IDPConfigID: wm.IDPConfigID,
|
||||
IDPDisplayNameMapping: model.OIDCMappingField(wm.IDPDisplayNameMapping),
|
||||
Issuer: wm.Issuer,
|
||||
Scopes: wm.Scopes,
|
||||
UsernameMapping: model.OIDCMappingField(wm.UserNameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPProvider(wm *idpprovider.WriteModel) *model.IDPProvider {
|
||||
return &model.IDPProvider{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel),
|
||||
IDPConfigID: wm.IDPConfigID,
|
||||
Type: model.IDPProviderType(wm.IDPProviderType),
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
func (r *Repository) IDPConfigByID(ctx context.Context, iamID, idpConfigID string) (*iam_model.IDPConfigView, error) {
|
||||
idpConfig := iam.NewIDPConfigReadModel(iamID, idpConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, idpConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readModelToIDPConfigView(idpConfig), nil
|
||||
}
|
||||
|
||||
func (r *Repository) AddIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
if config.OIDCConfig == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "IAM-eUpQU", "Errors.idp.config.notset")
|
||||
}
|
||||
|
||||
idpConfigID, err := r.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: check name unique on aggregate
|
||||
|
||||
clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.secretCrypto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
writeModel, err := r.pushIDPWriteModel(ctx, config.AggregateID, idpConfigID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate {
|
||||
return a.
|
||||
PushIDPConfigAdded(
|
||||
ctx,
|
||||
idpConfigID,
|
||||
config.Name,
|
||||
idp.ConfigType(config.Type),
|
||||
idp.StylingType(config.StylingType)).
|
||||
PushIDPOIDCConfigAdded(
|
||||
ctx,
|
||||
config.OIDCConfig.ClientID,
|
||||
idpConfigID,
|
||||
config.OIDCConfig.Issuer,
|
||||
clientSecret,
|
||||
oidc.MappingField(config.OIDCConfig.IDPDisplayNameMapping),
|
||||
oidc.MappingField(config.OIDCConfig.UsernameMapping),
|
||||
config.OIDCConfig.Scopes...)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangeIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
writeModel, err := r.pushIDPWriteModel(ctx, config.AggregateID, config.IDPConfigID, func(a *iam.Aggregate, writeModel *iam.IDPConfigWriteModel) *iam.Aggregate {
|
||||
return a.PushIDPConfigChanged(
|
||||
ctx,
|
||||
writeModel,
|
||||
config.IDPConfigID,
|
||||
config.Name,
|
||||
idp.ConfigType(config.Type),
|
||||
idp.StylingType(config.StylingType))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) DeactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate {
|
||||
return a.PushIDPConfigDeactivated(ctx, idpID)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ReactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate {
|
||||
return a.PushIDPConfigReactivated(ctx, idpID)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate {
|
||||
return a.PushIDPConfigRemoved(ctx, idpID)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) pushIDPWriteModel(ctx context.Context, iamID, idpID string, eventSetter func(*iam.Aggregate, *iam.IDPConfigWriteModel) *iam.Aggregate) (*iam.IDPConfigWriteModel, error) {
|
||||
writeModel := iam.NewIDPConfigWriteModel(iamID, idpID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregate := eventSetter(iam.AggregateFromWriteModel(&writeModel.WriteModel), writeModel)
|
||||
err = r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idp/oidc"
|
||||
)
|
||||
|
||||
func (r *Repository) ChangeIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) {
|
||||
writeModel := iam.NewIDPOIDCConfigWriteModel(config.AggregateID, config.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var clientSecret *crypto.CryptoValue
|
||||
if config.ClientSecretString != "" {
|
||||
clientSecret, err = crypto.Crypt([]byte(config.ClientSecretString), r.secretCrypto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
aggregate := iam.AggregateFromWriteModel(&writeModel.WriteModel).
|
||||
PushIDPOIDCConfigChanged(
|
||||
ctx,
|
||||
writeModel,
|
||||
config.ClientID,
|
||||
config.Issuer,
|
||||
clientSecret,
|
||||
oidc.MappingField(config.IDPDisplayNameMapping),
|
||||
oidc.MappingField(config.UsernameMapping),
|
||||
config.Scopes...)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPOIDCConfig(&writeModel.ConfigWriteModel), nil
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam"
|
||||
)
|
||||
|
||||
func (r *Repository) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
addedPolicy := org_iam.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToOrgIAMPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushOrgIAMPolicyChangedFromExisting(ctx, existingPolicy, policy.UserLoginMustBeDomain)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToOrgIAMPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) orgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *org_iam.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := org_iam.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/label"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func (r *Repository) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LabelPolicyInvalid")
|
||||
}
|
||||
|
||||
addedPolicy := label.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLabelPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LabelPolicyInvalid")
|
||||
}
|
||||
|
||||
existingPolicy, err := r.labelPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushLabelPolicyChangedFromExisting(ctx, existingPolicy, policy.PrimaryColor, policy.SecondaryColor)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLabelPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) labelPolicyWriteModelByID(ctx context.Context, iamID string) (policy *label.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := label.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
iam_login "github.com/caos/zitadel/internal/v2/repository/iam/policy/login"
|
||||
iam_factor "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/factors"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/login/idpprovider"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy/login"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy/login/factors"
|
||||
idpprovider2 "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider"
|
||||
)
|
||||
|
||||
func (r *Repository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LoginPolicyInvalid")
|
||||
}
|
||||
|
||||
addedPolicy := iam_login.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, login.PasswordlessType(policy.PasswordlessType))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLoginPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LoginPolicyInvalid")
|
||||
}
|
||||
|
||||
existingPolicy, err := r.loginPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushLoginPolicyChangedFromExisting(ctx, existingPolicy, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, login.PasswordlessType(policy.PasswordlessType))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLoginPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) AddIDPProviderToLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) {
|
||||
writeModel := idpprovider.NewWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.WriteModel.WriteModel).
|
||||
PushLoginPolicyIDPProviderAddedEvent(ctx, idpProvider.IDPConfigID, idpprovider2.Type(idpProvider.Type))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPProvider(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) error {
|
||||
writeModel := idpprovider.NewWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.WriteModel.WriteModel).
|
||||
PushLoginPolicyIDPProviderAddedEvent(ctx, idpProvider.IDPConfigID, idpprovider2.Type(idpProvider.Type))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
}
|
||||
|
||||
func (r *Repository) AddSecondFactorToLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) {
|
||||
writeModel := iam_factor.NewSecondFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return iam_model.SecondFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.SecondFactorWriteModel.WriteModel).
|
||||
PushLoginPolicySecondFactorAdded(ctx, factors.SecondFactorType(secondFactor))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil {
|
||||
return iam_model.SecondFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
return iam_model.SecondFactorType(writeModel.MFAType), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) error {
|
||||
writeModel := iam_factor.NewSecondFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.SecondFactorWriteModel.WriteModel).
|
||||
PushLoginPolicySecondFactorRemoved(ctx, factors.SecondFactorType(secondFactor))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
}
|
||||
|
||||
func (r *Repository) AddMultiFactorToLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) {
|
||||
writeModel := iam_factor.NewMultiFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return iam_model.MultiFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.MultiFactoryWriteModel.WriteModel).
|
||||
PushLoginPolicyMultiFactorAdded(ctx, factors.MultiFactorType(secondFactor))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil {
|
||||
return iam_model.MultiFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
return iam_model.MultiFactorType(writeModel.MultiFactoryWriteModel.MFAType), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.MultiFactorType) error {
|
||||
writeModel := iam_factor.NewMultiFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aggregate := iam_repo.AggregateFromWriteModel(&writeModel.MultiFactoryWriteModel.WriteModel).
|
||||
PushLoginPolicyMultiFactorRemoved(ctx, factors.MultiFactorType(secondFactor))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
}
|
||||
|
||||
func (r *Repository) loginPolicyWriteModelByID(ctx context.Context, iamID string) (policy *iam_login.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := iam_login.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age"
|
||||
)
|
||||
|
||||
func (r *Repository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
addedPolicy := password_age.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-6L0pd", "Errors.IAM.PasswordAgePolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordAgePolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
existingPolicy, err := r.passwordAgePolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushPasswordAgePolicyChangedFromExisting(ctx, existingPolicy, policy.ExpireWarnDays, policy.MaxAgeDays)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordAgePolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) passwordAgePolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_age.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := password_age.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity"
|
||||
)
|
||||
|
||||
func (r *Repository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
if err := policy.IsValid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addedPolicy := password_complexity.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordComplexityPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
if err := policy.IsValid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingPolicy, err := r.passwordComplexityPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushPasswordComplexityPolicyChangedFromExisting(ctx, existingPolicy, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordComplexityPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) passwordComplexityPolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_complexity.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := password_complexity.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout"
|
||||
)
|
||||
|
||||
func (r *Repository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
addedPolicy := password_lockout.NewWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy != nil {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel).
|
||||
PushPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordLockoutPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
existingPolicy, err := r.passwordLockoutPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel).
|
||||
PushPasswordLockoutPolicyChangedFromExisting(ctx, existingPolicy, policy.MaxAttempts, policy.ShowLockOutFailures)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordLockoutPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *Repository) passwordLockoutPolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_lockout.WriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := password_lockout.NewWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package iam
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *Repository) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepStartedEvent(ctx, iam_repo.Step(step)))
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
}
|
||||
return iam, nil
|
||||
}
|
||||
|
||||
func (r *Repository) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||
iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepDoneEvent(ctx, iam_repo.Step(step)))
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed")
|
||||
}
|
||||
return iam, nil
|
||||
}
|
||||
|
||||
func (r *Repository) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) {
|
||||
iam, err := r.iamByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
|
||||
}
|
||||
|
||||
aggregate := iam_repo.AggregateFromReadModel(iam).
|
||||
PushEvents(event)
|
||||
|
||||
events, err := r.eventstore.PushAggregates(ctx, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = iam.AppendAndReduce(events...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return readModelToIAM(iam), nil
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Eventstore *eventstore.Eventstore
|
||||
}
|
||||
|
||||
func StartRepository(config *Config) *Repository {
|
||||
return &Repository{
|
||||
eventstore: config.Eventstore,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repository) GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) RemoveLoginPolicy(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
func (r *Repository) SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) RemovePasswordComplexityPolicy(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) RemovePasswordAgePolicy(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *Repository) RemovePasswordLockoutPolicy(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
72
internal/v2/command/command.go
Normal file
72
internal/v2/command/command.go
Normal file
@ -0,0 +1,72 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type CommandSide struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
idGenerator id.Generator
|
||||
iamID string
|
||||
|
||||
idpConfigSecretCrypto crypto.Crypto
|
||||
|
||||
userPasswordAlg crypto.HashAlgorithm
|
||||
initializeUserCode crypto.Generator
|
||||
emailVerificationCode crypto.Generator
|
||||
phoneVerificationCode crypto.Generator
|
||||
passwordVerificationCode crypto.Generator
|
||||
machineKeyAlg crypto.EncryptionAlgorithm
|
||||
machineKeySize int
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Eventstore *eventstore.Eventstore
|
||||
SystemDefaults sd.SystemDefaults
|
||||
}
|
||||
|
||||
func StartCommandSide(config *Config) (repo *CommandSide, err error) {
|
||||
repo = &CommandSide{
|
||||
eventstore: config.Eventstore,
|
||||
idGenerator: id.SonyFlakeGenerator,
|
||||
iamID: config.SystemDefaults.IamID,
|
||||
}
|
||||
iam_repo.RegisterEventMappers(repo.eventstore)
|
||||
|
||||
repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aesCrypto, err := crypto.NewAESCrypto(config.SystemDefaults.UserVerificationKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo.initializeUserCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.InitializeUserCode, aesCrypto)
|
||||
repo.emailVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.EmailVerificationCode, aesCrypto)
|
||||
repo.phoneVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PhoneVerificationCode, aesCrypto)
|
||||
repo.passwordVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto)
|
||||
repo.userPasswordAlg = crypto.NewBCrypt(config.SystemDefaults.SecretGenerators.PasswordSaltCost)
|
||||
repo.machineKeyAlg = aesCrypto
|
||||
repo.machineKeySize = int(config.SystemDefaults.SecretGenerators.MachineKeySize)
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) iamByID(ctx context.Context, id string) (_ *IAMWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMriteModel(id)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
118
internal/v2/command/iam_converter.go
Normal file
118
internal/v2/command/iam_converter.go
Normal file
@ -0,0 +1,118 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func writeModelToObjectRoot(writeModel eventstore.WriteModel) models.ObjectRoot {
|
||||
return models.ObjectRoot{
|
||||
AggregateID: writeModel.AggregateID,
|
||||
ChangeDate: writeModel.ChangeDate,
|
||||
ResourceOwner: writeModel.ResourceOwner,
|
||||
Sequence: writeModel.ProcessedSequence,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIAM(wm *IAMWriteModel) *model.IAM {
|
||||
return &model.IAM{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
SetUpStarted: wm.SetUpStarted,
|
||||
SetUpDone: wm.SetUpDone,
|
||||
GlobalOrgID: wm.GlobalOrgID,
|
||||
IAMProjectID: wm.ProjectID,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToMember(writeModel *IAMMemberWriteModel) *model.IAMMember {
|
||||
return &model.IAMMember{
|
||||
ObjectRoot: writeModelToObjectRoot(writeModel.MemberWriteModel.WriteModel),
|
||||
Roles: writeModel.Roles,
|
||||
UserID: writeModel.UserID,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToLoginPolicy(wm *IAMLoginPolicyWriteModel) *model.LoginPolicy {
|
||||
return &model.LoginPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.LoginPolicyWriteModel.WriteModel),
|
||||
AllowUsernamePassword: wm.AllowUserNamePassword,
|
||||
AllowRegister: wm.AllowRegister,
|
||||
AllowExternalIdp: wm.AllowExternalIDP,
|
||||
ForceMFA: wm.ForceMFA,
|
||||
PasswordlessType: model.PasswordlessType(wm.PasswordlessType),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToLabelPolicy(wm *IAMLabelPolicyWriteModel) *model.LabelPolicy {
|
||||
return &model.LabelPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.LabelPolicyWriteModel.WriteModel),
|
||||
PrimaryColor: wm.PrimaryColor,
|
||||
SecondaryColor: wm.SecondaryColor,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToOrgIAMPolicy(wm *IAMOrgIAMPolicyWriteModel) *model.OrgIAMPolicy {
|
||||
return &model.OrgIAMPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel),
|
||||
UserLoginMustBeDomain: wm.UserLoginMustBeDomain,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordAgePolicy(wm *IAMPasswordAgePolicyWriteModel) *model.PasswordAgePolicy {
|
||||
return &model.PasswordAgePolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PasswordAgePolicyWriteModel.WriteModel),
|
||||
MaxAgeDays: wm.MaxAgeDays,
|
||||
ExpireWarnDays: wm.ExpireWarnDays,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordComplexityPolicy(wm *IAMPasswordComplexityPolicyWriteModel) *model.PasswordComplexityPolicy {
|
||||
return &model.PasswordComplexityPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PasswordComplexityPolicyWriteModel.WriteModel),
|
||||
MinLength: wm.MinLength,
|
||||
HasLowercase: wm.HasLowercase,
|
||||
HasUppercase: wm.HasUpperCase,
|
||||
HasNumber: wm.HasNumber,
|
||||
HasSymbol: wm.HasSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToPasswordLockoutPolicy(wm *IAMPasswordLockoutPolicyWriteModel) *model.PasswordLockoutPolicy {
|
||||
return &model.PasswordLockoutPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PasswordLockoutPolicyWriteModel.WriteModel),
|
||||
MaxAttempts: wm.MaxAttempts,
|
||||
ShowLockOutFailures: wm.ShowLockOutFailures,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPConfig(wm *IAMIDPConfigWriteModel) *model.IDPConfig {
|
||||
return &model.IDPConfig{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig),
|
||||
IDPConfigID: wm.ConfigID,
|
||||
Name: wm.Name,
|
||||
State: model.IDPConfigState(wm.State),
|
||||
StylingType: model.IDPStylingType(wm.StylingType),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPOIDCConfig(wm *OIDCConfigWriteModel) *model.OIDCIDPConfig {
|
||||
return &model.OIDCIDPConfig{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
ClientID: wm.ClientID,
|
||||
IDPConfigID: wm.IDPConfigID,
|
||||
IDPDisplayNameMapping: model.OIDCMappingField(wm.IDPDisplayNameMapping),
|
||||
Issuer: wm.Issuer,
|
||||
Scopes: wm.Scopes,
|
||||
UsernameMapping: model.OIDCMappingField(wm.UserNameMapping),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToIDPProvider(wm *IAMIdentityProviderWriteModel) *model.IDPProvider {
|
||||
return &model.IDPProvider{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.IdentityProviderWriteModel.WriteModel),
|
||||
IDPConfigID: wm.IDPConfigID,
|
||||
Type: model.IDPProviderType(wm.IDPProviderType),
|
||||
}
|
||||
}
|
159
internal/v2/command/iam_idp_config.go
Normal file
159
internal/v2/command/iam_idp_config.go
Normal file
@ -0,0 +1,159 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
if config.OIDCConfig == nil {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "IAM-eUpQU", "Errors.idp.config.notset")
|
||||
}
|
||||
|
||||
idpConfigID, err := r.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//TODO: check name unique on aggregate
|
||||
addedConfig := NewIAMIDPConfigWriteModel(config.AggregateID, idpConfigID)
|
||||
|
||||
clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.idpConfigSecretCrypto)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedConfig.WriteModel)
|
||||
iamAgg.PushEvents(
|
||||
iam_repo.NewIDPConfigAddedEvent(
|
||||
ctx,
|
||||
idpConfigID,
|
||||
config.Name,
|
||||
domain.IDPConfigType(config.Type),
|
||||
domain.IDPConfigStylingType(config.StylingType),
|
||||
),
|
||||
)
|
||||
iamAgg.PushEvents(
|
||||
iam_repo.NewIDPOIDCConfigAddedEvent(
|
||||
ctx, config.OIDCConfig.ClientID,
|
||||
idpConfigID,
|
||||
config.OIDCConfig.Issuer,
|
||||
clientSecret,
|
||||
domain.OIDCMappingField(config.OIDCConfig.IDPDisplayNameMapping),
|
||||
domain.OIDCMappingField(config.OIDCConfig.UsernameMapping),
|
||||
config.OIDCConfig.Scopes...,
|
||||
),
|
||||
)
|
||||
err = r.eventstore.PushAggregate(ctx, addedConfig, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(addedConfig), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, config.AggregateID, config.IDPConfigID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotExisting")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, config.IDPConfigID, config.Name, domain.IDPConfigStylingType(config.StylingType))
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, iamID, idpID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIDPConfigDeactivatedEvent(ctx, idpID))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, iamID, idpID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingIDP.State != domain.IDPConfigStateInactive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-5Mo0d", "Errors.IAM.IDPConfig.NotInactive")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIDPConfigReactivatedEvent(ctx, idpID))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(existingIDP), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) {
|
||||
writeModel, err := r.pushDefaultIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *IAMIDPConfigWriteModel) *iam.Aggregate {
|
||||
a.Aggregate = *a.PushEvents(iam_repo.NewIDPConfigRemovedEvent(ctx, idpID))
|
||||
return a
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPConfig(writeModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) pushDefaultIDPWriteModel(ctx context.Context, iamID, idpID string, eventSetter func(*iam.Aggregate, *IAMIDPConfigWriteModel) *iam.Aggregate) (*IAMIDPConfigWriteModel, error) {
|
||||
writeModel := NewIAMIDPConfigWriteModel(iamID, idpID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aggregate := eventSetter(IAMAggregateFromWriteModel(&writeModel.WriteModel), writeModel)
|
||||
err = r.eventstore.PushAggregate(ctx, writeModel, aggregate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModel, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) iamIDPConfigWriteModelByID(ctx context.Context, iamID, idpID string) (policy *IAMIDPConfigWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMIDPConfigWriteModel(iamID, idpID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
100
internal/v2/command/iam_idp_config_model.go
Normal file
100
internal/v2/command/iam_idp_config_model.go
Normal file
@ -0,0 +1,100 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMIDPConfigWriteModel struct {
|
||||
IDPConfigWriteModel
|
||||
}
|
||||
|
||||
func NewIAMIDPConfigWriteModel(iamID, configID string) *IAMIDPConfigWriteModel {
|
||||
return &IAMIDPConfigWriteModel{
|
||||
IDPConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
ConfigID: configID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.IDPConfigAddedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigAddedEvent)
|
||||
case *iam.IDPConfigChangedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigChangedEvent)
|
||||
case *iam.IDPConfigDeactivatedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent)
|
||||
case *iam.IDPConfigReactivatedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent)
|
||||
case *iam.IDPConfigRemovedEvent:
|
||||
if wm.ConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent)
|
||||
case *iam.IDPOIDCConfigAddedEvent:
|
||||
if wm.ConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent)
|
||||
case *iam.IDPOIDCConfigChangedEvent:
|
||||
if wm.ConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMIDPConfigWriteModel) Reduce() error {
|
||||
return wm.IDPConfigWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventReader) error {
|
||||
wm.AppendEvents(events...)
|
||||
return wm.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
configID,
|
||||
name string,
|
||||
stylingType domain.IDPConfigStylingType,
|
||||
) (*iam.IDPConfigChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewIDPConfigChangedEvent(ctx)
|
||||
changedEvent.ConfigID = configID
|
||||
if wm.Name != name {
|
||||
hasChanged = true
|
||||
changedEvent.Name = name
|
||||
}
|
||||
if stylingType.Valid() && wm.StylingType != stylingType {
|
||||
hasChanged = true
|
||||
changedEvent.StylingType = stylingType
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
47
internal/v2/command/iam_idp_oidc_config.go
Normal file
47
internal/v2/command/iam_idp_oidc_config.go
Normal file
@ -0,0 +1,47 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) {
|
||||
existingConfig := NewIDPOIDCConfigWriteModel(config.AggregateID, config.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, existingConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existingConfig.State == domain.IDPConfigStateRemoved || existingConfig.State == domain.IDPConfigStateUnspecified {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-67J9d", "Errors.IAM.IDPConfig.AlreadyExists")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged, err := existingConfig.NewChangedEvent(
|
||||
ctx,
|
||||
config.ClientID,
|
||||
config.Issuer,
|
||||
config.ClientSecretString,
|
||||
r.idpConfigSecretCrypto,
|
||||
domain.OIDCMappingField(config.IDPDisplayNameMapping),
|
||||
domain.OIDCMappingField(config.UsernameMapping),
|
||||
config.Scopes...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingConfig.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingConfig, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPOIDCConfig(&existingConfig.OIDCConfigWriteModel), nil
|
||||
}
|
115
internal/v2/command/iam_idp_oidc_config_model.go
Normal file
115
internal/v2/command/iam_idp_oidc_config_model.go
Normal file
@ -0,0 +1,115 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type IDPOIDCConfigWriteModel struct {
|
||||
OIDCConfigWriteModel
|
||||
}
|
||||
|
||||
func NewIDPOIDCConfigWriteModel(iamID, idpConfigID string) *IDPOIDCConfigWriteModel {
|
||||
return &IDPOIDCConfigWriteModel{
|
||||
OIDCConfigWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
IDPConfigID: idpConfigID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.IDPOIDCConfigAddedEvent:
|
||||
if wm.IDPConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent)
|
||||
case *iam.IDPOIDCConfigChangedEvent:
|
||||
if wm.IDPConfigID != e.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent)
|
||||
case *iam.IDPConfigReactivatedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent)
|
||||
case *iam.IDPConfigDeactivatedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent)
|
||||
case *iam.IDPConfigRemovedEvent:
|
||||
if wm.IDPConfigID != e.ConfigID {
|
||||
continue
|
||||
}
|
||||
wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent)
|
||||
default:
|
||||
wm.OIDCConfigWriteModel.AppendEvents(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Reduce() error {
|
||||
if err := wm.OIDCConfigWriteModel.Reduce(); err != nil {
|
||||
return err
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
clientID,
|
||||
issuer,
|
||||
clientSecretString string,
|
||||
secretCrypto crypto.Crypto,
|
||||
idpDisplayNameMapping,
|
||||
userNameMapping domain.OIDCMappingField,
|
||||
scopes ...string,
|
||||
) (*iam.IDPOIDCConfigChangedEvent, bool, error) {
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewIDPOIDCConfigChangedEvent(ctx)
|
||||
var clientSecret *crypto.CryptoValue
|
||||
var err error
|
||||
if clientSecretString != "" {
|
||||
clientSecret, err = crypto.Crypt([]byte(clientSecretString), secretCrypto)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
changedEvent.ClientSecret = clientSecret
|
||||
}
|
||||
if wm.ClientID != clientID {
|
||||
hasChanged = true
|
||||
changedEvent.ClientID = clientID
|
||||
}
|
||||
if wm.Issuer != issuer {
|
||||
hasChanged = true
|
||||
changedEvent.Issuer = issuer
|
||||
}
|
||||
if idpDisplayNameMapping.Valid() && wm.IDPDisplayNameMapping != idpDisplayNameMapping {
|
||||
hasChanged = true
|
||||
changedEvent.IDPDisplayNameMapping = idpDisplayNameMapping
|
||||
}
|
||||
if userNameMapping.Valid() && wm.UserNameMapping != userNameMapping {
|
||||
hasChanged = true
|
||||
changedEvent.UserNameMapping = userNameMapping
|
||||
}
|
||||
if reflect.DeepEqual(wm.Scopes, scopes) {
|
||||
hasChanged = true
|
||||
changedEvent.Scopes = scopes
|
||||
}
|
||||
return changedEvent, hasChanged, nil
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package iam
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
@ -10,14 +11,14 @@ import (
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
func (r *CommandSide) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//TODO: check if roles valid
|
||||
|
||||
if !member.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid")
|
||||
}
|
||||
|
||||
addedMember := iam_repo.NewMemberWriteModel(member.AggregateID, member.UserID)
|
||||
addedMember := NewIAMMemberWriteModel(member.AggregateID, member.UserID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -26,8 +27,8 @@ func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember)
|
||||
return nil, errors.ThrowAlreadyExists(nil, "IAM-PtXi1", "Errors.IAM.Member.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedMember.WriteModel.WriteModel).
|
||||
PushMemberAdded(ctx, member.UserID, member.Roles...)
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg)
|
||||
if err != nil {
|
||||
@ -37,23 +38,26 @@ func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember)
|
||||
return writeModelToMember(addedMember), nil
|
||||
}
|
||||
|
||||
//ChangeMember updates an existing member
|
||||
func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//ChangeIAMMember updates an existing member
|
||||
func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||
//TODO: check if roles valid
|
||||
|
||||
if !member.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid")
|
||||
}
|
||||
|
||||
existingMember, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||
existingMember, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam := iam_repo.AggregateFromWriteModel(&existingMember.WriteModel.WriteModel).
|
||||
PushMemberChangedFromExisting(ctx, existingMember, member.Roles...)
|
||||
if reflect.DeepEqual(existingMember.Roles, member.Roles) {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.Member.RolesNotChanged")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewMemberChangedEvent(ctx, member.UserID, member.Roles...))
|
||||
|
||||
events, err := r.eventstore.PushAggregates(ctx, iam)
|
||||
events, err := r.eventstore.PushAggregates(ctx, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -66,8 +70,8 @@ func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMemb
|
||||
return writeModelToMember(existingMember), nil
|
||||
}
|
||||
|
||||
func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMember) error {
|
||||
m, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||
func (r *CommandSide) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error {
|
||||
m, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@ -75,30 +79,17 @@ func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMemb
|
||||
return nil
|
||||
}
|
||||
|
||||
iamAgg := iam_repo.AggregateFromWriteModel(&m.WriteModel.WriteModel).
|
||||
PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID))
|
||||
iamAgg := IAMAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, m, iamAgg)
|
||||
}
|
||||
|
||||
func (r *Repository) MemberByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberReadModel, err error) {
|
||||
func (r *CommandSide) iamMemberWriteModelByID(ctx context.Context, iamID, userID string) (member *IAMMemberWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
member = iam_repo.NewMemberReadModel(iamID, userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, member)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return member, nil
|
||||
}
|
||||
|
||||
func (r *Repository) memberWriteModelByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := iam_repo.NewMemberWriteModel(iamID, userID)
|
||||
writeModel := NewIAMMemberWriteModel(iamID, userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
52
internal/v2/command/iam_member_model.go
Normal file
52
internal/v2/command/iam_member_model.go
Normal file
@ -0,0 +1,52 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMMemberWriteModel struct {
|
||||
MemberWriteModel
|
||||
}
|
||||
|
||||
func NewIAMMemberWriteModel(iamID, userID string) *IAMMemberWriteModel {
|
||||
return &IAMMemberWriteModel{
|
||||
MemberWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
UserID: userID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMMemberWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.MemberAddedEvent:
|
||||
if e.UserID != wm.MemberWriteModel.UserID {
|
||||
continue
|
||||
}
|
||||
wm.MemberWriteModel.AppendEvents(&e.MemberAddedEvent)
|
||||
case *iam.MemberChangedEvent:
|
||||
if e.UserID != wm.MemberWriteModel.UserID {
|
||||
continue
|
||||
}
|
||||
wm.MemberWriteModel.AppendEvents(&e.MemberChangedEvent)
|
||||
case *iam.MemberRemovedEvent:
|
||||
if e.UserID != wm.MemberWriteModel.UserID {
|
||||
continue
|
||||
}
|
||||
wm.MemberWriteModel.AppendEvents(&e.MemberRemovedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMMemberWriteModel) Reduce() error {
|
||||
return wm.MemberWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.MemberWriteModel.AggregateID)
|
||||
}
|
77
internal/v2/command/iam_model.go
Normal file
77
internal/v2/command/iam_model.go
Normal file
@ -0,0 +1,77 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
SetUpStarted domain.Step
|
||||
SetUpDone domain.Step
|
||||
|
||||
GlobalOrgID string
|
||||
ProjectID string
|
||||
}
|
||||
|
||||
func NewIAMriteModel(iamID string) *IAMWriteModel {
|
||||
return &IAMWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
wm.WriteModel.AppendEvents(events...)
|
||||
//for _, event := range events {
|
||||
// switch e := event.(type) {
|
||||
// case *iam.LabelPolicyAddedEvent:
|
||||
// wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyAddedEvent)
|
||||
// case *iam.LabelPolicyChangedEvent:
|
||||
// wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyChangedEvent)
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
func (wm *IAMWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *iam.ProjectSetEvent:
|
||||
wm.ProjectID = e.ProjectID
|
||||
case *iam.GlobalOrgSetEvent:
|
||||
wm.GlobalOrgID = e.OrgID
|
||||
case *iam.SetupStepEvent:
|
||||
if e.Done {
|
||||
wm.SetUpDone = e.Step
|
||||
} else {
|
||||
wm.SetUpStarted = e.Step
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wm *IAMWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.AggregateID)
|
||||
}
|
||||
|
||||
//
|
||||
//func (wm *IAMLabelPolicyWriteModel) HasChanged(primaryColor, secondaryColor string) bool {
|
||||
// if primaryColor != "" && wm.PrimaryColor != primaryColor {
|
||||
// return true
|
||||
// }
|
||||
// if secondaryColor != "" && wm.SecondaryColor != secondaryColor {
|
||||
// return true
|
||||
// }
|
||||
// return false
|
||||
//}
|
||||
|
||||
func IAMAggregateFromWriteModel(wm *eventstore.WriteModel) *iam.Aggregate {
|
||||
return &iam.Aggregate{
|
||||
Aggregate: *eventstore.AggregateFromWriteModel(wm, iam.AggregateType, iam.AggregateVersion),
|
||||
}
|
||||
}
|
76
internal/v2/command/iam_policy_label.go
Normal file
76
internal/v2/command/iam_policy_label.go
Normal file
@ -0,0 +1,76 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LabelPolicyInvalid")
|
||||
}
|
||||
|
||||
addedPolicy := NewIAMLabelPolicyWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLabelPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LabelPolicyInvalid")
|
||||
}
|
||||
|
||||
existingPolicy, err := r.defaultLabelPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0K9dq", "Errors.IAM.LabelPolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLabelPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultLabelPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLabelPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMLabelPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
60
internal/v2/command/iam_policy_label_model.go
Normal file
60
internal/v2/command/iam_policy_label_model.go
Normal file
@ -0,0 +1,60 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMLabelPolicyWriteModel struct {
|
||||
LabelPolicyWriteModel
|
||||
}
|
||||
|
||||
func NewIAMLabelPolicyWriteModel(iamID string) *IAMLabelPolicyWriteModel {
|
||||
return &IAMLabelPolicyWriteModel{
|
||||
LabelPolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMLabelPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.LabelPolicyAddedEvent:
|
||||
wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyAddedEvent)
|
||||
case *iam.LabelPolicyChangedEvent:
|
||||
wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMLabelPolicyWriteModel) Reduce() error {
|
||||
return wm.LabelPolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMLabelPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.LabelPolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMLabelPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
primaryColor,
|
||||
secondaryColor string,
|
||||
) (*iam.LabelPolicyChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewLabelPolicyChangedEvent(ctx)
|
||||
if wm.PrimaryColor != primaryColor {
|
||||
hasChanged = true
|
||||
changedEvent.PrimaryColor = primaryColor
|
||||
}
|
||||
if wm.SecondaryColor != secondaryColor {
|
||||
hasChanged = true
|
||||
changedEvent.SecondaryColor = secondaryColor
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
183
internal/v2/command/iam_policy_login.go
Normal file
183
internal/v2/command/iam_policy_login.go
Normal file
@ -0,0 +1,183 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
addedPolicy := NewIAMLoginPolicyWriteModel(policy.AggregateID)
|
||||
iamAgg, err := r.addDefaultLoginPolicy(ctx, addedPolicy, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLoginPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, addedPolicy *IAMLoginPolicyWriteModel, policy *iam_model.LoginPolicy) (*iam_repo.Aggregate, error) {
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LoginPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, domain.PasswordlessType(policy.PasswordlessType)))
|
||||
|
||||
return iamAgg, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||
if !policy.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LoginPolicyInvalid")
|
||||
}
|
||||
|
||||
existingPolicy, err := r.defaultLoginPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-M0sif", "Errors.IAM.LoginPolicy.NotFound")
|
||||
}
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, domain.PasswordlessType(policy.PasswordlessType))
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToLoginPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) {
|
||||
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, idpModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if idpModel.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.IDP.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&idpModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIdentityProviderAddedEvent(ctx, idpProvider.IDPConfigID, domain.IdentityProviderType(idpProvider.Type)))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, idpModel, iamAgg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToIDPProvider(idpModel), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) error {
|
||||
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, idpModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !idpModel.IsActive {
|
||||
return caos_errs.ThrowAlreadyExists(nil, "IAM-39fjs", "Errors.IAM.LoginPolicy.IDP.NotExisting")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&idpModel.IdentityProviderWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewIdentityProviderRemovedEvent(ctx, idpProvider.IDPConfigID))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, idpModel, iamAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) {
|
||||
secondFactorModel := NewIAMSecondFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel)
|
||||
if err != nil {
|
||||
return iam_model.SecondFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
if secondFactorModel.IsActive {
|
||||
return iam_model.SecondFactorTypeUnspecified, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.MFA.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorAddedEvent(ctx, domain.SecondFactorType(secondFactor)))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg); err != nil {
|
||||
return iam_model.SecondFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
return iam_model.SecondFactorType(secondFactorModel.MFAType), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) error {
|
||||
secondFactorModel := NewIAMSecondFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !secondFactorModel.IsActive {
|
||||
return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.NotExisting")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorRemovedEvent(ctx, domain.SecondFactorType(secondFactor)))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, iamID string, multiFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) {
|
||||
multiFactorModel := NewIAMMultiFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel)
|
||||
if err != nil {
|
||||
return iam_model.MultiFactorTypeUnspecified, err
|
||||
}
|
||||
if multiFactorModel.IsActive {
|
||||
return iam_model.MultiFactorTypeUnspecified, caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.AlreadyExists")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorAddedEvent(ctx, domain.MultiFactorType(multiFactor)))
|
||||
|
||||
if err = r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg); err != nil {
|
||||
return iam_model.MultiFactorTypeUnspecified, err
|
||||
}
|
||||
|
||||
return iam_model.MultiFactorType(multiFactorModel.MultiFactoryWriteModel.MFAType), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, iamID string, multiFactor iam_model.MultiFactorType) error {
|
||||
multiFactorModel := NewIAMMultiFactorWriteModel(iamID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if multiFactorModel.IsActive {
|
||||
return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9df", "Errors.IAM.LoginPolicy.MFA.NotExisting")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorRemovedEvent(ctx, domain.MultiFactorType(multiFactor)))
|
||||
|
||||
return r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg)
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultLoginPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLoginPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMLoginPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
70
internal/v2/command/iam_policy_login_factors_model.go
Normal file
70
internal/v2/command/iam_policy_login_factors_model.go
Normal file
@ -0,0 +1,70 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMSecondFactorWriteModel struct {
|
||||
SecondFactorWriteModel
|
||||
}
|
||||
|
||||
func NewIAMSecondFactorWriteModel(iamID string) *IAMSecondFactorWriteModel {
|
||||
return &IAMSecondFactorWriteModel{
|
||||
SecondFactorWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMSecondFactorWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.LoginPolicySecondFactorAddedEvent:
|
||||
wm.WriteModel.AppendEvents(&e.SecondFactorAddedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMSecondFactorWriteModel) Reduce() error {
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMSecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.WriteModel.AggregateID)
|
||||
}
|
||||
|
||||
type IAMMultiFactorWriteModel struct {
|
||||
MultiFactoryWriteModel
|
||||
}
|
||||
|
||||
func NewIAMMultiFactorWriteModel(iamID string) *IAMMultiFactorWriteModel {
|
||||
return &IAMMultiFactorWriteModel{
|
||||
MultiFactoryWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMMultiFactorWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.LoginPolicyMultiFactorAddedEvent:
|
||||
wm.WriteModel.AppendEvents(&e.MultiFactorAddedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMMultiFactorWriteModel) Reduce() error {
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMMultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.WriteModel.AggregateID)
|
||||
}
|
42
internal/v2/command/iam_policy_login_identity_provider.go
Normal file
42
internal/v2/command/iam_policy_login_identity_provider.go
Normal file
@ -0,0 +1,42 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMIdentityProviderWriteModel struct {
|
||||
IdentityProviderWriteModel
|
||||
}
|
||||
|
||||
func NewIAMIdentityProviderWriteModel(iamID, idpConfigID string) *IAMIdentityProviderWriteModel {
|
||||
return &IAMIdentityProviderWriteModel{
|
||||
IdentityProviderWriteModel: IdentityProviderWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
IDPConfigID: idpConfigID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMIdentityProviderWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.IdentityProviderAddedEvent:
|
||||
if e.IDPConfigID != wm.IDPConfigID {
|
||||
continue
|
||||
}
|
||||
wm.IdentityProviderWriteModel.AppendEvents(&e.IdentityProviderAddedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMIdentityProviderWriteModel) Reduce() error {
|
||||
return wm.IdentityProviderWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMIdentityProviderWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.AggregateID)
|
||||
}
|
80
internal/v2/command/iam_policy_login_model.go
Normal file
80
internal/v2/command/iam_policy_login_model.go
Normal file
@ -0,0 +1,80 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMLoginPolicyWriteModel struct {
|
||||
LoginPolicyWriteModel
|
||||
}
|
||||
|
||||
func NewIAMLoginPolicyWriteModel(iamID string) *IAMLoginPolicyWriteModel {
|
||||
return &IAMLoginPolicyWriteModel{
|
||||
LoginPolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMLoginPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.LoginPolicyAddedEvent:
|
||||
wm.LoginPolicyWriteModel.AppendEvents(&e.LoginPolicyAddedEvent)
|
||||
case *iam.LoginPolicyChangedEvent:
|
||||
wm.LoginPolicyWriteModel.AppendEvents(&e.LoginPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMLoginPolicyWriteModel) IsValid() bool {
|
||||
return wm.AggregateID != ""
|
||||
}
|
||||
|
||||
func (wm *IAMLoginPolicyWriteModel) Reduce() error {
|
||||
return wm.LoginPolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMLoginPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.LoginPolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMLoginPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
allowUsernamePassword,
|
||||
allowRegister,
|
||||
allowExternalIDP,
|
||||
forceMFA bool,
|
||||
passwordlessType domain.PasswordlessType,
|
||||
) (*iam.LoginPolicyChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewLoginPolicyChangedEvent(ctx)
|
||||
if wm.AllowUserNamePassword == allowUsernamePassword {
|
||||
hasChanged = true
|
||||
changedEvent.AllowUserNamePassword = allowUsernamePassword
|
||||
}
|
||||
if wm.AllowRegister == allowRegister {
|
||||
hasChanged = true
|
||||
changedEvent.AllowRegister = allowRegister
|
||||
}
|
||||
if wm.AllowExternalIDP == allowExternalIDP {
|
||||
hasChanged = true
|
||||
changedEvent.AllowExternalIDP = allowExternalIDP
|
||||
}
|
||||
if wm.ForceMFA != forceMFA {
|
||||
hasChanged = true
|
||||
changedEvent.ForceMFA = forceMFA
|
||||
}
|
||||
if passwordlessType.Valid() && wm.PasswordlessType != passwordlessType {
|
||||
hasChanged = true
|
||||
changedEvent.PasswordlessType = passwordlessType
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
77
internal/v2/command/iam_policy_org_iam.go
Normal file
77
internal/v2/command/iam_policy_org_iam.go
Normal file
@ -0,0 +1,77 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) GetDefaultOrgIAMPolicy(ctx context.Context, aggregateID string) (*iam_model.OrgIAMPolicy, error) {
|
||||
policyWriteModel := NewIAMOrgIAMPolicyWriteModel(aggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy := writeModelToOrgIAMPolicy(policyWriteModel)
|
||||
policy.Default = true
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
addedPolicy := NewIAMOrgIAMPolicyWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToOrgIAMPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingPolicy, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0Pl0d", "Errors.IAM.OrgIAMPolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToOrgIAMPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultOrgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMOrgIAMPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMOrgIAMPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
51
internal/v2/command/iam_policy_org_iam_model.go
Normal file
51
internal/v2/command/iam_policy_org_iam_model.go
Normal file
@ -0,0 +1,51 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMOrgIAMPolicyWriteModel struct {
|
||||
PolicyOrgIAMWriteModel
|
||||
}
|
||||
|
||||
func NewIAMOrgIAMPolicyWriteModel(iamID string) *IAMOrgIAMPolicyWriteModel {
|
||||
return &IAMOrgIAMPolicyWriteModel{
|
||||
PolicyOrgIAMWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMOrgIAMPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.OrgIAMPolicyAddedEvent:
|
||||
wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyAddedEvent)
|
||||
case *iam.OrgIAMPolicyChangedEvent:
|
||||
wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMOrgIAMPolicyWriteModel) Reduce() error {
|
||||
return wm.PolicyOrgIAMWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*iam.OrgIAMPolicyChangedEvent, bool) {
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewOrgIAMPolicyChangedEvent(ctx)
|
||||
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
||||
hasChanged = true
|
||||
changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
67
internal/v2/command/iam_policy_password_age.go
Normal file
67
internal/v2/command/iam_policy_password_age.go
Normal file
@ -0,0 +1,67 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
addedPolicy := NewIAMPasswordAgePolicyWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.PasswordAgePolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordAgePolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordAgePolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||
existingPolicy, err := r.defaultPasswordAgePolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordAgePolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultPasswordAgePolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordAgePolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMPasswordAgePolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
55
internal/v2/command/iam_policy_password_age_model.go
Normal file
55
internal/v2/command/iam_policy_password_age_model.go
Normal file
@ -0,0 +1,55 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMPasswordAgePolicyWriteModel struct {
|
||||
PasswordAgePolicyWriteModel
|
||||
}
|
||||
|
||||
func NewIAMPasswordAgePolicyWriteModel(iamID string) *IAMPasswordAgePolicyWriteModel {
|
||||
return &IAMPasswordAgePolicyWriteModel{
|
||||
PasswordAgePolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordAgePolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.PasswordAgePolicyAddedEvent:
|
||||
wm.PasswordAgePolicyWriteModel.AppendEvents(&e.PasswordAgePolicyAddedEvent)
|
||||
case *iam.PasswordAgePolicyChangedEvent:
|
||||
wm.PasswordAgePolicyWriteModel.AppendEvents(&e.PasswordAgePolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordAgePolicyWriteModel) Reduce() error {
|
||||
return wm.PasswordAgePolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordAgePolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) (*iam.PasswordAgePolicyChangedEvent, bool) {
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewPasswordAgePolicyChangedEvent(ctx)
|
||||
if wm.ExpireWarnDays != expireWarnDays {
|
||||
hasChanged = true
|
||||
changedEvent.ExpireWarnDays = expireWarnDays
|
||||
}
|
||||
if wm.MaxAgeDays != maxAgeDays {
|
||||
hasChanged = true
|
||||
changedEvent.MaxAgeDays = maxAgeDays
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
94
internal/v2/command/iam_policy_password_complexity.go
Normal file
94
internal/v2/command/iam_policy_password_complexity.go
Normal file
@ -0,0 +1,94 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) GetDefaultPasswordComplexityPolicy(ctx context.Context, aggregateID string) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
policyWriteModel := NewIAMPasswordComplexityPolicyWriteModel(aggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
policy := writeModelToPasswordComplexityPolicy(policyWriteModel)
|
||||
policy.Default = true
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
addedPolicy := NewIAMPasswordComplexityPolicyWriteModel(policy.AggregateID)
|
||||
iamAgg, err := r.addDefaultPasswordComplexityPolicy(ctx, addedPolicy, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordComplexityPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *iam_model.PasswordComplexityPolicy) (*iam_repo.Aggregate, error) {
|
||||
if err := policy.IsValid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordComplexityPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol))
|
||||
|
||||
return iamAgg, nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
if err := policy.IsValid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingPolicy, err := r.defaultPasswordComplexityPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
|
||||
}
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordComplexityPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultPasswordComplexityPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordComplexityPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMPasswordComplexityPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
75
internal/v2/command/iam_policy_password_complexity_model.go
Normal file
75
internal/v2/command/iam_policy_password_complexity_model.go
Normal file
@ -0,0 +1,75 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMPasswordComplexityPolicyWriteModel struct {
|
||||
PasswordComplexityPolicyWriteModel
|
||||
}
|
||||
|
||||
func NewIAMPasswordComplexityPolicyWriteModel(iamID string) *IAMPasswordComplexityPolicyWriteModel {
|
||||
return &IAMPasswordComplexityPolicyWriteModel{
|
||||
PasswordComplexityPolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordComplexityPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.PasswordComplexityPolicyAddedEvent:
|
||||
wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent)
|
||||
case *iam.PasswordComplexityPolicyChangedEvent:
|
||||
wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordComplexityPolicyWriteModel) Reduce() error {
|
||||
return wm.PasswordComplexityPolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
minLength uint64,
|
||||
hasLowercase,
|
||||
hasUppercase,
|
||||
hasNumber,
|
||||
hasSymbol bool,
|
||||
) (*iam.PasswordComplexityPolicyChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewPasswordComplexityPolicyChangedEvent(ctx)
|
||||
if wm.MinLength != minLength {
|
||||
hasChanged = true
|
||||
changedEvent.MinLength = minLength
|
||||
}
|
||||
if wm.HasLowercase != hasLowercase {
|
||||
hasChanged = true
|
||||
changedEvent.HasLowercase = hasLowercase
|
||||
}
|
||||
if wm.HasUpperCase != hasUppercase {
|
||||
hasChanged = true
|
||||
changedEvent.HasUpperCase = hasUppercase
|
||||
}
|
||||
if wm.HasNumber != hasNumber {
|
||||
hasChanged = true
|
||||
changedEvent.HasNumber = hasNumber
|
||||
}
|
||||
if wm.HasSymbol != hasSymbol {
|
||||
hasChanged = true
|
||||
changedEvent.HasSymbol = hasSymbol
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
67
internal/v2/command/iam_policy_password_lockout.go
Normal file
67
internal/v2/command/iam_policy_password_lockout.go
Normal file
@ -0,0 +1,67 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
addedPolicy := NewIAMPasswordLockoutPolicyWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordLockoutPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||
existingPolicy, err := r.defaultPasswordLockoutPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordLockoutPolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.PasswordLockoutPolicy.NotChanged")
|
||||
}
|
||||
|
||||
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel)
|
||||
iamAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToPasswordLockoutPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordLockoutPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewIAMPasswordLockoutPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
55
internal/v2/command/iam_policy_password_lockout_model.go
Normal file
55
internal/v2/command/iam_policy_password_lockout_model.go
Normal file
@ -0,0 +1,55 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type IAMPasswordLockoutPolicyWriteModel struct {
|
||||
PasswordLockoutPolicyWriteModel
|
||||
}
|
||||
|
||||
func NewIAMPasswordLockoutPolicyWriteModel(iamID string) *IAMPasswordLockoutPolicyWriteModel {
|
||||
return &IAMPasswordLockoutPolicyWriteModel{
|
||||
PasswordLockoutPolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *iam.PasswordLockoutPolicyAddedEvent:
|
||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent)
|
||||
case *iam.PasswordLockoutPolicyChangedEvent:
|
||||
wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error {
|
||||
return wm.PasswordLockoutPolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
|
||||
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) {
|
||||
hasChanged := false
|
||||
changedEvent := iam.NewPasswordLockoutPolicyChangedEvent(ctx)
|
||||
if wm.MaxAttempts != maxAttempts {
|
||||
hasChanged = true
|
||||
changedEvent.MaxAttempts = maxAttempts
|
||||
}
|
||||
if wm.ShowLockOutFailures != showLockoutFailure {
|
||||
hasChanged = true
|
||||
changedEvent.ShowLockOutFailures = showLockoutFailure
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
29
internal/v2/command/identity_provider_model.go
Normal file
29
internal/v2/command/identity_provider_model.go
Normal file
@ -0,0 +1,29 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type IdentityProviderWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
IDPConfigID string
|
||||
IDPProviderType domain.IdentityProviderType
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *IdentityProviderWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *policy.IdentityProviderAddedEvent:
|
||||
wm.IDPConfigID = e.IDPConfigID
|
||||
wm.IDPProviderType = e.IDPProviderType
|
||||
wm.IsActive = true
|
||||
case *policy.IdentityProviderRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
75
internal/v2/command/idp_config_model.go
Normal file
75
internal/v2/command/idp_config_model.go
Normal file
@ -0,0 +1,75 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
)
|
||||
|
||||
type IDPConfigWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
State domain.IDPConfigState
|
||||
|
||||
ConfigID string
|
||||
Name string
|
||||
StylingType domain.IDPConfigStylingType
|
||||
|
||||
OIDCConfig *OIDCConfigWriteModel
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
rm.WriteModel.AppendEvents(events...)
|
||||
for _, event := range events {
|
||||
switch event.(type) {
|
||||
case *idpconfig.OIDCConfigAddedEvent:
|
||||
rm.OIDCConfig = new(OIDCConfigWriteModel)
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
case *idpconfig.OIDCConfigChangedEvent:
|
||||
rm.OIDCConfig.AppendEvents(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) Reduce() error {
|
||||
for _, event := range rm.Events {
|
||||
switch e := event.(type) {
|
||||
case *idpconfig.IDPConfigAddedEvent:
|
||||
rm.reduceConfigAddedEvent(e)
|
||||
case *idpconfig.IDPConfigChangedEvent:
|
||||
rm.reduceConfigChangedEvent(e)
|
||||
case *idpconfig.IDPConfigDeactivatedEvent:
|
||||
rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateInactive)
|
||||
case *idpconfig.IDPConfigReactivatedEvent:
|
||||
rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateActive)
|
||||
case *idpconfig.IDPConfigRemovedEvent:
|
||||
rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateRemoved)
|
||||
}
|
||||
}
|
||||
if rm.OIDCConfig != nil {
|
||||
if err := rm.OIDCConfig.Reduce(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return rm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAddedEvent) {
|
||||
rm.ConfigID = e.ConfigID
|
||||
rm.Name = e.Name
|
||||
rm.StylingType = e.StylingType
|
||||
rm.State = domain.IDPConfigStateActive
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) {
|
||||
if e.Name != "" {
|
||||
rm.Name = e.Name
|
||||
}
|
||||
if e.StylingType.Valid() {
|
||||
rm.StylingType = e.StylingType
|
||||
}
|
||||
}
|
||||
|
||||
func (rm *IDPConfigWriteModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) {
|
||||
rm.State = state
|
||||
}
|
37
internal/v2/command/member_model.go
Normal file
37
internal/v2/command/member_model.go
Normal file
@ -0,0 +1,37 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/member"
|
||||
)
|
||||
|
||||
type MemberWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
UserID string
|
||||
Roles []string
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func NewMemberWriteModel(userID string) *MemberWriteModel {
|
||||
return &MemberWriteModel{
|
||||
UserID: userID,
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *MemberWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *member.MemberAddedEvent:
|
||||
wm.UserID = e.UserID
|
||||
wm.Roles = e.Roles
|
||||
wm.IsActive = true
|
||||
case *member.MemberChangedEvent:
|
||||
wm.Roles = e.Roles
|
||||
case *member.MemberRemovedEvent:
|
||||
wm.Roles = nil
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
package oidc
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
|
||||
)
|
||||
|
||||
type ConfigWriteModel struct {
|
||||
type OIDCConfigWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
IDPConfigID string
|
||||
@ -14,24 +16,31 @@ type ConfigWriteModel struct {
|
||||
Issuer string
|
||||
Scopes []string
|
||||
|
||||
IDPDisplayNameMapping MappingField
|
||||
UserNameMapping MappingField
|
||||
IDPDisplayNameMapping domain.OIDCMappingField
|
||||
UserNameMapping domain.OIDCMappingField
|
||||
State domain.IDPConfigState
|
||||
}
|
||||
|
||||
func (wm *ConfigWriteModel) Reduce() error {
|
||||
func (wm *OIDCConfigWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *ConfigAddedEvent:
|
||||
case *idpconfig.OIDCConfigAddedEvent:
|
||||
wm.reduceConfigAddedEvent(e)
|
||||
case *ConfigChangedEvent:
|
||||
case *idpconfig.OIDCConfigChangedEvent:
|
||||
wm.reduceConfigChangedEvent(e)
|
||||
case *idpconfig.IDPConfigDeactivatedEvent:
|
||||
wm.State = domain.IDPConfigStateInactive
|
||||
case *idpconfig.IDPConfigReactivatedEvent:
|
||||
wm.State = domain.IDPConfigStateActive
|
||||
case *idpconfig.IDPConfigRemovedEvent:
|
||||
wm.State = domain.IDPConfigStateRemoved
|
||||
}
|
||||
}
|
||||
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) {
|
||||
func (wm *OIDCConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.OIDCConfigAddedEvent) {
|
||||
wm.IDPConfigID = e.IDPConfigID
|
||||
wm.ClientID = e.ClientID
|
||||
wm.ClientSecret = e.ClientSecret
|
||||
@ -39,9 +48,10 @@ func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) {
|
||||
wm.Scopes = e.Scopes
|
||||
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||
wm.UserNameMapping = e.UserNameMapping
|
||||
wm.State = domain.IDPConfigStateActive
|
||||
}
|
||||
|
||||
func (wm *ConfigWriteModel) reduceConfigChangedEvent(e *ConfigChangedEvent) {
|
||||
func (wm *OIDCConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.OIDCConfigChangedEvent) {
|
||||
if e.ClientID != "" {
|
||||
wm.ClientID = e.ClientID
|
||||
}
|
23
internal/v2/command/org_converter.go
Normal file
23
internal/v2/command/org_converter.go
Normal file
@ -0,0 +1,23 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func orgWriteModelToOrgIAMPolicy(wm *ORGOrgIAMPolicyWriteModel) *model.OrgIAMPolicy {
|
||||
return &model.OrgIAMPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel),
|
||||
UserLoginMustBeDomain: wm.UserLoginMustBeDomain,
|
||||
}
|
||||
}
|
||||
|
||||
func orgWriteModelToPasswordComplexityPolicy(wm *OrgPasswordComplexityPolicyWriteModel) *model.PasswordComplexityPolicy {
|
||||
return &model.PasswordComplexityPolicy{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.PasswordComplexityPolicyWriteModel.WriteModel),
|
||||
MinLength: wm.MinLength,
|
||||
HasLowercase: wm.HasLowercase,
|
||||
HasUppercase: wm.HasUpperCase,
|
||||
HasNumber: wm.HasNumber,
|
||||
HasSymbol: wm.HasSymbol,
|
||||
}
|
||||
}
|
5
internal/v2/command/org_member_model.go
Normal file
5
internal/v2/command/org_member_model.go
Normal file
@ -0,0 +1,5 @@
|
||||
package command
|
||||
|
||||
type OrgMemberWriteModel struct {
|
||||
MemberWriteModel
|
||||
}
|
12
internal/v2/command/org_model.go
Normal file
12
internal/v2/command/org_model.go
Normal file
@ -0,0 +1,12 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
func ORGAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate {
|
||||
return &org.Aggregate{
|
||||
Aggregate: *eventstore.AggregateFromWriteModel(wm, org.AggregateType, org.AggregateVersion),
|
||||
}
|
||||
}
|
78
internal/v2/command/org_policy_org_iam.go
Normal file
78
internal/v2/command/org_policy_org_iam.go
Normal file
@ -0,0 +1,78 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) GetOrgIAMPolicy(ctx context.Context, orgID string) (*iam_model.OrgIAMPolicy, error) {
|
||||
policy := NewORGOrgIAMPolicyWriteModel(orgID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policy.IsActive {
|
||||
return orgWriteModelToOrgIAMPolicy(policy), nil
|
||||
}
|
||||
return r.GetDefaultOrgIAMPolicy(ctx, r.iamID)
|
||||
}
|
||||
|
||||
func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
addedPolicy := NewORGOrgIAMPolicyWriteModel(policy.AggregateID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if addedPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-5M0ds", "Errors.Org.OrgIAMPolicy.AlreadyExists")
|
||||
}
|
||||
orgAgg := ORGAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel)
|
||||
orgAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return orgWriteModelToOrgIAMPolicy(addedPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||
existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !existingPolicy.IsActive {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-2N9sd", "Errors.Org.OrgIAMPolicy.NotFound")
|
||||
}
|
||||
|
||||
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-3M9ds", "Errors.Org.LabelPolicy.NotChanged")
|
||||
}
|
||||
|
||||
orgAgg := ORGAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel)
|
||||
orgAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return orgWriteModelToOrgIAMPolicy(existingPolicy), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) orgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *ORGOrgIAMPolicyWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel := NewORGOrgIAMPolicyWriteModel(iamID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
51
internal/v2/command/org_policy_org_iam_model.go
Normal file
51
internal/v2/command/org_policy_org_iam_model.go
Normal file
@ -0,0 +1,51 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
type ORGOrgIAMPolicyWriteModel struct {
|
||||
PolicyOrgIAMWriteModel
|
||||
}
|
||||
|
||||
func NewORGOrgIAMPolicyWriteModel(orgID string) *ORGOrgIAMPolicyWriteModel {
|
||||
return &ORGOrgIAMPolicyWriteModel{
|
||||
PolicyOrgIAMWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: orgID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *ORGOrgIAMPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *org.OrgIAMPolicyAddedEvent:
|
||||
wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyAddedEvent)
|
||||
case *org.OrgIAMPolicyChangedEvent:
|
||||
wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *ORGOrgIAMPolicyWriteModel) Reduce() error {
|
||||
return wm.PolicyOrgIAMWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *ORGOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
|
||||
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*org.OrgIAMPolicyChangedEvent, bool) {
|
||||
hasChanged := false
|
||||
changedEvent := org.NewOrgIAMPolicyChangedEvent(ctx)
|
||||
if wm.UserLoginMustBeDomain != userLoginMustBeDomain {
|
||||
hasChanged = true
|
||||
changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
18
internal/v2/command/org_policy_password_complexity.go
Normal file
18
internal/v2/command/org_policy_password_complexity.go
Normal file
@ -0,0 +1,18 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
)
|
||||
|
||||
func (r *CommandSide) GetOrgPasswordComplexityPolicy(ctx context.Context, orgID string) (*iam_model.PasswordComplexityPolicy, error) {
|
||||
policy := NewOrgPasswordComplexityPolicyWriteModel(orgID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if policy.IsActive {
|
||||
return orgWriteModelToPasswordComplexityPolicy(policy), nil
|
||||
}
|
||||
return r.GetDefaultPasswordComplexityPolicy(ctx, r.iamID)
|
||||
}
|
75
internal/v2/command/org_policy_password_complexity_model.go
Normal file
75
internal/v2/command/org_policy_password_complexity_model.go
Normal file
@ -0,0 +1,75 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/org"
|
||||
)
|
||||
|
||||
type OrgPasswordComplexityPolicyWriteModel struct {
|
||||
PasswordComplexityPolicyWriteModel
|
||||
}
|
||||
|
||||
func NewOrgPasswordComplexityPolicyWriteModel(iamID string) *OrgPasswordComplexityPolicyWriteModel {
|
||||
return &OrgPasswordComplexityPolicyWriteModel{
|
||||
PasswordComplexityPolicyWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: iamID,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *OrgPasswordComplexityPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *org.PasswordComplexityPolicyAddedEvent:
|
||||
wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent)
|
||||
case *org.PasswordComplexityPolicyChangedEvent:
|
||||
wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *OrgPasswordComplexityPolicyWriteModel) Reduce() error {
|
||||
return wm.PasswordComplexityPolicyWriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *OrgPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
|
||||
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID)
|
||||
}
|
||||
|
||||
func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent(
|
||||
ctx context.Context,
|
||||
minLength uint64,
|
||||
hasLowercase,
|
||||
hasUppercase,
|
||||
hasNumber,
|
||||
hasSymbol bool,
|
||||
) (*org.PasswordComplexityPolicyChangedEvent, bool) {
|
||||
|
||||
hasChanged := false
|
||||
changedEvent := org.NewPasswordComplexityPolicyChangedEvent(ctx)
|
||||
if wm.MinLength != minLength {
|
||||
hasChanged = true
|
||||
changedEvent.MinLength = minLength
|
||||
}
|
||||
if wm.HasLowercase != hasLowercase {
|
||||
hasChanged = true
|
||||
changedEvent.HasLowercase = hasLowercase
|
||||
}
|
||||
if wm.HasUpperCase != hasUppercase {
|
||||
hasChanged = true
|
||||
changedEvent.HasUpperCase = hasUppercase
|
||||
}
|
||||
if wm.HasNumber != hasNumber {
|
||||
hasChanged = true
|
||||
changedEvent.HasNumber = hasNumber
|
||||
}
|
||||
if wm.HasSymbol != hasSymbol {
|
||||
hasChanged = true
|
||||
changedEvent.HasSymbol = hasSymbol
|
||||
}
|
||||
return changedEvent, hasChanged
|
||||
}
|
@ -1,25 +1,30 @@
|
||||
package label
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type WriteModel struct {
|
||||
type LabelPolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
PrimaryColor string
|
||||
SecondaryColor string
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *WriteModel) Reduce() error {
|
||||
func (wm *LabelPolicyWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *AddedEvent:
|
||||
case *policy.LabelPolicyAddedEvent:
|
||||
wm.PrimaryColor = e.PrimaryColor
|
||||
wm.SecondaryColor = e.SecondaryColor
|
||||
case *ChangedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.LabelPolicyChangedEvent:
|
||||
wm.PrimaryColor = e.PrimaryColor
|
||||
wm.SecondaryColor = e.SecondaryColor
|
||||
case *policy.LabelPolicyRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
@ -1,19 +1,26 @@
|
||||
package factors
|
||||
package command
|
||||
|
||||
import "github.com/caos/zitadel/internal/eventstore/v2"
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type SecondFactorWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
MFAType SecondFactorType
|
||||
MFAType domain.SecondFactorType
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *SecondFactorWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *SecondFactorAddedEvent:
|
||||
case *policy.SecondFactorAddedEvent:
|
||||
wm.MFAType = e.MFAType
|
||||
case *SecondFactorRemovedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.SecondFactorRemovedEvent:
|
||||
wm.MFAType = e.MFAType
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
@ -21,16 +28,19 @@ func (wm *SecondFactorWriteModel) Reduce() error {
|
||||
|
||||
type MultiFactoryWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
MFAType MultiFactorType
|
||||
MFAType domain.MultiFactorType
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *MultiFactoryWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *MultiFactorAddedEvent:
|
||||
case *policy.MultiFactorAddedEvent:
|
||||
wm.MFAType = e.MFAType
|
||||
case *MultiFactorRemovedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.MultiFactorRemovedEvent:
|
||||
wm.MFAType = e.MFAType
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
@ -1,34 +1,40 @@
|
||||
package login
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type WriteModel struct {
|
||||
type LoginPolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
AllowUserNamePassword bool
|
||||
AllowRegister bool
|
||||
AllowExternalIDP bool
|
||||
ForceMFA bool
|
||||
PasswordlessType PasswordlessType
|
||||
PasswordlessType domain.PasswordlessType
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *WriteModel) Reduce() error {
|
||||
func (wm *LoginPolicyWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *AddedEvent:
|
||||
case *policy.LoginPolicyAddedEvent:
|
||||
wm.AllowRegister = e.AllowRegister
|
||||
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
||||
wm.AllowExternalIDP = e.AllowExternalIDP
|
||||
wm.ForceMFA = e.ForceMFA
|
||||
wm.PasswordlessType = e.PasswordlessType
|
||||
case *ChangedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.LoginPolicyChangedEvent:
|
||||
wm.AllowRegister = e.AllowRegister
|
||||
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
||||
wm.AllowExternalIDP = e.AllowExternalIDP
|
||||
wm.ForceMFA = e.ForceMFA
|
||||
wm.PasswordlessType = e.PasswordlessType
|
||||
case *policy.LoginPolicyRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
26
internal/v2/command/policy_org_iam_model.go
Normal file
26
internal/v2/command/policy_org_iam_model.go
Normal file
@ -0,0 +1,26 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type PolicyOrgIAMWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
UserLoginMustBeDomain bool
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *PolicyOrgIAMWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *policy.OrgIAMPolicyAddedEvent:
|
||||
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
||||
wm.IsActive = true
|
||||
case *policy.OrgIAMPolicyChangedEvent:
|
||||
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
@ -1,25 +1,30 @@
|
||||
package password_age
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type WriteModel struct {
|
||||
type PasswordAgePolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
ExpireWarnDays uint64
|
||||
MaxAgeDays uint64
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *WriteModel) Reduce() error {
|
||||
func (wm *PasswordAgePolicyWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *AddedEvent:
|
||||
case *policy.PasswordAgePolicyAddedEvent:
|
||||
wm.ExpireWarnDays = e.ExpireWarnDays
|
||||
wm.MaxAgeDays = e.MaxAgeDays
|
||||
case *ChangedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.PasswordAgePolicyChangedEvent:
|
||||
wm.ExpireWarnDays = e.ExpireWarnDays
|
||||
wm.MaxAgeDays = e.MaxAgeDays
|
||||
case *policy.PasswordAgePolicyRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
@ -1,10 +1,11 @@
|
||||
package password_complexity
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type WriteModel struct {
|
||||
type PasswordComplexityPolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
MinLength uint64
|
||||
@ -12,23 +13,27 @@ type WriteModel struct {
|
||||
HasUpperCase bool
|
||||
HasNumber bool
|
||||
HasSymbol bool
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *WriteModel) Reduce() error {
|
||||
func (wm *PasswordComplexityPolicyWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *AddedEvent:
|
||||
case *policy.PasswordComplexityPolicyAddedEvent:
|
||||
wm.MinLength = e.MinLength
|
||||
wm.HasLowercase = e.HasLowercase
|
||||
wm.HasUpperCase = e.HasUpperCase
|
||||
wm.HasNumber = e.HasNumber
|
||||
wm.HasSymbol = e.HasSymbol
|
||||
case *ChangedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.PasswordComplexityPolicyChangedEvent:
|
||||
wm.MinLength = e.MinLength
|
||||
wm.HasLowercase = e.HasLowercase
|
||||
wm.HasUpperCase = e.HasUpperCase
|
||||
wm.HasNumber = e.HasNumber
|
||||
wm.HasSymbol = e.HasSymbol
|
||||
case *policy.PasswordComplexityPolicyRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
@ -1,25 +1,30 @@
|
||||
package password_lockout
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||
)
|
||||
|
||||
type WriteModel struct {
|
||||
type PasswordLockoutPolicyWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
MaxAttempts uint64
|
||||
ShowLockOutFailures bool
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
func (wm *WriteModel) Reduce() error {
|
||||
func (wm *PasswordLockoutPolicyWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *AddedEvent:
|
||||
case *policy.PasswordLockoutPolicyAddedEvent:
|
||||
wm.MaxAttempts = e.MaxAttempts
|
||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||
case *ChangedEvent:
|
||||
wm.IsActive = true
|
||||
case *policy.PasswordLockoutPolicyChangedEvent:
|
||||
wm.MaxAttempts = e.MaxAttempts
|
||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||
case *policy.PasswordLockoutPolicyRemovedEvent:
|
||||
wm.IsActive = false
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
65
internal/v2/command/setup.go
Normal file
65
internal/v2/command/setup.go
Normal file
@ -0,0 +1,65 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain.Step) (*iam_model.IAM, error) {
|
||||
iamWriteModel, err := r.iamByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if iamWriteModel.SetUpStarted >= step || iamWriteModel.SetUpStarted != iamWriteModel.SetUpDone {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
|
||||
}
|
||||
aggregate := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel).PushEvents(iam_repo.NewSetupStepStartedEvent(ctx, step))
|
||||
err = r.eventstore.PushAggregate(ctx, iamWriteModel, aggregate)
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Grgh1", "Setup start failed")
|
||||
}
|
||||
return writeModelToIAM(iamWriteModel), nil
|
||||
}
|
||||
|
||||
//func (r *CommandSide) setupDone(ctx context.Context, iamAgg *iam_repo.Aggregate, event eventstore.EventPusher, aggregates ...eventstore.Aggregater) error {
|
||||
// aggregate := iamAgg.PushEvents(event)
|
||||
//
|
||||
// aggregates = append(aggregates, aggregate)
|
||||
// _, err := r.eventstore.PushAggregates(ctx, aggregates...)
|
||||
// if err != nil {
|
||||
// return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dgd2", "Setup done failed")
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
|
||||
//
|
||||
////TODO: should not use readmodel
|
||||
//func (r *CommandSide) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) {
|
||||
// iam, err := r.iamByID(ctx, iamID)
|
||||
// if err != nil && !caos_errs.IsNotFound(err) {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) {
|
||||
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
|
||||
// }
|
||||
//
|
||||
// aggregate := query.AggregateFromReadModel(iam).
|
||||
// PushEvents(event)
|
||||
//
|
||||
// events, err := r.eventstore.PushAggregates(ctx, aggregate)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// if err = iam.AppendAndReduce(events...); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return nil, nil
|
||||
// //TODO: return write model
|
||||
// //return readModelToIAM(iam), nil
|
||||
//}
|
107
internal/v2/command/setup_step1.go
Normal file
107
internal/v2/command/setup_step1.go
Normal file
@ -0,0 +1,107 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type Step1 struct {
|
||||
GlobalOrg string
|
||||
IAMProject string
|
||||
DefaultLoginPolicy LoginPolicy //*iam_model.LoginPolicy
|
||||
Orgs []Org
|
||||
Owners []string
|
||||
|
||||
//setup *Setup
|
||||
//createdUsers map[string]*usr_model.User
|
||||
//createdOrgs map[string]*org_model.Org
|
||||
//createdProjects map[string]*proj_model.Project
|
||||
//pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
|
||||
}
|
||||
|
||||
type LoginPolicy struct {
|
||||
AllowRegister bool
|
||||
AllowUsernamePassword bool
|
||||
AllowExternalIdp bool
|
||||
}
|
||||
|
||||
type User struct {
|
||||
FirstName string
|
||||
LastName string
|
||||
UserName string
|
||||
Email string
|
||||
Password string
|
||||
}
|
||||
|
||||
type Org struct {
|
||||
Name string
|
||||
Domain string
|
||||
OrgIamPolicy bool
|
||||
Users []User
|
||||
Owners []string
|
||||
Projects []Project
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
Name string
|
||||
Users []User
|
||||
Members []string
|
||||
OIDCApps []OIDCApp
|
||||
}
|
||||
|
||||
type OIDCApp struct {
|
||||
Name string
|
||||
RedirectUris []string
|
||||
ResponseTypes []string
|
||||
GrantTypes []string
|
||||
ApplicationType string
|
||||
AuthMethodType string
|
||||
PostLogoutRedirectUris []string
|
||||
DevMode bool
|
||||
}
|
||||
|
||||
func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 Step1) error {
|
||||
iam, err := r.iamByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
//create default login policy
|
||||
iamAgg, err := r.addDefaultLoginPolicy(ctx,
|
||||
NewIAMLoginPolicyWriteModel(iam.AggregateID),
|
||||
&iam_model.LoginPolicy{
|
||||
AllowUsernamePassword: step1.DefaultLoginPolicy.AllowUsernamePassword,
|
||||
AllowRegister: step1.DefaultLoginPolicy.AllowRegister,
|
||||
AllowExternalIdp: step1.DefaultLoginPolicy.AllowExternalIdp,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//create orgs
|
||||
//create projects
|
||||
//create applications
|
||||
//set iam owners
|
||||
//set global org
|
||||
//set iam project id
|
||||
|
||||
/*aggregates:
|
||||
iam:
|
||||
default login policy
|
||||
iam owner
|
||||
org:
|
||||
default
|
||||
caos
|
||||
zitadel
|
||||
|
||||
*/
|
||||
iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1))
|
||||
|
||||
_, err = r.eventstore.PushAggregates(ctx, iamAgg)
|
||||
if err != nil {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Gr2hh", "Setup Step1 failed")
|
||||
}
|
||||
return nil
|
||||
}
|
38
internal/v2/command/setup_step2.go
Normal file
38
internal/v2/command/setup_step2.go
Normal file
@ -0,0 +1,38 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
|
||||
)
|
||||
|
||||
type Step2 struct {
|
||||
DefaultPasswordComplexityPolicy iam_model.PasswordComplexityPolicy
|
||||
}
|
||||
|
||||
func (r *CommandSide) SetupStep2(ctx context.Context, iamID string, step Step2) error {
|
||||
iam, err := r.iamByID(ctx, iamID)
|
||||
if err != nil && !caos_errs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
iamAgg, err := r.addDefaultPasswordComplexityPolicy(ctx, NewIAMPasswordComplexityPolicyWriteModel(iam.AggregateID), &iam_model.PasswordComplexityPolicy{
|
||||
MinLength: step.DefaultPasswordComplexityPolicy.MinLength,
|
||||
HasLowercase: step.DefaultPasswordComplexityPolicy.HasLowercase,
|
||||
HasUppercase: step.DefaultPasswordComplexityPolicy.HasUppercase,
|
||||
HasNumber: step.DefaultPasswordComplexityPolicy.HasNumber,
|
||||
HasSymbol: step.DefaultPasswordComplexityPolicy.HasSymbol,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1))
|
||||
|
||||
_, err = r.eventstore.PushAggregates(ctx, iamAgg)
|
||||
if err != nil {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-HR2na", "Setup Step2 failed")
|
||||
}
|
||||
return nil
|
||||
}
|
123
internal/v2/command/user.go
Normal file
123
internal/v2/command/user.go
Normal file
@ -0,0 +1,123 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/user"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddUser(ctx context.Context, user *usr_model.User) (*usr_model.User, error) {
|
||||
if !user.IsValid() {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2N9fs", "Errors.User.Invalid")
|
||||
}
|
||||
|
||||
if user.Human != nil {
|
||||
human, err := r.AddHuman(ctx, user.ResourceOwner, user.UserName, user.Human)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &usr_model.User{UserName: user.UserName, Human: human}, nil
|
||||
} else if user.Machine != nil {
|
||||
|
||||
}
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined")
|
||||
}
|
||||
|
||||
func (r *CommandSide) DeactivateUser(ctx context.Context, userID string) (*usr_model.User, error) {
|
||||
existingUser, err := r.userWriteModelByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-3M9ds", "Errors.User.NotFound")
|
||||
}
|
||||
if existingUser.UserState == domain.UserStateInactive {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0sf", "Errors.User.AlreadyInactive")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
userAgg.PushEvents(user.NewUserDeactivatedEvent(ctx))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToUser(existingUser), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) ReactivateUser(ctx context.Context, userID string) (*usr_model.User, error) {
|
||||
existingUser, err := r.userWriteModelByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-4M0sd", "Errors.User.NotFound")
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateInactive {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M0sf", "Errors.User.NotInactive")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
userAgg.PushEvents(user.NewUserReactivatedEvent(ctx))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToUser(existingUser), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) LockUser(ctx context.Context, userID string) (*usr_model.User, error) {
|
||||
existingUser, err := r.userWriteModelByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-5M9fs", "Errors.User.NotFound")
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateActive && existingUser.UserState != domain.UserStateInitial {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.ShouldBeActiveOrInitial")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
userAgg.PushEvents(user.NewUserLockedEvent(ctx))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToUser(existingUser), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) UnlockUser(ctx context.Context, userID string) (*usr_model.User, error) {
|
||||
existingUser, err := r.userWriteModelByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-M0dos", "Errors.User.NotFound")
|
||||
}
|
||||
if existingUser.UserState != domain.UserStateLocked {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0ds", "Errors.User.NotLocked")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
userAgg.PushEvents(user.NewUserUnlockedEvent(ctx))
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingUser, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToUser(existingUser), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID string) (writeModel *UserWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel = NewUserWriteModel(userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
62
internal/v2/command/user_converter.go
Normal file
62
internal/v2/command/user_converter.go
Normal file
@ -0,0 +1,62 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
)
|
||||
|
||||
func writeModelToUser(wm *UserWriteModel) *model.User {
|
||||
return &model.User{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
UserName: wm.UserName,
|
||||
State: model.UserState(wm.UserState),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToHuman(wm *HumanWriteModel) *model.Human {
|
||||
return &model.Human{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
Profile: &model.Profile{
|
||||
FirstName: wm.FirstName,
|
||||
LastName: wm.LastName,
|
||||
NickName: wm.NickName,
|
||||
DisplayName: wm.DisplayName,
|
||||
PreferredLanguage: wm.PreferredLanguage,
|
||||
Gender: model.Gender(wm.Gender),
|
||||
},
|
||||
Email: &model.Email{
|
||||
EmailAddress: wm.Email,
|
||||
IsEmailVerified: wm.IsEmailVerified,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToProfile(wm *HumanProfileWriteModel) *model.Profile {
|
||||
return &model.Profile{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
FirstName: wm.FirstName,
|
||||
LastName: wm.LastName,
|
||||
NickName: wm.NickName,
|
||||
DisplayName: wm.DisplayName,
|
||||
PreferredLanguage: wm.PreferredLanguage,
|
||||
Gender: model.Gender(wm.Gender),
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToEmail(wm *HumanEmailWriteModel) *model.Email {
|
||||
return &model.Email{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
EmailAddress: wm.Email,
|
||||
IsEmailVerified: wm.IsEmailVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func writeModelToAddress(wm *HumanAddressWriteModel) *model.Address {
|
||||
return &model.Address{
|
||||
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
|
||||
Country: wm.Country,
|
||||
Locality: wm.Locality,
|
||||
PostalCode: wm.PostalCode,
|
||||
Region: wm.Region,
|
||||
StreetAddress: wm.StreetAddress,
|
||||
}
|
||||
}
|
71
internal/v2/command/user_human.go
Normal file
71
internal/v2/command/user_human.go
Normal file
@ -0,0 +1,71 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
"github.com/caos/zitadel/internal/v2/repository/user"
|
||||
)
|
||||
|
||||
func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, human *usr_model.Human) (*usr_model.Human, error) {
|
||||
if !human.IsValid() {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
|
||||
}
|
||||
userID, err := r.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
human.AggregateID = userID
|
||||
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//pwPolicy, err := r.GetOrgPasswordComplexityPolicy(ctx, orgID)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
addedHuman := NewHumanWriteModel(human.AggregateID)
|
||||
//TODO: Check Unique Username
|
||||
human.CheckOrgIAMPolicy(username, orgIAMPolicy)
|
||||
human.SetNamesAsDisplayname()
|
||||
//human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true)
|
||||
|
||||
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)
|
||||
userAgg.PushEvents(
|
||||
user.NewHumanAddedEvent(
|
||||
ctx,
|
||||
username,
|
||||
human.FirstName,
|
||||
human.LastName,
|
||||
human.NickName,
|
||||
human.DisplayName,
|
||||
human.PreferredLanguage,
|
||||
domain.Gender(human.Gender),
|
||||
human.EmailAddress,
|
||||
human.PhoneNumber,
|
||||
human.Country,
|
||||
human.Locality,
|
||||
human.PostalCode,
|
||||
human.Region,
|
||||
human.StreetAddress,
|
||||
),
|
||||
)
|
||||
//TODO: HashPassword If existing
|
||||
//TODO: Generate Init Code if needed
|
||||
//TODO: Generate Phone Code if needed
|
||||
if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified {
|
||||
userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx))
|
||||
}
|
||||
if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified {
|
||||
userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx))
|
||||
}
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToHuman(addedHuman), nil
|
||||
}
|
44
internal/v2/command/user_human_address.go
Normal file
44
internal/v2/command/user_human_address.go
Normal file
@ -0,0 +1,44 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/internal/v2/domain"
|
||||
)
|
||||
|
||||
func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) {
|
||||
existingAddress, err := r.addressWriteModel(ctx, address.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if existingAddress.UserState == domain.UserStateUnspecified || existingAddress.UserState == domain.UserStateDeleted {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-0pLdo", "Errors.User.Address.NotFound")
|
||||
}
|
||||
changedEvent, hasChanged := existingAddress.NewChangedEvent(ctx, address.Country, address.Locality, address.PostalCode, address.Region, address.StreetAddress)
|
||||
if !hasChanged {
|
||||
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-3M0cs", "Errors.User.Address.NotChanged")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingAddress.WriteModel)
|
||||
userAgg.PushEvents(changedEvent)
|
||||
|
||||
err = r.eventstore.PushAggregate(ctx, existingAddress, userAgg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return writeModelToAddress(existingAddress), nil
|
||||
}
|
||||
|
||||
func (r *CommandSide) addressWriteModel(ctx context.Context, userID string) (writeModel *HumanAddressWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel = NewHumanAddressWriteModel(userID)
|
||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user