mirror of
https://github.com/zitadel/zitadel.git
synced 2025-04-07 17:14: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()
|
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")
|
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")
|
logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup")
|
||||||
}
|
}
|
||||||
|
@ -26,53 +26,53 @@ SetUp:
|
|||||||
Step1:
|
Step1:
|
||||||
GlobalOrg: 'Global'
|
GlobalOrg: 'Global'
|
||||||
IAMProject: 'Zitadel'
|
IAMProject: 'Zitadel'
|
||||||
DefaultLoginPolicy:
|
# DefaultLoginPolicy:
|
||||||
AllowUsernamePassword: true
|
# AllowUsernamePassword: true
|
||||||
AllowRegister: true
|
# AllowRegister: true
|
||||||
AllowExternalIdp: true
|
# AllowExternalIdp: true
|
||||||
Orgs:
|
# Orgs:
|
||||||
- Name: 'Global'
|
# - Name: 'Global'
|
||||||
Domain: 'global.caos.ch'
|
# Domain: 'global.caos.ch'
|
||||||
Default: true
|
# Default: true
|
||||||
OrgIamPolicy: true
|
# OrgIamPolicy: true
|
||||||
Users:
|
# Users:
|
||||||
- FirstName: 'Global Org'
|
# - FirstName: 'Global Org'
|
||||||
LastName: 'Administrator'
|
# LastName: 'Administrator'
|
||||||
UserName: 'zitadel-global-org-admin@caos.ch'
|
# UserName: 'zitadel-global-org-admin@caos.ch'
|
||||||
Email: 'zitadel-global-org-admin@caos.ch'
|
# Email: 'zitadel-global-org-admin@caos.ch'
|
||||||
Password: 'Password1!'
|
# Password: 'Password1!'
|
||||||
Owners:
|
# Owners:
|
||||||
- 'zitadel-global-org-admin@caos.ch'
|
# - 'zitadel-global-org-admin@caos.ch'
|
||||||
- Name: 'CAOS AG'
|
# - Name: 'CAOS AG'
|
||||||
Domain: 'caos.ch'
|
# Domain: 'caos.ch'
|
||||||
Users:
|
# Users:
|
||||||
- FirstName: 'Zitadel'
|
# - FirstName: 'Zitadel'
|
||||||
LastName: 'Administrator'
|
# LastName: 'Administrator'
|
||||||
UserName: 'zitadel-admin'
|
# UserName: 'zitadel-admin'
|
||||||
Email: 'zitadel-admin@caos.ch'
|
# Email: 'zitadel-admin@caos.ch'
|
||||||
Password: 'Password1!'
|
# Password: 'Password1!'
|
||||||
Owners:
|
# Owners:
|
||||||
- 'zitadel-admin@caos.ch'
|
# - 'zitadel-admin@caos.ch'
|
||||||
Projects:
|
# Projects:
|
||||||
- Name: 'Zitadel'
|
# - Name: 'Zitadel'
|
||||||
OIDCApps:
|
# OIDCApps:
|
||||||
- Name: 'Management-API'
|
# - Name: 'Management-API'
|
||||||
- Name: 'Auth-API'
|
# - Name: 'Auth-API'
|
||||||
- Name: 'Admin-API'
|
# - Name: 'Admin-API'
|
||||||
- Name: 'Zitadel Console'
|
# - Name: 'Zitadel Console'
|
||||||
RedirectUris:
|
# RedirectUris:
|
||||||
- '$ZITADEL_CONSOLE/auth/callback'
|
# - '$ZITADEL_CONSOLE/auth/callback'
|
||||||
PostLogoutRedirectUris:
|
# PostLogoutRedirectUris:
|
||||||
- '$ZITADEL_CONSOLE/signedout'
|
# - '$ZITADEL_CONSOLE/signedout'
|
||||||
ResponseTypes:
|
# ResponseTypes:
|
||||||
- $ZITADEL_CONSOLE_RESPONSE_TYPE
|
# - $ZITADEL_CONSOLE_RESPONSE_TYPE
|
||||||
GrantTypes:
|
# GrantTypes:
|
||||||
- $ZITADEL_CONSOLE_GRANT_TYPE
|
# - $ZITADEL_CONSOLE_GRANT_TYPE
|
||||||
ApplicationType: 'USER_AGENT'
|
# ApplicationType: 'USER_AGENT'
|
||||||
AuthMethodType: 'NONE'
|
# AuthMethodType: 'NONE'
|
||||||
DevMode: $ZITADEL_CONSOLE_DEV_MODE
|
# DevMode: $ZITADEL_CONSOLE_DEV_MODE
|
||||||
Owners:
|
# Owners:
|
||||||
- 'zitadel-admin@caos.ch'
|
# - 'zitadel-admin@caos.ch'
|
||||||
Step2:
|
Step2:
|
||||||
DefaultPasswordComplexityPolicy:
|
DefaultPasswordComplexityPolicy:
|
||||||
MinLength: 8
|
MinLength: 8
|
||||||
|
@ -2,6 +2,7 @@ package eventstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
@ -18,7 +19,7 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||||
usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
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 {
|
type IAMRepository struct {
|
||||||
@ -30,7 +31,8 @@ type IAMRepository struct {
|
|||||||
SystemDefaults systemdefaults.SystemDefaults
|
SystemDefaults systemdefaults.SystemDefaults
|
||||||
Roles []string
|
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) {
|
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) {
|
func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||||
member.AggregateID = repo.SystemDefaults.IamID
|
member.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddMember(ctx, member)
|
return repo.IAMV2Command.AddIAMMember(ctx, member)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddIAMMember(ctx, member)
|
return repo.IAMEventstore.AddIAMMember(ctx, member)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||||
member.AggregateID = repo.SystemDefaults.IamID
|
member.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeMember(ctx, member)
|
return repo.IAMV2Command.ChangeIAMMember(ctx, member)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeIAMMember(ctx, member)
|
return repo.IAMEventstore.ChangeIAMMember(ctx, member)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error {
|
func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error {
|
||||||
member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID)
|
member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID)
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.RemoveMember(ctx, member)
|
return repo.IAMV2Command.RemoveIAMMember(ctx, member)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.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) {
|
func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.IDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
return repo.IAMV2Query.DefaultIDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||||
}
|
}
|
||||||
|
|
||||||
idp, err := repo.View.IDPConfigByID(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) {
|
func (repo *IAMRepository) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||||
idp.AggregateID = repo.SystemDefaults.IamID
|
idp.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddIDPConfig(ctx, idp)
|
return repo.IAMV2Command.AddDefaultIDPConfig(ctx, idp)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddIDPConfig(ctx, idp)
|
return repo.IAMEventstore.AddIDPConfig(ctx, idp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
func (repo *IAMRepository) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) {
|
||||||
idp.AggregateID = repo.SystemDefaults.IamID
|
idp.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeIDPConfig(ctx, idp)
|
return repo.IAMV2Command.ChangeDefaultIDPConfig(ctx, idp)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeIDPConfig(ctx, idp)
|
return repo.IAMEventstore.ChangeIDPConfig(ctx, idp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) DeactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
func (repo *IAMRepository) DeactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.DeactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
return repo.IAMV2Command.DeactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.DeactivateIDPConfig(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) {
|
func (repo *IAMRepository) ReactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
return repo.IAMV2Command.ReactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
return repo.IAMEventstore.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error {
|
func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error {
|
||||||
// if repo.IAMV2 != nil {
|
// if repo.IAMV2Command != nil {
|
||||||
// return repo.IAMV2.
|
// return repo.IAMV2Command.
|
||||||
// }
|
// }
|
||||||
aggregates := make([]*es_models.Aggregate, 0)
|
aggregates := make([]*es_models.Aggregate, 0)
|
||||||
idp := iam_model.NewIDPConfig(repo.SystemDefaults.IamID, idpConfigID)
|
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) {
|
func (repo *IAMRepository) ChangeOidcIDPConfig(ctx context.Context, oidcConfig *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) {
|
||||||
oidcConfig.AggregateID = repo.SystemDefaults.IamID
|
oidcConfig.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeIDPOIDCConfig(ctx, oidcConfig)
|
return repo.IAMV2Command.ChangeDefaultIDPOIDCConfig(ctx, oidcConfig)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeIDPOIDCConfig(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) {
|
func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddLabelPolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultLabelPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddLabelPolicy(ctx, policy)
|
return repo.IAMEventstore.AddLabelPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeLabelPolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultLabelPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeLabelPolicy(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) {
|
func (repo *IAMRepository) AddDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddLoginPolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultLoginPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddLoginPolicy(ctx, policy)
|
return repo.IAMEventstore.AddLoginPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeLoginPolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultLoginPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeLoginPolicy(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) {
|
func (repo *IAMRepository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) {
|
||||||
provider.AggregateID = repo.SystemDefaults.IamID
|
provider.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddIDPProviderToLoginPolicy(ctx, provider)
|
return repo.IAMV2Command.AddIDPProviderToDefaultLoginPolicy(ctx, provider)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddIDPProviderToLoginPolicy(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) {
|
func (repo *IAMRepository) AddSecondFactorToLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddSecondFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
return repo.IAMV2Command.AddSecondFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddSecondFactorToLoginPolicy(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 {
|
func (repo *IAMRepository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) error {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.RemoveSecondFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
return repo.IAMV2Command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.RemoveSecondFactorFromLoginPolicy(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) {
|
func (repo *IAMRepository) AddMultiFactorToLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddMultiFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
return repo.IAMV2Command.AddMultiFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddMultiFactorToLoginPolicy(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 {
|
func (repo *IAMRepository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) error {
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.RemoveMultiFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
return repo.IAMV2Command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.RemoveMultiFactorFromLoginPolicy(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) {
|
func (repo *IAMRepository) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddPasswordComplexityPolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultPasswordComplexityPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddPasswordComplexityPolicy(ctx, policy)
|
return repo.IAMEventstore.AddPasswordComplexityPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangePasswordComplexityPolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultPasswordComplexityPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangePasswordComplexityPolicy(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) {
|
func (repo *IAMRepository) AddDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddPasswordAgePolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultPasswordAgePolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddPasswordAgePolicy(ctx, policy)
|
return repo.IAMEventstore.AddPasswordAgePolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangePasswordAgePolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultPasswordAgePolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangePasswordAgePolicy(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) {
|
func (repo *IAMRepository) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddPasswordLockoutPolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultPasswordLockoutPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddPasswordLockoutPolicy(ctx, policy)
|
return repo.IAMEventstore.AddPasswordLockoutPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangePasswordLockoutPolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultPasswordLockoutPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangePasswordLockoutPolicy(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) {
|
func (repo *IAMRepository) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.AddOrgIAMPolicy(ctx, policy)
|
return repo.IAMV2Command.AddDefaultOrgIAMPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.AddOrgIAMPolicy(ctx, policy)
|
return repo.IAMEventstore.AddOrgIAMPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
func (repo *IAMRepository) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) {
|
||||||
policy.AggregateID = repo.SystemDefaults.IamID
|
policy.AggregateID = repo.SystemDefaults.IamID
|
||||||
if repo.IAMV2 != nil {
|
if repo.IAMV2Command != nil {
|
||||||
return repo.IAMV2.ChangeOrgIAMPolicy(ctx, policy)
|
return repo.IAMV2Command.ChangeDefaultOrgIAMPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy)
|
return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"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/eventstore"
|
||||||
"github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler"
|
"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_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||||
es_usr "github.com/caos/zitadel/internal/user/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 {
|
type Config struct {
|
||||||
@ -65,7 +66,11 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -90,7 +95,8 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r
|
|||||||
SystemDefaults: systemDefaults,
|
SystemDefaults: systemDefaults,
|
||||||
SearchLimit: conf.SearchLimit,
|
SearchLimit: conf.SearchLimit,
|
||||||
Roles: roles,
|
Roles: roles,
|
||||||
IAMV2: iamV2,
|
IAMV2Command: iamV2Command,
|
||||||
|
IAMV2Query: iamV2Query,
|
||||||
},
|
},
|
||||||
AdministratorRepo: eventstore.AdministratorRepo{
|
AdministratorRepo: eventstore.AdministratorRepo{
|
||||||
View: view,
|
View: view,
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
auth_es "github.com/caos/zitadel/internal/auth/repository/eventsourcing"
|
auth_es "github.com/caos/zitadel/internal/auth/repository/eventsourcing"
|
||||||
"github.com/caos/zitadel/internal/telemetry/metrics"
|
"github.com/caos/zitadel/internal/telemetry/metrics"
|
||||||
"github.com/caos/zitadel/internal/telemetry/metrics/otel"
|
"github.com/caos/zitadel/internal/telemetry/metrics/otel"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
view_model "github.com/caos/zitadel/internal/view/model"
|
view_model "github.com/caos/zitadel/internal/view/model"
|
||||||
"go.opentelemetry.io/otel/api/metric"
|
"go.opentelemetry.io/otel/api/metric"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -98,10 +99,10 @@ func (a *API) healthHandler() http.Handler {
|
|||||||
if err != nil && !errors.IsNotFound(err) {
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED")
|
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")
|
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 errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,6 +2,7 @@ package management
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
"github.com/caos/zitadel/pkg/grpc/management"
|
"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 {
|
switch step {
|
||||||
case iam_model.Step1:
|
case domain.Step1:
|
||||||
return management.IamSetupStep_iam_setup_step_1
|
return management.IamSetupStep_iam_setup_step_1
|
||||||
case iam_model.Step2:
|
case domain.Step2:
|
||||||
return management.IamSetupStep_iam_setup_step_2
|
return management.IamSetupStep_iam_setup_step_2
|
||||||
// case iam_model.Step3:
|
// case iam_model.Step3:
|
||||||
// return management.IamSetupStep_iam_setup_step_3
|
// return management.IamSetupStep_iam_setup_step_3
|
||||||
|
@ -2,17 +2,17 @@ package eventstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/iam/model"
|
"github.com/caos/zitadel/internal/iam/model"
|
||||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAMRepository struct {
|
type IAMRepository struct {
|
||||||
IAMID string
|
IAMID string
|
||||||
|
|
||||||
IAMV2 *iam_business.Repository
|
IAMV2QuerySide *query.QuerySide
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) GetIAM(ctx context.Context) (*model.IAM, error) {
|
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"
|
"strings"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
caos_errs "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"
|
||||||
"github.com/caos/zitadel/internal/eventstore/models"
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
"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_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||||
org_model "github.com/caos/zitadel/internal/org/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"
|
usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model"
|
||||||
grant_es_model "github.com/caos/zitadel/internal/usergrant/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"
|
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserGrant struct {
|
type UserGrant struct {
|
||||||
@ -308,7 +309,7 @@ func (u *UserGrant) setIamProjectID() error {
|
|||||||
return err
|
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")
|
return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done")
|
||||||
}
|
}
|
||||||
u.iamProjectID = iam.IAMProjectID
|
u.iamProjectID = iam.IAMProjectID
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing"
|
||||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||||
es_user "github.com/caos/zitadel/internal/user/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 {
|
type Config struct {
|
||||||
@ -110,7 +110,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
|
|||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -182,8 +182,8 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au
|
|||||||
SystemDefaults: systemDefaults,
|
SystemDefaults: systemDefaults,
|
||||||
},
|
},
|
||||||
eventstore.IAMRepository{
|
eventstore.IAMRepository{
|
||||||
IAMID: systemDefaults.IamID,
|
IAMID: systemDefaults.IamID,
|
||||||
IAMV2: iamV2,
|
IAMV2QuerySide: iamV2Query,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,17 @@ package eventstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/iam/model"
|
"github.com/caos/zitadel/internal/iam/model"
|
||||||
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IamRepo struct {
|
type IamRepo struct {
|
||||||
IAMID string
|
IAMID string
|
||||||
IAMEvents *iam_event.IAMEventstore
|
IAMEvents *iam_event.IAMEventstore
|
||||||
|
|
||||||
IAMV2 *iam_business.Repository
|
IAMV2Query *query.QuerySide
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IamRepo) Health(ctx context.Context) error {
|
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) {
|
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/api/authz"
|
||||||
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
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"
|
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||||
grant_model "github.com/caos/zitadel/internal/usergrant/model"
|
grant_model "github.com/caos/zitadel/internal/usergrant/model"
|
||||||
"github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
"github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserGrantRepo struct {
|
type UserGrantRepo struct {
|
||||||
@ -72,7 +72,7 @@ func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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")
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-skiwS", "Setup not done")
|
||||||
}
|
}
|
||||||
repo.IamProjectID = iam.IAMProjectID
|
repo.IamProjectID = iam.IAMProjectID
|
||||||
|
@ -12,12 +12,12 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/eventstore/models"
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/eventstore/spooler"
|
"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_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||||
org_es_model "github.com/caos/zitadel/internal/org/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"
|
proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
|
||||||
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserGrant struct {
|
type UserGrant struct {
|
||||||
@ -224,7 +224,7 @@ func (u *UserGrant) setIamProjectID() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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")
|
return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done")
|
||||||
}
|
}
|
||||||
u.iamProjectID = iam.IAMProjectID
|
u.iamProjectID = iam.IAMProjectID
|
||||||
|
@ -2,6 +2,7 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
|
|
||||||
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||||
|
|
||||||
@ -19,7 +20,6 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/id"
|
"github.com/caos/zitadel/internal/id"
|
||||||
es_key "github.com/caos/zitadel/internal/key/repository/eventsourcing"
|
es_key "github.com/caos/zitadel/internal/key/repository/eventsourcing"
|
||||||
es_proj "github.com/caos/zitadel/internal/project/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 {
|
type Config struct {
|
||||||
@ -79,7 +79,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -96,9 +96,9 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (*
|
|||||||
IamEvents: iam,
|
IamEvents: iam,
|
||||||
},
|
},
|
||||||
eventstore.IamRepo{
|
eventstore.IamRepo{
|
||||||
IAMID: systemDefaults.IamID,
|
IAMID: systemDefaults.IamID,
|
||||||
IAMEvents: iam,
|
IAMEvents: iam,
|
||||||
IAMV2: iamV2,
|
IAMV2Query: iamV2,
|
||||||
},
|
},
|
||||||
eventstore.TokenVerifierRepo{
|
eventstore.TokenVerifierRepo{
|
||||||
//TODO: Add Token Verification Key
|
//TODO: Add Token Verification Key
|
||||||
|
@ -59,7 +59,7 @@ func (data *Data) createTemplate(templateName string, file *os.File) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func readErrorName() (errorName string) {
|
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()
|
flag.Parse()
|
||||||
return errorName
|
return errorName
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package eventstore
|
|||||||
type aggregater interface {
|
type aggregater interface {
|
||||||
//ID returns the aggreagte id
|
//ID returns the aggreagte id
|
||||||
ID() string
|
ID() string
|
||||||
//Type returns the aggregate type
|
//KeyType returns the aggregate type
|
||||||
Type() AggregateType
|
Type() AggregateType
|
||||||
//Events returns the events which will be pushed
|
//Events returns the events which will be pushed
|
||||||
Events() []EventPusher
|
Events() []EventPusher
|
||||||
@ -74,7 +74,7 @@ func (a *Aggregate) ID() string {
|
|||||||
return a.id
|
return a.id
|
||||||
}
|
}
|
||||||
|
|
||||||
//Type implements aggregater
|
//KeyType implements aggregater
|
||||||
func (a *Aggregate) Type() AggregateType {
|
func (a *Aggregate) Type() AggregateType {
|
||||||
return a.typ
|
return a.typ
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ type EventPusher interface {
|
|||||||
EditorService() string
|
EditorService() string
|
||||||
//EditorUser is the user who wants to push the event
|
//EditorUser is the user who wants to push the event
|
||||||
EditorUser() string
|
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
|
Type() EventType
|
||||||
//Data returns the payload of the event. It represent the changed fields by the event
|
//Data returns the payload of the event. It represent the changed fields by the event
|
||||||
// valid types are:
|
// valid types are:
|
||||||
@ -25,7 +25,7 @@ type EventReader interface {
|
|||||||
EditorService() string
|
EditorService() string
|
||||||
//EditorUser is the user who pushed the event
|
//EditorUser is the user who pushed the event
|
||||||
EditorUser() string
|
EditorUser() string
|
||||||
//Type is the type of the event
|
//KeyType is the type of the event
|
||||||
Type() EventType
|
Type() EventType
|
||||||
|
|
||||||
AggregateID() string
|
AggregateID() string
|
||||||
|
@ -36,7 +36,7 @@ func (e *BaseEvent) EditorUser() string {
|
|||||||
return e.User
|
return e.User
|
||||||
}
|
}
|
||||||
|
|
||||||
//Type implements EventPusher
|
//KeyType implements EventPusher
|
||||||
func (e *BaseEvent) Type() EventType {
|
func (e *BaseEvent) Type() EventType {
|
||||||
return e.EventType
|
return e.EventType
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"log"
|
"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
|
// it might be saved in a database or in memory
|
||||||
type ReadModel struct {
|
type ReadModel struct {
|
||||||
ProcessedSequence uint64
|
ProcessedSequence uint64
|
||||||
|
@ -2,7 +2,7 @@ package eventstore
|
|||||||
|
|
||||||
import "time"
|
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 implements a basic reducer
|
||||||
// it might be saved in a database or in memory
|
// it might be saved in a database or in memory
|
||||||
type ReadModel struct {
|
type ReadModel struct {
|
||||||
|
@ -26,7 +26,7 @@ type Event struct {
|
|||||||
// time drifts in different services could cause integrity problems
|
// time drifts in different services could cause integrity problems
|
||||||
CreationDate time.Time
|
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
|
// it should always be in past-form
|
||||||
Type EventType
|
Type EventType
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package eventstore
|
|||||||
|
|
||||||
import "time"
|
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 implements a basic reducer
|
||||||
// it's purpose is to reduce events to create new ones
|
// it's purpose is to reduce events to create new ones
|
||||||
type WriteModel struct {
|
type WriteModel struct {
|
||||||
|
@ -2,6 +2,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Step int
|
type Step int
|
||||||
@ -23,8 +24,8 @@ type IAM struct {
|
|||||||
es_models.ObjectRoot
|
es_models.ObjectRoot
|
||||||
GlobalOrgID string
|
GlobalOrgID string
|
||||||
IAMProjectID string
|
IAMProjectID string
|
||||||
SetUpDone Step
|
SetUpDone domain.Step
|
||||||
SetUpStarted Step
|
SetUpStarted domain.Step
|
||||||
Members []*IAMMember
|
Members []*IAMMember
|
||||||
IDPs []*IDPConfig
|
IDPs []*IDPConfig
|
||||||
DefaultLoginPolicy *LoginPolicy
|
DefaultLoginPolicy *LoginPolicy
|
||||||
|
@ -22,6 +22,8 @@ type PasswordComplexityPolicy struct {
|
|||||||
HasUppercase bool
|
HasUppercase bool
|
||||||
HasNumber bool
|
HasNumber bool
|
||||||
HasSymbol bool
|
HasSymbol bool
|
||||||
|
|
||||||
|
Default bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PasswordComplexityPolicy) IsValid() error {
|
func (p *PasswordComplexityPolicy) IsValid() error {
|
||||||
@ -30,3 +32,26 @@ func (p *PasswordComplexityPolicy) IsValid() error {
|
|||||||
}
|
}
|
||||||
return nil
|
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)
|
return es.FilterEvents(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
//func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||||
iam, err := es.IAMByID(ctx, iamID)
|
// iam, err := es.IAMByID(ctx, iamID)
|
||||||
if err != nil && !caos_errs.IsNotFound(err) {
|
// if err != nil && !caos_errs.IsNotFound(err) {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) {
|
// if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started")
|
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if iam == nil {
|
// if iam == nil {
|
||||||
iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}}
|
// iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}}
|
||||||
}
|
// }
|
||||||
iam.SetUpStarted = step
|
// iam.SetUpStarted = step
|
||||||
repoIAM := model.IAMFromModel(iam)
|
// repoIAM := model.IAMFromModel(iam)
|
||||||
|
//
|
||||||
createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM)
|
// createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM)
|
||||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate)
|
// err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
es.iamCache.cacheIAM(repoIAM)
|
// es.iamCache.cacheIAM(repoIAM)
|
||||||
return model.IAMToModel(repoIAM), nil
|
// return model.IAMToModel(repoIAM), nil
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
//func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) {
|
||||||
iam, err := es.IAMByID(ctx, iamID)
|
// iam, err := es.IAMByID(ctx, iamID)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
iam.SetUpDone = step
|
// iam.SetUpDone = step
|
||||||
|
//
|
||||||
repoIam := model.IAMFromModel(iam)
|
// repoIam := model.IAMFromModel(iam)
|
||||||
createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam)
|
// createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam)
|
||||||
err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
// err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
es.iamCache.cacheIAM(repoIam)
|
// es.iamCache.cacheIAM(repoIam)
|
||||||
return model.IAMToModel(repoIam), nil
|
// 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) {
|
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)
|
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)
|
t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID)
|
||||||
}
|
}
|
||||||
if result.Type != tt.res.result.Type {
|
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"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/iam/model"
|
"github.com/caos/zitadel/internal/iam/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -75,8 +76,8 @@ func IAMToModel(iam *IAM) *model.IAM {
|
|||||||
idps := IDPConfigsToModel(iam.IDPs)
|
idps := IDPConfigsToModel(iam.IDPs)
|
||||||
converted := &model.IAM{
|
converted := &model.IAM{
|
||||||
ObjectRoot: iam.ObjectRoot,
|
ObjectRoot: iam.ObjectRoot,
|
||||||
SetUpStarted: model.Step(iam.SetUpStarted),
|
SetUpStarted: domain.Step(iam.SetUpStarted),
|
||||||
SetUpDone: model.Step(iam.SetUpDone),
|
SetUpDone: domain.Step(iam.SetUpDone),
|
||||||
GlobalOrgID: iam.GlobalOrgID,
|
GlobalOrgID: iam.GlobalOrgID,
|
||||||
IAMProjectID: iam.IAMProjectID,
|
IAMProjectID: iam.IAMProjectID,
|
||||||
Members: members,
|
Members: members,
|
||||||
|
@ -2,15 +2,15 @@ package eventstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
iam_business "github.com/caos/zitadel/internal/v2/business/iam"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAMRepository struct {
|
type IAMRepository struct {
|
||||||
IAMV2 *iam_business.Repository
|
IAMV2Query *query.QuerySide
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *IAMRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) {
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/caos/zitadel/internal/v2/query"
|
||||||
|
|
||||||
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
sd "github.com/caos/zitadel/internal/config/systemdefaults"
|
||||||
"github.com/caos/zitadel/internal/config/types"
|
"github.com/caos/zitadel/internal/config/types"
|
||||||
@ -17,7 +18,6 @@ import (
|
|||||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||||
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||||
es_grant "github.com/caos/zitadel/internal/usergrant/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 {
|
type Config struct {
|
||||||
@ -75,7 +75,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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},
|
UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults},
|
||||||
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
|
UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view},
|
||||||
IAMRepository: eventstore.IAMRepository{
|
IAMRepository: eventstore.IAMRepository{
|
||||||
IAMV2: iamV2,
|
IAMV2Query: iamV2Query,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ func (msg *EmailMessage) GetContent() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//default mime-type is html
|
//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) {
|
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
|
subject := "Subject: " + msg.Subject + lineBreak
|
||||||
message += subject + mime + lineBreak + msg.Content
|
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)
|
t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID)
|
||||||
}
|
}
|
||||||
if result.Type != tt.res.result.Type {
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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) {
|
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||||
t.Errorf("got wrong err: %v ", err)
|
t.Errorf("got wrong err: %v ", err)
|
||||||
return
|
return
|
||||||
@ -509,7 +509,7 @@ func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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) {
|
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||||
t.Errorf("got wrong err: %v ", err)
|
t.Errorf("got wrong err: %v ", err)
|
||||||
return
|
return
|
||||||
@ -682,7 +682,7 @@ func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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) {
|
if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) {
|
||||||
t.Errorf("got wrong err: %v ", err)
|
t.Errorf("got wrong err: %v ", err)
|
||||||
return
|
return
|
||||||
|
@ -7,28 +7,28 @@ import (
|
|||||||
|
|
||||||
type IAMSetUp struct {
|
type IAMSetUp struct {
|
||||||
Step1 *Step1
|
Step1 *Step1
|
||||||
Step2 *Step2
|
//Step2 *Step2
|
||||||
Step3 *Step3
|
//Step3 *Step3
|
||||||
Step4 *Step4
|
//Step4 *Step4
|
||||||
Step5 *Step5
|
//Step5 *Step5
|
||||||
Step6 *Step6
|
//Step6 *Step6
|
||||||
Step7 *Step7
|
//Step7 *Step7
|
||||||
Step8 *Step8
|
//Step8 *Step8
|
||||||
}
|
}
|
||||||
|
|
||||||
func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]step, error) {
|
func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]stepV2, error) {
|
||||||
steps := make([]step, 0)
|
steps := make([]stepV2, 0)
|
||||||
missingSteps := make([]iam_model.Step, 0)
|
missingSteps := make([]iam_model.Step, 0)
|
||||||
|
|
||||||
for _, step := range []step{
|
for _, step := range []stepV2{
|
||||||
setup.Step1,
|
setup.Step1,
|
||||||
setup.Step2,
|
//setup.Step2,
|
||||||
setup.Step3,
|
//setup.Step3,
|
||||||
setup.Step4,
|
//setup.Step4,
|
||||||
setup.Step5,
|
//setup.Step5,
|
||||||
setup.Step6,
|
//setup.Step6,
|
||||||
setup.Step7,
|
//setup.Step7,
|
||||||
setup.Step8,
|
//setup.Step8,
|
||||||
} {
|
} {
|
||||||
if step.step() <= currentDone {
|
if step.step() <= currentDone {
|
||||||
continue
|
continue
|
||||||
|
@ -3,24 +3,12 @@ package setup
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/api/authz"
|
"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"
|
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"
|
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"
|
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"
|
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
|
||||||
|
"github.com/caos/zitadel/internal/v2/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Setup struct {
|
type Setup struct {
|
||||||
@ -29,6 +17,8 @@ type Setup struct {
|
|||||||
OrgEvents *org_event.OrgEventstore
|
OrgEvents *org_event.OrgEventstore
|
||||||
UserEvents *usr_event.UserEventstore
|
UserEvents *usr_event.UserEventstore
|
||||||
ProjectEvents *proj_event.ProjectEventstore
|
ProjectEvents *proj_event.ProjectEventstore
|
||||||
|
|
||||||
|
Commands *command.CommandSide
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -48,168 +38,169 @@ const (
|
|||||||
OIDCAuthMethodTypePost = "POST"
|
OIDCAuthMethodTypePost = "POST"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
//
|
||||||
setup := &Setup{
|
//func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) {
|
||||||
iamID: sd.IamID,
|
// setup := &Setup{
|
||||||
}
|
// iamID: sd.IamID,
|
||||||
es, err := es_int.Start(esConfig)
|
// }
|
||||||
if err != nil {
|
// es, err := es_int.Start(esConfig)
|
||||||
return nil, err
|
// if err != nil {
|
||||||
}
|
// return nil, err
|
||||||
|
// }
|
||||||
setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{
|
//
|
||||||
Eventstore: es,
|
// setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{
|
||||||
Cache: esConfig.Cache,
|
// Eventstore: es,
|
||||||
}, sd)
|
// Cache: esConfig.Cache,
|
||||||
if err != nil {
|
// }, sd)
|
||||||
return nil, err
|
// if err != nil {
|
||||||
}
|
// return nil, err
|
||||||
|
// }
|
||||||
setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd)
|
//
|
||||||
|
// 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,
|
// setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{
|
||||||
Cache: esConfig.Cache,
|
// Eventstore: es,
|
||||||
}, sd)
|
// Cache: esConfig.Cache,
|
||||||
if err != nil {
|
// }, sd)
|
||||||
return nil, err
|
// if err != nil {
|
||||||
}
|
// return nil, err
|
||||||
|
// }
|
||||||
setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{
|
//
|
||||||
Eventstore: es,
|
// setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{
|
||||||
Cache: esConfig.Cache,
|
// Eventstore: es,
|
||||||
}, sd)
|
// Cache: esConfig.Cache,
|
||||||
if err != nil {
|
// }, sd)
|
||||||
return nil, err
|
// if err != nil {
|
||||||
}
|
// return nil, err
|
||||||
|
// }
|
||||||
return setup, nil
|
//
|
||||||
}
|
// return setup, nil
|
||||||
|
//}
|
||||||
func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error {
|
//
|
||||||
logging.Log("SETUP-hwG32").Info("starting setup")
|
//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) {
|
// iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||||
return err
|
// 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")
|
// if iam != nil && (iam.SetUpDone == domain.Step(iam_model.StepCount)-1 || iam.SetUpStarted != iam.SetUpDone) {
|
||||||
return nil
|
// logging.Log("SETUP-cWEsn").Info("all steps done")
|
||||||
}
|
// return nil
|
||||||
|
// }
|
||||||
if iam == nil {
|
//
|
||||||
iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}}
|
// 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 {
|
// steps, err := setUpConfig.steps(iam_model.Step(iam.SetUpDone))
|
||||||
return err
|
// if err != nil || len(steps) == 0 {
|
||||||
}
|
// return err
|
||||||
|
// }
|
||||||
ctx = setSetUpContextData(ctx, s.iamID)
|
//
|
||||||
|
// ctx = setSetUpContextData(ctx, s.iamID)
|
||||||
for _, step := range steps {
|
//
|
||||||
step.init(s)
|
// for _, step := range steps {
|
||||||
if step.step() != iam.SetUpDone+1 {
|
// step.init(s)
|
||||||
logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order")
|
// if step.step() != iam_model.Step(iam.SetUpDone)+1 {
|
||||||
return errors.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison")
|
// 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 {
|
// iam, err = s.IamEvents.StartSetup(ctx, s.iamID, step.step())
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
|
// }
|
||||||
iam, err = step.execute(ctx)
|
//
|
||||||
if err != nil {
|
// iam, err = step.execute(ctx)
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
|
// }
|
||||||
err = s.validateExecutedStep(ctx)
|
//
|
||||||
if err != nil {
|
// err = s.validateExecutedStep(ctx)
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
logging.Log("SETUP-ds31h").Info("setup done")
|
//
|
||||||
return nil
|
// 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)
|
//func (s *Setup) validateExecutedStep(ctx context.Context) error {
|
||||||
if err != nil {
|
// iam, err := s.IamEvents.IAMByID(ctx, s.iamID)
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
if iam.SetUpStarted != iam.SetUpDone {
|
// }
|
||||||
return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done")
|
// if iam.SetUpStarted != iam.SetUpDone {
|
||||||
}
|
// return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done")
|
||||||
return nil
|
// }
|
||||||
}
|
// return nil
|
||||||
|
//}
|
||||||
func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType {
|
//
|
||||||
types := make([]proj_model.OIDCResponseType, len(responseTypes))
|
//func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType {
|
||||||
for i, t := range responseTypes {
|
// types := make([]proj_model.OIDCResponseType, len(responseTypes))
|
||||||
types[i] = getOIDCResponseType(t)
|
// for i, t := range responseTypes {
|
||||||
}
|
// types[i] = getOIDCResponseType(t)
|
||||||
return types
|
// }
|
||||||
}
|
// return types
|
||||||
|
//}
|
||||||
func getOIDCResponseType(responseType string) proj_model.OIDCResponseType {
|
//
|
||||||
switch responseType {
|
//func getOIDCResponseType(responseType string) proj_model.OIDCResponseType {
|
||||||
case OIDCResponseTypeCode:
|
// switch responseType {
|
||||||
return proj_model.OIDCResponseTypeCode
|
// case OIDCResponseTypeCode:
|
||||||
case OIDCResponseTypeIDToken:
|
// return proj_model.OIDCResponseTypeCode
|
||||||
return proj_model.OIDCResponseTypeIDToken
|
// case OIDCResponseTypeIDToken:
|
||||||
case OIDCResponseTypeToken:
|
// return proj_model.OIDCResponseTypeIDToken
|
||||||
return proj_model.OIDCResponseTypeIDTokenToken
|
// case OIDCResponseTypeToken:
|
||||||
}
|
// return proj_model.OIDCResponseTypeIDTokenToken
|
||||||
return proj_model.OIDCResponseTypeCode
|
// }
|
||||||
}
|
// return proj_model.OIDCResponseTypeCode
|
||||||
|
//}
|
||||||
func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType {
|
//
|
||||||
types := make([]proj_model.OIDCGrantType, len(grantTypes))
|
//func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType {
|
||||||
for i, t := range grantTypes {
|
// types := make([]proj_model.OIDCGrantType, len(grantTypes))
|
||||||
types[i] = getOIDCGrantType(t)
|
// for i, t := range grantTypes {
|
||||||
}
|
// types[i] = getOIDCGrantType(t)
|
||||||
return types
|
// }
|
||||||
}
|
// return types
|
||||||
|
//}
|
||||||
func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType {
|
//
|
||||||
switch grantTypes {
|
//func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType {
|
||||||
case OIDCGrantTypeAuthorizationCode:
|
// switch grantTypes {
|
||||||
return proj_model.OIDCGrantTypeAuthorizationCode
|
// case OIDCGrantTypeAuthorizationCode:
|
||||||
case OIDCGrantTypeImplicit:
|
// return proj_model.OIDCGrantTypeAuthorizationCode
|
||||||
return proj_model.OIDCGrantTypeImplicit
|
// case OIDCGrantTypeImplicit:
|
||||||
case OIDCGrantTypeRefreshToken:
|
// return proj_model.OIDCGrantTypeImplicit
|
||||||
return proj_model.OIDCGrantTypeRefreshToken
|
// case OIDCGrantTypeRefreshToken:
|
||||||
}
|
// return proj_model.OIDCGrantTypeRefreshToken
|
||||||
return proj_model.OIDCGrantTypeAuthorizationCode
|
// }
|
||||||
}
|
// return proj_model.OIDCGrantTypeAuthorizationCode
|
||||||
|
//}
|
||||||
func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType {
|
//
|
||||||
switch appType {
|
//func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType {
|
||||||
case OIDCApplicationTypeNative:
|
// switch appType {
|
||||||
return proj_model.OIDCApplicationTypeNative
|
// case OIDCApplicationTypeNative:
|
||||||
case OIDCApplicationTypeUserAgent:
|
// return proj_model.OIDCApplicationTypeNative
|
||||||
return proj_model.OIDCApplicationTypeUserAgent
|
// case OIDCApplicationTypeUserAgent:
|
||||||
case OIDCApplicationTypeWeb:
|
// return proj_model.OIDCApplicationTypeUserAgent
|
||||||
return proj_model.OIDCApplicationTypeWeb
|
// case OIDCApplicationTypeWeb:
|
||||||
}
|
// return proj_model.OIDCApplicationTypeWeb
|
||||||
return proj_model.OIDCApplicationTypeWeb
|
// }
|
||||||
}
|
// return proj_model.OIDCApplicationTypeWeb
|
||||||
|
//}
|
||||||
func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType {
|
//
|
||||||
switch authMethod {
|
//func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType {
|
||||||
case OIDCAuthMethodTypeNone:
|
// switch authMethod {
|
||||||
return proj_model.OIDCAuthMethodTypeNone
|
// case OIDCAuthMethodTypeNone:
|
||||||
case OIDCAuthMethodTypeBasic:
|
// return proj_model.OIDCAuthMethodTypeNone
|
||||||
return proj_model.OIDCAuthMethodTypeBasic
|
// case OIDCAuthMethodTypeBasic:
|
||||||
case OIDCAuthMethodTypePost:
|
// return proj_model.OIDCAuthMethodTypeBasic
|
||||||
return proj_model.OIDCAuthMethodTypePost
|
// case OIDCAuthMethodTypePost:
|
||||||
}
|
// return proj_model.OIDCAuthMethodTypePost
|
||||||
return proj_model.OIDCAuthMethodTypeBasic
|
// }
|
||||||
}
|
// return proj_model.OIDCAuthMethodTypeBasic
|
||||||
|
//}
|
||||||
|
//
|
||||||
func setSetUpContextData(ctx context.Context, orgID string) context.Context {
|
func setSetUpContextData(ctx context.Context, orgID string) context.Context {
|
||||||
return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser, OrgID: orgID})
|
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"
|
"context"
|
||||||
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type step interface {
|
type step interface {
|
||||||
@ -12,3 +13,9 @@ type step interface {
|
|||||||
init(*Setup)
|
init(*Setup)
|
||||||
isNil() bool
|
isNil() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stepV2 interface {
|
||||||
|
step() iam_model.Step
|
||||||
|
execute(context.Context, string, command.CommandSide) error
|
||||||
|
isNil() bool
|
||||||
|
}
|
||||||
|
@ -4,322 +4,287 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"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"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
org_model "github.com/caos/zitadel/internal/org/model"
|
"github.com/caos/zitadel/internal/v2/command"
|
||||||
proj_model "github.com/caos/zitadel/internal/project/model"
|
|
||||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Step1 struct {
|
type Step1 struct {
|
||||||
GlobalOrg string
|
//GlobalOrg string
|
||||||
IAMProject string
|
//IAMProject string
|
||||||
DefaultLoginPolicy LoginPolicy
|
//DefaultLoginPolicy LoginPolicy
|
||||||
Orgs []Org
|
//Orgs []Org
|
||||||
Owners []string
|
//Owners []string
|
||||||
|
command.Step1
|
||||||
|
|
||||||
setup *Setup
|
//setup *Setup
|
||||||
createdUsers map[string]*usr_model.User
|
//createdUsers map[string]*usr_model.User
|
||||||
createdOrgs map[string]*org_model.Org
|
//createdOrgs map[string]*org_model.Org
|
||||||
createdProjects map[string]*proj_model.Project
|
//createdProjects map[string]*proj_model.Project
|
||||||
pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
|
//pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Step1) isNil() bool {
|
func (s *Step1) isNil() bool {
|
||||||
return s == nil
|
return s == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (step *Step1) step() iam_model.Step {
|
func (s *Step1) step() iam_model.Step {
|
||||||
return iam_model.Step1
|
return iam_model.Step1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (step *Step1) init(setup *Setup) {
|
//func (s *Step1) init(setup *Setup) {
|
||||||
step.setup = setup
|
// s.setup = setup
|
||||||
step.createdUsers = make(map[string]*usr_model.User)
|
// s.createdUsers = make(map[string]*usr_model.User)
|
||||||
step.createdOrgs = make(map[string]*org_model.Org)
|
// s.createdOrgs = make(map[string]*org_model.Org)
|
||||||
step.createdProjects = make(map[string]*proj_model.Project)
|
// s.createdProjects = make(map[string]*proj_model.Project)
|
||||||
}
|
//}
|
||||||
|
|
||||||
func (step *Step1) execute(ctx context.Context) (*iam_model.IAM, error) {
|
func (s *Step1) execute(ctx context.Context, iamID string, commands command.CommandSide) error {
|
||||||
err := step.loginPolicy(ctx, step.DefaultLoginPolicy)
|
err := commands.SetupStep1(ctx, iamID, s.Step1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Log("SETUP-Hdu8S").WithError(err).Error("unable to create login policy")
|
logging.Log("SETUP-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup")
|
||||||
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")
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logging.Log("SETUP-d32h1").Info("global org set")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error {
|
//
|
||||||
logging.Log("SETUP-HE3qa").Info("setting iam project")
|
//func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error {
|
||||||
iamProject, ok := step.createdProjects[iamProjectName]
|
// logging.Log("SETUP-4djul").Info("setting up login policy")
|
||||||
if !ok {
|
// loginPolicy := &iam_model.LoginPolicy{
|
||||||
logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created")
|
// ObjectRoot: models.ObjectRoot{
|
||||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName)
|
// AggregateID: step.setup.iamID,
|
||||||
}
|
// },
|
||||||
|
// AllowRegister: policy.AllowRegister,
|
||||||
if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil {
|
// AllowUsernamePassword: policy.AllowUsernamePassword,
|
||||||
logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam")
|
// AllowExternalIdp: policy.AllowExternalIdp,
|
||||||
return err
|
// }
|
||||||
}
|
// _, err := step.setup.Commands.AddDefaultLoginPolicy(ctx, loginPolicy)
|
||||||
logging.Log("SETUP-d7WEU").Info("iam project set")
|
// return err
|
||||||
return nil
|
//}
|
||||||
}
|
//
|
||||||
|
//func (step *Step1) orgs(ctx context.Context, orgs []Org) error {
|
||||||
func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error {
|
// logging.Log("SETUP-dsTh3").Info("setting up orgs")
|
||||||
for _, user := range users {
|
// for _, iamOrg := range orgs {
|
||||||
created, err := step.user(ctx, user, orgPolicy)
|
// org, err := step.org(ctx, iamOrg)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user")
|
// logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org")
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
step.createdUsers[user.Email] = created
|
// step.createdOrgs[iamOrg.Name] = org
|
||||||
}
|
// logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation")
|
||||||
return nil
|
//
|
||||||
}
|
// var policy *iam_model.OrgIAMPolicyView
|
||||||
|
// if iamOrg.OrgIamPolicy {
|
||||||
func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) {
|
// policy, err = step.iamorgpolicy(ctx, org)
|
||||||
createUser := &usr_model.User{
|
// if err != nil {
|
||||||
UserName: user.UserName,
|
// logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy")
|
||||||
Human: &usr_model.Human{
|
// return err
|
||||||
Profile: &usr_model.Profile{
|
// }
|
||||||
FirstName: user.FirstName,
|
// } else {
|
||||||
LastName: user.LastName,
|
// policy = &iam_model.OrgIAMPolicyView{
|
||||||
},
|
// UserLoginMustBeDomain: true,
|
||||||
Email: &usr_model.Email{
|
// }
|
||||||
EmailAddress: user.Email,
|
// }
|
||||||
IsEmailVerified: true,
|
//
|
||||||
},
|
// ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||||
Password: &usr_model.Password{
|
// err = step.users(ctx, iamOrg.Users, policy)
|
||||||
SecretString: user.Password,
|
// if err != nil {
|
||||||
},
|
// logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users")
|
||||||
},
|
// return err
|
||||||
}
|
// }
|
||||||
return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy)
|
//
|
||||||
}
|
// err = step.orgOwners(ctx, org, iamOrg.Owners)
|
||||||
|
// if err != nil {
|
||||||
func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error {
|
// logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners")
|
||||||
for _, orgOwner := range owners {
|
// return err
|
||||||
user, ok := step.createdUsers[orgOwner]
|
// }
|
||||||
if !ok {
|
//
|
||||||
logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members")
|
// err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID)
|
||||||
return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner)
|
// if err != nil {
|
||||||
}
|
// logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects")
|
||||||
err := step.orgOwner(ctx, org, user)
|
// return err
|
||||||
if err != nil {
|
// }
|
||||||
logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org")
|
// }
|
||||||
return err
|
// logging.Log("SETUP-dgjT4").Info("orgs set up")
|
||||||
}
|
// return nil
|
||||||
}
|
//}
|
||||||
return nil
|
//
|
||||||
}
|
//func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) {
|
||||||
|
// ctx = setSetUpContextData(ctx, "")
|
||||||
func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error {
|
// createOrg := &org_model.Org{
|
||||||
addMember := &org_model.OrgMember{
|
// Name: org.Name,
|
||||||
ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
// Domains: []*org_model.OrgDomain{{Domain: org.Domain}},
|
||||||
UserID: user.AggregateID,
|
// }
|
||||||
Roles: []string{OrgOwnerRole},
|
// return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil)
|
||||||
}
|
//}
|
||||||
_, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember)
|
//
|
||||||
return err
|
//func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) {
|
||||||
}
|
// ctx = setSetUpContextData(ctx, org.AggregateID)
|
||||||
|
// policy := &iam_model.OrgIAMPolicy{
|
||||||
func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error {
|
// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
|
||||||
ctxData := authz.GetCtxData(ctx)
|
// UserLoginMustBeDomain: false,
|
||||||
ctxData.UserID = ownerID
|
// }
|
||||||
projectCtx := authz.SetCtxData(ctx, ctxData)
|
// createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy)
|
||||||
|
// if err != nil {
|
||||||
for _, project := range projects {
|
// return nil, err
|
||||||
createdProject, err := step.project(projectCtx, project)
|
// }
|
||||||
if err != nil {
|
// return &iam_model.OrgIAMPolicyView{
|
||||||
return err
|
// AggregateID: org.AggregateID,
|
||||||
}
|
// UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain,
|
||||||
step.createdProjects[createdProject.Name] = createdProject
|
// }, nil
|
||||||
for _, oidc := range project.OIDCApps {
|
//}
|
||||||
app, err := step.oidcApp(ctx, createdProject, oidc)
|
//
|
||||||
if err != nil {
|
//func (step *Step1) iamOwners(ctx context.Context, owners []string) error {
|
||||||
return err
|
// logging.Log("SETUP-dtxfj").Info("setting iam owners")
|
||||||
}
|
// for _, iamOwner := range owners {
|
||||||
logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application")
|
// user, ok := step.createdUsers[iamOwner]
|
||||||
}
|
// if !ok {
|
||||||
}
|
// logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members")
|
||||||
return nil
|
// 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"}})
|
||||||
func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) {
|
// if err != nil {
|
||||||
addProject := &proj_model.Project{
|
// logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner")
|
||||||
Name: project.Name,
|
// return err
|
||||||
}
|
// }
|
||||||
return step.setup.ProjectEvents.CreateProject(ctx, addProject, false)
|
// }
|
||||||
}
|
// logging.Log("SETUP-fg5aq").Info("iam owners set")
|
||||||
|
// return nil
|
||||||
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},
|
//func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error {
|
||||||
Name: oidc.Name,
|
// logging.Log("SETUP-dsj75").Info("setting global org")
|
||||||
OIDCConfig: &proj_model.OIDCConfig{
|
// globalOrg, ok := step.createdOrgs[globalOrgName]
|
||||||
RedirectUris: oidc.RedirectUris,
|
// if !ok {
|
||||||
ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes),
|
// logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created")
|
||||||
GrantTypes: getOIDCGrantTypes(oidc.GrantTypes),
|
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName)
|
||||||
ApplicationType: getOIDCApplicationType(oidc.ApplicationType),
|
// }
|
||||||
AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType),
|
//
|
||||||
PostLogoutRedirectUris: oidc.PostLogoutRedirectUris,
|
// if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil {
|
||||||
DevMode: oidc.DevMode,
|
// logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam")
|
||||||
},
|
// return err
|
||||||
}
|
// }
|
||||||
return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp)
|
// 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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/eventstore/models"
|
"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_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||||
|
"github.com/caos/zitadel/internal/v2/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Step2 struct {
|
type Step2 struct {
|
||||||
@ -27,23 +29,25 @@ func (step *Step2) init(setup *Setup) {
|
|||||||
step.setup = setup
|
step.setup = setup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (step *Step2) execute(ctx context.Context) (*iam_model.IAM, error) {
|
func (step *Step2) execute(ctx context.Context, commands command.CommandSide) error {
|
||||||
iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy)
|
//commands.SetupStep2(ctx, )
|
||||||
if err != nil {
|
//iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy)
|
||||||
logging.Log("SETUP-Ms9fl").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw complexity policy)")
|
//if err != nil {
|
||||||
return nil, err
|
// 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 {
|
//iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step())
|
||||||
logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)")
|
//if err != nil {
|
||||||
return nil, err
|
// 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 {
|
//err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg)
|
||||||
logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup")
|
//if err != nil {
|
||||||
return nil, err
|
// 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 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) {
|
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
|
NotLocked: Benutzer ist nicht gesperrt
|
||||||
NoChanges: Keine Änderungen gefunden
|
NoChanges: Keine Änderungen gefunden
|
||||||
InitCodeNotFound: Kein Initialisierungs Code gefunden
|
InitCodeNotFound: Kein Initialisierungs Code gefunden
|
||||||
ProfileNotFound: Profil nicht gefunden
|
Profile:
|
||||||
ProfileInvalid: Profildaten sind ungültig
|
NotFound: Profil nicht gefunden
|
||||||
EmailNotFound: Email nicht gefunden
|
NotChanged: Profile nicht verändert
|
||||||
EmailInvalid: Email ist ungültig
|
Invalid: Profildaten sind ungültig
|
||||||
EmailAlreadyVerified: Email ist bereits verifiziert
|
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
|
PhoneNotFound: Telfonnummer nicht gefunden
|
||||||
PhoneInvalid: Telefonnummer ist ungültig
|
PhoneInvalid: Telefonnummer ist ungültig
|
||||||
PhoneAlreadyVerified: Telefonnummer bereits verifiziert
|
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
|
NotHuman: Der Benutzer muss eine Person sein
|
||||||
NotMachine: Der Benutzer muss technisch sein
|
NotMachine: Der Benutzer muss technisch sein
|
||||||
NotAllowedToLink: Der Benutzer darf nicht mit einem externen Login Provider verlinkt werden
|
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
|
GrantHasNotExistingRole: Eine der Rollen existiert nicht auf dem Projekt
|
||||||
UserIDMisisng: User ID fehlt
|
UserIDMisisng: User ID fehlt
|
||||||
IAM:
|
IAM:
|
||||||
|
Member:
|
||||||
|
RolesNotChanged: Rollen wurden nicht verändert
|
||||||
MemberInvalid: Member ist ungültig
|
MemberInvalid: Member ist ungültig
|
||||||
MemberAlreadyExisting: Member existiert bereits
|
MemberAlreadyExisting: Member existiert bereits
|
||||||
MemberNotExisting: Member existiert nicht
|
MemberNotExisting: Member existiert nicht
|
||||||
@ -179,6 +187,7 @@ Errors:
|
|||||||
IdpProviderInvalid: Idp Provider ist ungültig
|
IdpProviderInvalid: Idp Provider ist ungültig
|
||||||
LoginPolicy:
|
LoginPolicy:
|
||||||
NotFound: Default Login Policy konnte nicht gefunden
|
NotFound: Default Login Policy konnte nicht gefunden
|
||||||
|
NotChanged: Default Login Policy wurde nicht verändert
|
||||||
NotExisting: Default Login Policy existiert nicht
|
NotExisting: Default Login Policy existiert nicht
|
||||||
AlreadyExists: Default Login Policy existiert bereits
|
AlreadyExists: Default Login Policy existiert bereits
|
||||||
IdpProviderAlreadyExisting: Idp Provider existiert bereits
|
IdpProviderAlreadyExisting: Idp Provider existiert bereits
|
||||||
@ -187,28 +196,41 @@ Errors:
|
|||||||
AlreadyExists: Multifaktor existiert bereits
|
AlreadyExists: Multifaktor existiert bereits
|
||||||
NotExisting: Multifaktor existiert nicht
|
NotExisting: Multifaktor existiert nicht
|
||||||
Unspecified: Multifaktor ungültig
|
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:
|
LabelPolicy:
|
||||||
NotFound: Default Private Label Policy konnte nicht gefunden
|
NotFound: Default Private Label Policy konnte nicht gefunden
|
||||||
|
NotChanged: Default Private Label Policy wurde nicht verändert
|
||||||
PasswordComplexityPolicy:
|
PasswordComplexityPolicy:
|
||||||
NotFound: Default Password Complexity Policy konnte nicht gefunden werden
|
NotFound: Default Password Complexity Policy konnte nicht gefunden werden
|
||||||
NotExisting: Default Password Complexity Policy existiert nicht
|
NotExisting: Default Password Complexity Policy existiert nicht
|
||||||
AlreadyExists: Default Password Complexity Policy existiert bereits
|
AlreadyExists: Default Password Complexity Policy existiert bereits
|
||||||
Empty: Default Password Complexity Policy leer
|
Empty: Default Password Complexity Policy leer
|
||||||
|
NotChanged: Default Password Complexity Policy wurde nicht verändert
|
||||||
PasswordAgePolicy:
|
PasswordAgePolicy:
|
||||||
NotFound: Default Password Age Policy konnte nicht gefunden werden
|
NotFound: Default Password Age Policy konnte nicht gefunden werden
|
||||||
NotExisting: Default Password Age Policy existiert nicht
|
NotExisting: Default Password Age Policy existiert nicht
|
||||||
AlreadyExists: Default Password Age Policy existiert bereits
|
AlreadyExists: Default Password Age Policy existiert bereits
|
||||||
Empty: Default Password Age Policy leer
|
Empty: Default Password Age Policy leer
|
||||||
|
NotChanged: Default Password Age Policy wurde nicht verändert
|
||||||
PasswordLockoutPolicy:
|
PasswordLockoutPolicy:
|
||||||
NotFound: Default Password Lockout Policy konnte nicht gefunden werden
|
NotFound: Default Password Lockout Policy konnte nicht gefunden werden
|
||||||
NotExisting: Default Password Lockout Policy existiert nicht
|
NotExisting: Default Password Lockout Policy existiert nicht
|
||||||
AlreadyExists: Default Password Lockout Policy existiert bereits
|
AlreadyExists: Default Password Lockout Policy existiert bereits
|
||||||
Empty: Default Password Lockout Policy leer
|
Empty: Default Password Lockout Policy leer
|
||||||
|
NotChanged: Default Password Lockout Policy wurde nicht verändert
|
||||||
OrgIAMPolicy:
|
OrgIAMPolicy:
|
||||||
NotFound: Default Org IAM Policy konnte nicht gefunden werden
|
NotFound: Default Org IAM Policy konnte nicht gefunden werden
|
||||||
NotExisting: Default Org IAM Policy existiert nicht
|
NotExisting: Default Org IAM Policy existiert nicht
|
||||||
AlreadyExists: Default Org IAM Policy existiert bereits
|
AlreadyExists: Default Org IAM Policy existiert bereits
|
||||||
Empty: Default Org IAM Policy leer
|
Empty: Default Org IAM Policy leer
|
||||||
|
NotChanged: Default Org IAM Policy wurde nicht verändert
|
||||||
Policy:
|
Policy:
|
||||||
AlreadyExists: Policy existiert bereits
|
AlreadyExists: Policy existiert bereits
|
||||||
UserGrant:
|
UserGrant:
|
||||||
|
@ -17,15 +17,21 @@ Errors:
|
|||||||
NotLocked: User is not locked
|
NotLocked: User is not locked
|
||||||
NoChanges: No changes found
|
NoChanges: No changes found
|
||||||
InitCodeNotFound: Initialization Code not found
|
InitCodeNotFound: Initialization Code not found
|
||||||
ProfileNotFound: Profile not found
|
Profile:
|
||||||
ProfileInvalid: Profildata invalid
|
NotFound: Profile not found
|
||||||
EmailNotFound: Email not found
|
NotChanged: Profile not changed
|
||||||
EmailInvalid: Email is invalid
|
Invalid: Profildata invalid
|
||||||
EmailAlreadyVerified: Email is alredy verified
|
Email:
|
||||||
|
NotFound: Email not found
|
||||||
|
Invalid: Email is invalid
|
||||||
|
AlreadyVerified: Email is alredy verified
|
||||||
|
NotChanged: Email not changed
|
||||||
PhoneNotFound: Phone not found
|
PhoneNotFound: Phone not found
|
||||||
PhoneInvalid: Phone is invalid
|
PhoneInvalid: Phone is invalid
|
||||||
PhoneAlreadyVerified: Phone already verified
|
PhoneAlreadyVerified: Phone already verified
|
||||||
AddressNotFound: Address not found
|
Address:
|
||||||
|
NotFound: Address not found
|
||||||
|
NotChanged: Address not changed
|
||||||
NotHuman: The User must be personal
|
NotHuman: The User must be personal
|
||||||
NotMachine: The User must be technical
|
NotMachine: The User must be technical
|
||||||
NotAllowedToLink: User is not allowed to link with external login provider
|
NotAllowedToLink: User is not allowed to link with external login provider
|
||||||
@ -164,6 +170,8 @@ Errors:
|
|||||||
GrantHasNotExistingRole: One role doesn't exist on project
|
GrantHasNotExistingRole: One role doesn't exist on project
|
||||||
UserIDMisisng: User ID missing
|
UserIDMisisng: User ID missing
|
||||||
IAM:
|
IAM:
|
||||||
|
Member:
|
||||||
|
RolesNotChanged: Roles habe not been changed
|
||||||
MemberInvalid: Member is invalid
|
MemberInvalid: Member is invalid
|
||||||
MemberAlreadyExisting: Member already exists
|
MemberAlreadyExisting: Member already exists
|
||||||
MemberNotExisting: Member does not exist
|
MemberNotExisting: Member does not exist
|
||||||
@ -179,6 +187,7 @@ Errors:
|
|||||||
IdpProviderInvalid: Idp Provider is invalid
|
IdpProviderInvalid: Idp Provider is invalid
|
||||||
LoginPolicy:
|
LoginPolicy:
|
||||||
NotFound: Default Login Policy not found
|
NotFound: Default Login Policy not found
|
||||||
|
NotChanged: Default Login Policy has not been changed
|
||||||
NotExisting: Default Login Policy not existig
|
NotExisting: Default Login Policy not existig
|
||||||
AlreadyExists: Default Login Policy already exists
|
AlreadyExists: Default Login Policy already exists
|
||||||
IdpProviderAlreadyExisting: Idp Provider already existing
|
IdpProviderAlreadyExisting: Idp Provider already existing
|
||||||
@ -187,28 +196,38 @@ Errors:
|
|||||||
AlreadyExists: Multifactor already exists
|
AlreadyExists: Multifactor already exists
|
||||||
NotExisting: Multifactor not existing
|
NotExisting: Multifactor not existing
|
||||||
Unspecified: Multifactor invalid
|
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:
|
LabelPolicy:
|
||||||
NotFound: Default Private Label Policy not found
|
NotFound: Default Private Label Policy not found
|
||||||
|
NotChanged: Default Private Label Policy has not been changed
|
||||||
PasswordComplexityPolicy:
|
PasswordComplexityPolicy:
|
||||||
NotFound: Default Private Label Policy not found
|
NotFound: Default Private Label Policy not found
|
||||||
NotExisting: Default Password Complexity Policy not existing
|
NotExisting: Default Password Complexity Policy not existing
|
||||||
AlreadyExists: Default Password Complexity Policy already existing
|
AlreadyExists: Default Password Complexity Policy already existing
|
||||||
Empty: Default Password Complexity Policy empty
|
Empty: Default Password Complexity Policy empty
|
||||||
|
NotChanged: Default Password Complexity Policy has not been changed
|
||||||
PasswordAgePolicy:
|
PasswordAgePolicy:
|
||||||
NotFound: Default Password Age Policy not found
|
NotFound: Default Password Age Policy not found
|
||||||
NotExisting: Default Password Age Policy not existing
|
NotExisting: Default Password Age Policy not existing
|
||||||
AlreadyExists: Default Password Age Policy already existing
|
AlreadyExists: Default Password Age Policy already existing
|
||||||
Empty: Default Password Age Policy empty
|
Empty: Default Password Age Policy empty
|
||||||
|
NotChanged: Default Password Age Policy has not been changed
|
||||||
PasswordLockoutPolicy:
|
PasswordLockoutPolicy:
|
||||||
NotFound: Default Password Lockout Policy not found
|
NotFound: Default Password Lockout Policy not found
|
||||||
NotExisting: Default Password Lockout Policy not existing
|
NotExisting: Default Password Lockout Policy not existing
|
||||||
AlreadyExists: Default Password Lockout Policy already existing
|
AlreadyExists: Default Password Lockout Policy already existing
|
||||||
Empty: Default Password Lockout Policy empty
|
Empty: Default Password Lockout Policy empty
|
||||||
|
NotChanged: Default Password Lockout Policy has not been changed
|
||||||
OrgIAMPolicy:
|
OrgIAMPolicy:
|
||||||
NotFound: Org IAM Policy not found
|
NotFound: Org IAM Policy not found
|
||||||
Empty: Org IAM Policy is empty
|
Empty: Org IAM Policy is empty
|
||||||
NotExisting: Org IAM Policy not existing
|
NotExisting: Org IAM Policy not existing
|
||||||
AlreadyExists: Org IAM Policy already exists
|
AlreadyExists: Org IAM Policy already exists
|
||||||
|
NotChanged: Org IAM Policy has not been changed
|
||||||
Policy:
|
Policy:
|
||||||
AlreadyExists: Policy already exists
|
AlreadyExists: Policy already exists
|
||||||
UserGrant:
|
UserGrant:
|
||||||
|
@ -2,6 +2,8 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
caos_errors "github.com/caos/zitadel/internal/errors"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||||
@ -11,6 +13,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Human struct {
|
type Human struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
|
||||||
*Password
|
*Password
|
||||||
*Profile
|
*Profile
|
||||||
*Email
|
*Email
|
||||||
@ -44,6 +48,19 @@ const (
|
|||||||
GenderDiverse
|
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() {
|
func (u *Human) SetNamesAsDisplayname() {
|
||||||
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
|
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
|
||||||
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 {
|
if user.Profile != nil {
|
||||||
return 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) {
|
func (es *UserEventstore) ChangeProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) {
|
||||||
profile.SetNamesAsDisplayname()
|
profile.SetNamesAsDisplayname()
|
||||||
if !profile.IsValid() {
|
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)
|
user, err := es.HumanByID(ctx, profile.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -897,12 +897,12 @@ func (es *UserEventstore) EmailByID(ctx context.Context, userID string) (*usr_mo
|
|||||||
if user.Email != nil {
|
if user.Email != nil {
|
||||||
return 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) {
|
func (es *UserEventstore) ChangeEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) {
|
||||||
if !email.IsValid() {
|
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)
|
user, err := es.HumanByID(ctx, email.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -975,10 +975,10 @@ func (es *UserEventstore) CreateEmailVerificationCode(ctx context.Context, userI
|
|||||||
return errors.ThrowPreconditionFailed(nil, "EVENT-E3fbw", "Errors.User.NotInitialised")
|
return errors.ThrowPreconditionFailed(nil, "EVENT-E3fbw", "Errors.User.NotInitialised")
|
||||||
}
|
}
|
||||||
if user.Email == nil {
|
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 {
|
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)
|
emailCode := new(usr_model.EmailCode)
|
||||||
@ -1158,7 +1158,7 @@ func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_
|
|||||||
if user.Address != nil {
|
if user.Address != nil {
|
||||||
return 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) {
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
caos_errs "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"
|
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
|
//TODO: check if roles valid
|
||||||
|
|
||||||
if !member.IsValid() {
|
if !member.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid")
|
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)
|
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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")
|
return nil, errors.ThrowAlreadyExists(nil, "IAM-PtXi1", "Errors.IAM.Member.AlreadyExists")
|
||||||
}
|
}
|
||||||
|
|
||||||
iamAgg := iam_repo.AggregateFromWriteModel(&addedMember.WriteModel.WriteModel).
|
iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel)
|
||||||
PushMemberAdded(ctx, member.UserID, member.Roles...)
|
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
|
||||||
|
|
||||||
err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg)
|
err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -37,23 +38,26 @@ func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember)
|
|||||||
return writeModelToMember(addedMember), nil
|
return writeModelToMember(addedMember), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//ChangeMember updates an existing member
|
//ChangeIAMMember updates an existing member
|
||||||
func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) {
|
||||||
//TODO: check if roles valid
|
//TODO: check if roles valid
|
||||||
|
|
||||||
if !member.IsValid() {
|
if !member.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid")
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
iam := iam_repo.AggregateFromWriteModel(&existingMember.WriteModel.WriteModel).
|
if reflect.DeepEqual(existingMember.Roles, member.Roles) {
|
||||||
PushMemberChangedFromExisting(ctx, existingMember, 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -66,8 +70,8 @@ func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMemb
|
|||||||
return writeModelToMember(existingMember), nil
|
return writeModelToMember(existingMember), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMember) error {
|
func (r *CommandSide) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error {
|
||||||
m, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
m, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
|
||||||
if err != nil && !errors.IsNotFound(err) {
|
if err != nil && !errors.IsNotFound(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -75,30 +79,17 @@ func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMemb
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
iamAgg := iam_repo.AggregateFromWriteModel(&m.WriteModel.WriteModel).
|
iamAgg := IAMAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
|
||||||
PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID))
|
iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID))
|
||||||
|
|
||||||
return r.eventstore.PushAggregate(ctx, m, iamAgg)
|
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)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
member = iam_repo.NewMemberReadModel(iamID, userID)
|
writeModel := NewIAMMemberWriteModel(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)
|
|
||||||
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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 (
|
import (
|
||||||
"github.com/caos/zitadel/internal/crypto"
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"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
|
eventstore.WriteModel
|
||||||
|
|
||||||
IDPConfigID string
|
IDPConfigID string
|
||||||
@ -14,24 +16,31 @@ type ConfigWriteModel struct {
|
|||||||
Issuer string
|
Issuer string
|
||||||
Scopes []string
|
Scopes []string
|
||||||
|
|
||||||
IDPDisplayNameMapping MappingField
|
IDPDisplayNameMapping domain.OIDCMappingField
|
||||||
UserNameMapping MappingField
|
UserNameMapping domain.OIDCMappingField
|
||||||
|
State domain.IDPConfigState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *ConfigWriteModel) Reduce() error {
|
func (wm *OIDCConfigWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *ConfigAddedEvent:
|
case *idpconfig.OIDCConfigAddedEvent:
|
||||||
wm.reduceConfigAddedEvent(e)
|
wm.reduceConfigAddedEvent(e)
|
||||||
case *ConfigChangedEvent:
|
case *idpconfig.OIDCConfigChangedEvent:
|
||||||
wm.reduceConfigChangedEvent(e)
|
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()
|
return wm.WriteModel.Reduce()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) {
|
func (wm *OIDCConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.OIDCConfigAddedEvent) {
|
||||||
wm.IDPConfigID = e.IDPConfigID
|
wm.IDPConfigID = e.IDPConfigID
|
||||||
wm.ClientID = e.ClientID
|
wm.ClientID = e.ClientID
|
||||||
wm.ClientSecret = e.ClientSecret
|
wm.ClientSecret = e.ClientSecret
|
||||||
@ -39,9 +48,10 @@ func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) {
|
|||||||
wm.Scopes = e.Scopes
|
wm.Scopes = e.Scopes
|
||||||
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping
|
||||||
wm.UserNameMapping = e.UserNameMapping
|
wm.UserNameMapping = e.UserNameMapping
|
||||||
|
wm.State = domain.IDPConfigStateActive
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *ConfigWriteModel) reduceConfigChangedEvent(e *ConfigChangedEvent) {
|
func (wm *OIDCConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.OIDCConfigChangedEvent) {
|
||||||
if e.ClientID != "" {
|
if e.ClientID != "" {
|
||||||
wm.ClientID = 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 (
|
import (
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WriteModel struct {
|
type LabelPolicyWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
PrimaryColor string
|
PrimaryColor string
|
||||||
SecondaryColor string
|
SecondaryColor string
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WriteModel) Reduce() error {
|
func (wm *LabelPolicyWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *AddedEvent:
|
case *policy.LabelPolicyAddedEvent:
|
||||||
wm.PrimaryColor = e.PrimaryColor
|
wm.PrimaryColor = e.PrimaryColor
|
||||||
wm.SecondaryColor = e.SecondaryColor
|
wm.SecondaryColor = e.SecondaryColor
|
||||||
case *ChangedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.LabelPolicyChangedEvent:
|
||||||
wm.PrimaryColor = e.PrimaryColor
|
wm.PrimaryColor = e.PrimaryColor
|
||||||
wm.SecondaryColor = e.SecondaryColor
|
wm.SecondaryColor = e.SecondaryColor
|
||||||
|
case *policy.LabelPolicyRemovedEvent:
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
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 {
|
type SecondFactorWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
MFAType SecondFactorType
|
MFAType domain.SecondFactorType
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *SecondFactorWriteModel) Reduce() error {
|
func (wm *SecondFactorWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *SecondFactorAddedEvent:
|
case *policy.SecondFactorAddedEvent:
|
||||||
wm.MFAType = e.MFAType
|
wm.MFAType = e.MFAType
|
||||||
case *SecondFactorRemovedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.SecondFactorRemovedEvent:
|
||||||
wm.MFAType = e.MFAType
|
wm.MFAType = e.MFAType
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
||||||
@ -21,16 +28,19 @@ func (wm *SecondFactorWriteModel) Reduce() error {
|
|||||||
|
|
||||||
type MultiFactoryWriteModel struct {
|
type MultiFactoryWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
MFAType MultiFactorType
|
MFAType domain.MultiFactorType
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *MultiFactoryWriteModel) Reduce() error {
|
func (wm *MultiFactoryWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *MultiFactorAddedEvent:
|
case *policy.MultiFactorAddedEvent:
|
||||||
wm.MFAType = e.MFAType
|
wm.MFAType = e.MFAType
|
||||||
case *MultiFactorRemovedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.MultiFactorRemovedEvent:
|
||||||
wm.MFAType = e.MFAType
|
wm.MFAType = e.MFAType
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
@ -1,34 +1,40 @@
|
|||||||
package login
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"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
|
eventstore.WriteModel
|
||||||
|
|
||||||
AllowUserNamePassword bool
|
AllowUserNamePassword bool
|
||||||
AllowRegister bool
|
AllowRegister bool
|
||||||
AllowExternalIDP bool
|
AllowExternalIDP bool
|
||||||
ForceMFA 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 {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *AddedEvent:
|
case *policy.LoginPolicyAddedEvent:
|
||||||
wm.AllowRegister = e.AllowRegister
|
wm.AllowRegister = e.AllowRegister
|
||||||
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
||||||
wm.AllowExternalIDP = e.AllowExternalIDP
|
wm.AllowExternalIDP = e.AllowExternalIDP
|
||||||
wm.ForceMFA = e.ForceMFA
|
wm.ForceMFA = e.ForceMFA
|
||||||
wm.PasswordlessType = e.PasswordlessType
|
wm.PasswordlessType = e.PasswordlessType
|
||||||
case *ChangedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.LoginPolicyChangedEvent:
|
||||||
wm.AllowRegister = e.AllowRegister
|
wm.AllowRegister = e.AllowRegister
|
||||||
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
wm.AllowUserNamePassword = e.AllowUserNamePassword
|
||||||
wm.AllowExternalIDP = e.AllowExternalIDP
|
wm.AllowExternalIDP = e.AllowExternalIDP
|
||||||
wm.ForceMFA = e.ForceMFA
|
wm.ForceMFA = e.ForceMFA
|
||||||
wm.PasswordlessType = e.PasswordlessType
|
wm.PasswordlessType = e.PasswordlessType
|
||||||
|
case *policy.LoginPolicyRemovedEvent:
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
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 (
|
import (
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WriteModel struct {
|
type PasswordAgePolicyWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
ExpireWarnDays uint64
|
ExpireWarnDays uint64
|
||||||
MaxAgeDays uint64
|
MaxAgeDays uint64
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WriteModel) Reduce() error {
|
func (wm *PasswordAgePolicyWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *AddedEvent:
|
case *policy.PasswordAgePolicyAddedEvent:
|
||||||
wm.ExpireWarnDays = e.ExpireWarnDays
|
wm.ExpireWarnDays = e.ExpireWarnDays
|
||||||
wm.MaxAgeDays = e.MaxAgeDays
|
wm.MaxAgeDays = e.MaxAgeDays
|
||||||
case *ChangedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.PasswordAgePolicyChangedEvent:
|
||||||
wm.ExpireWarnDays = e.ExpireWarnDays
|
wm.ExpireWarnDays = e.ExpireWarnDays
|
||||||
wm.MaxAgeDays = e.MaxAgeDays
|
wm.MaxAgeDays = e.MaxAgeDays
|
||||||
|
case *policy.PasswordAgePolicyRemovedEvent:
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
@ -1,10 +1,11 @@
|
|||||||
package password_complexity
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WriteModel struct {
|
type PasswordComplexityPolicyWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
MinLength uint64
|
MinLength uint64
|
||||||
@ -12,23 +13,27 @@ type WriteModel struct {
|
|||||||
HasUpperCase bool
|
HasUpperCase bool
|
||||||
HasNumber bool
|
HasNumber bool
|
||||||
HasSymbol bool
|
HasSymbol bool
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WriteModel) Reduce() error {
|
func (wm *PasswordComplexityPolicyWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *AddedEvent:
|
case *policy.PasswordComplexityPolicyAddedEvent:
|
||||||
wm.MinLength = e.MinLength
|
wm.MinLength = e.MinLength
|
||||||
wm.HasLowercase = e.HasLowercase
|
wm.HasLowercase = e.HasLowercase
|
||||||
wm.HasUpperCase = e.HasUpperCase
|
wm.HasUpperCase = e.HasUpperCase
|
||||||
wm.HasNumber = e.HasNumber
|
wm.HasNumber = e.HasNumber
|
||||||
wm.HasSymbol = e.HasSymbol
|
wm.HasSymbol = e.HasSymbol
|
||||||
case *ChangedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.PasswordComplexityPolicyChangedEvent:
|
||||||
wm.MinLength = e.MinLength
|
wm.MinLength = e.MinLength
|
||||||
wm.HasLowercase = e.HasLowercase
|
wm.HasLowercase = e.HasLowercase
|
||||||
wm.HasUpperCase = e.HasUpperCase
|
wm.HasUpperCase = e.HasUpperCase
|
||||||
wm.HasNumber = e.HasNumber
|
wm.HasNumber = e.HasNumber
|
||||||
wm.HasSymbol = e.HasSymbol
|
wm.HasSymbol = e.HasSymbol
|
||||||
|
case *policy.PasswordComplexityPolicyRemovedEvent:
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
return wm.WriteModel.Reduce()
|
@ -1,25 +1,30 @@
|
|||||||
package password_lockout
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/caos/zitadel/internal/eventstore/v2"
|
"github.com/caos/zitadel/internal/eventstore/v2"
|
||||||
|
"github.com/caos/zitadel/internal/v2/repository/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WriteModel struct {
|
type PasswordLockoutPolicyWriteModel struct {
|
||||||
eventstore.WriteModel
|
eventstore.WriteModel
|
||||||
|
|
||||||
MaxAttempts uint64
|
MaxAttempts uint64
|
||||||
ShowLockOutFailures bool
|
ShowLockOutFailures bool
|
||||||
|
IsActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wm *WriteModel) Reduce() error {
|
func (wm *PasswordLockoutPolicyWriteModel) Reduce() error {
|
||||||
for _, event := range wm.Events {
|
for _, event := range wm.Events {
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case *AddedEvent:
|
case *policy.PasswordLockoutPolicyAddedEvent:
|
||||||
wm.MaxAttempts = e.MaxAttempts
|
wm.MaxAttempts = e.MaxAttempts
|
||||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
case *ChangedEvent:
|
wm.IsActive = true
|
||||||
|
case *policy.PasswordLockoutPolicyChangedEvent:
|
||||||
wm.MaxAttempts = e.MaxAttempts
|
wm.MaxAttempts = e.MaxAttempts
|
||||||
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
wm.ShowLockOutFailures = e.ShowLockOutFailures
|
||||||
|
case *policy.PasswordLockoutPolicyRemovedEvent:
|
||||||
|
wm.IsActive = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wm.WriteModel.Reduce()
|
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