From 820a21dce30dc0c99fd5844cf5ef02f31b6077be Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Wed, 13 Apr 2022 11:24:03 +0200 Subject: [PATCH] feat: validate org domains (#3387) * feat: validate org domain command side * feat: validate org domain query side * fix: create domain policy * feat: add reading domain policy on addorg domain --- cmd/admin/setup/steps.yaml | 1 + docs/docs/apis/proto/admin.md | 3 +++ docs/docs/apis/proto/policy.md | 1 + internal/api/grpc/admin/domain_policy.go | 11 +++++--- internal/api/grpc/policy/domain_policy.go | 1 + internal/command/instance.go | 2 ++ internal/command/instance_converter.go | 1 + internal/command/instance_domain_policy.go | 4 ++- internal/command/instance_policy_domain.go | 4 +-- .../command/instance_policy_domain_model.go | 8 ++++-- .../command/instance_policy_domain_test.go | 18 ++++++++++--- internal/command/org_converter.go | 1 + internal/command/org_domain.go | 13 +++++++--- internal/command/org_domain_test.go | 26 ++++++++++++++++--- internal/command/org_policy_domain.go | 4 +-- internal/command/org_policy_domain_model.go | 8 ++++-- internal/command/org_policy_domain_test.go | 21 ++++++++++++--- internal/command/policy_org_model.go | 5 ++++ internal/command/user_domain_policy_test.go | 8 ++++++ internal/command/user_human_otp_test.go | 1 + internal/command/user_human_test.go | 26 +++++++++++++++++++ internal/command/user_machine_test.go | 2 ++ internal/command/user_test.go | 5 ++++ .../{policy_org_iam.go => policy_domain.go} | 1 + internal/query/org_iam_policy.go | 7 +++++ internal/query/org_iam_policy_test.go | 6 +++++ internal/query/projection/domain_policy.go | 6 +++++ .../query/projection/domain_policy_test.go | 24 +++++++++++------ internal/repository/instance/policy_domain.go | 6 +++-- internal/repository/org/policy_domain.go | 6 +++-- internal/repository/policy/policy_domain.go | 16 +++++++++--- proto/zitadel/admin.proto | 11 ++++++++ proto/zitadel/policy.proto | 5 ++++ 33 files changed, 223 insertions(+), 39 deletions(-) rename internal/domain/{policy_org_iam.go => policy_domain.go} (87%) diff --git a/cmd/admin/setup/steps.yaml b/cmd/admin/setup/steps.yaml index 0e98f1444a..f391897ad8 100644 --- a/cmd/admin/setup/steps.yaml +++ b/cmd/admin/setup/steps.yaml @@ -100,6 +100,7 @@ S3DefaultInstance: MaxAgeDays: 0 DomainPolicy: UserLoginMustBeDomain: true + ValidateOrgDomains: true LoginPolicy: AllowUsernamePassword: true AllowRegister: true diff --git a/docs/docs/apis/proto/admin.md b/docs/docs/apis/proto/admin.md index ae89546a26..6b0640a027 100644 --- a/docs/docs/apis/proto/admin.md +++ b/docs/docs/apis/proto/admin.md @@ -1493,6 +1493,7 @@ This is an empty request | ----- | ---- | ----------- | ----------- | | org_id | string | - | string.min_len: 1
string.max_len: 200
| | user_login_must_be_domain | bool | the username has to end with the domain of it's organisation (uniqueness is organisation based) | | +| validate_org_domains | bool | - | | @@ -3676,6 +3677,7 @@ This is an empty request | ----- | ---- | ----------- | ----------- | | org_id | string | - | string.min_len: 1
string.max_len: 200
| | user_login_must_be_domain | bool | - | | +| validate_org_domains | bool | - | | @@ -3721,6 +3723,7 @@ This is an empty request | Field | Type | Description | Validation | | ----- | ---- | ----------- | ----------- | | user_login_must_be_domain | bool | - | | +| validate_org_domains | bool | - | | diff --git a/docs/docs/apis/proto/policy.md b/docs/docs/apis/proto/policy.md index a3c6dc149a..5fc1712a46 100644 --- a/docs/docs/apis/proto/policy.md +++ b/docs/docs/apis/proto/policy.md @@ -18,6 +18,7 @@ title: zitadel/policy.proto | details | zitadel.v1.ObjectDetails | - | | | user_login_must_be_domain | bool | - | | | is_default | bool | - | | +| validate_org_domains | bool | - | | diff --git a/internal/api/grpc/admin/domain_policy.go b/internal/api/grpc/admin/domain_policy.go index ae98a69464..4705f624dc 100644 --- a/internal/api/grpc/admin/domain_policy.go +++ b/internal/api/grpc/admin/domain_policy.go @@ -27,7 +27,7 @@ func (s *Server) GetCustomDomainPolicy(ctx context.Context, req *admin_pb.GetCus } func (s *Server) AddCustomDomainPolicy(ctx context.Context, req *admin_pb.AddCustomDomainPolicyRequest) (*admin_pb.AddCustomDomainPolicyResponse, error) { - policy, err := s.command.AddOrgDomainPolicy(ctx, req.OrgId, domainPolicyToDomain(req.UserLoginMustBeDomain)) + policy, err := s.command.AddOrgDomainPolicy(ctx, req.OrgId, domainPolicyToDomain(req.UserLoginMustBeDomain, req.ValidateOrgDomains)) if err != nil { return nil, err } @@ -76,9 +76,10 @@ func (s *Server) ResetCustomDomainPolicyTo(ctx context.Context, req *admin_pb.Re return nil, nil //TOOD: return data } -func domainPolicyToDomain(userLoginMustBeDomain bool) *domain.DomainPolicy { +func domainPolicyToDomain(userLoginMustBeDomain, validateOrgDomains bool) *domain.DomainPolicy { return &domain.DomainPolicy{ UserLoginMustBeDomain: userLoginMustBeDomain, + ValidateOrgDomains: validateOrgDomains, } } @@ -88,6 +89,7 @@ func updateDomainPolicyToDomain(req *admin_pb.UpdateDomainPolicyRequest) *domain // // AggreagateID: //TODO: there should only be ONE default // }, UserLoginMustBeDomain: req.UserLoginMustBeDomain, + ValidateOrgDomains: req.ValidateOrgDomains, } } @@ -97,11 +99,12 @@ func updateCustomDomainPolicyToDomain(req *admin_pb.UpdateCustomDomainPolicyRequ AggregateID: req.OrgId, }, UserLoginMustBeDomain: req.UserLoginMustBeDomain, + ValidateOrgDomains: req.ValidateOrgDomains, } } func (s *Server) AddCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.AddCustomOrgIAMPolicyRequest) (*admin_pb.AddCustomOrgIAMPolicyResponse, error) { - policy, err := s.command.AddOrgDomainPolicy(ctx, req.OrgId, domainPolicyToDomain(req.UserLoginMustBeDomain)) + policy, err := s.command.AddOrgDomainPolicy(ctx, req.OrgId, domainPolicyToDomain(req.UserLoginMustBeDomain, true)) if err != nil { return nil, err } @@ -161,6 +164,7 @@ func (s *Server) GetCustomOrgIAMPolicy(ctx context.Context, req *admin_pb.GetCus func updateOrgIAMPolicyToDomain(req *admin_pb.UpdateOrgIAMPolicyRequest) *domain.DomainPolicy { return &domain.DomainPolicy{ UserLoginMustBeDomain: req.UserLoginMustBeDomain, + ValidateOrgDomains: true, } } @@ -170,5 +174,6 @@ func updateCustomOrgIAMPolicyToDomain(req *admin_pb.UpdateCustomOrgIAMPolicyRequ AggregateID: req.OrgId, }, UserLoginMustBeDomain: req.UserLoginMustBeDomain, + ValidateOrgDomains: true, } } diff --git a/internal/api/grpc/policy/domain_policy.go b/internal/api/grpc/policy/domain_policy.go index 304b8b124b..d8cc9bacfb 100644 --- a/internal/api/grpc/policy/domain_policy.go +++ b/internal/api/grpc/policy/domain_policy.go @@ -9,6 +9,7 @@ import ( func DomainPolicyToPb(policy *query.DomainPolicy) *policy_pb.DomainPolicy { return &policy_pb.DomainPolicy{ UserLoginMustBeDomain: policy.UserLoginMustBeDomain, + ValidateOrgDomains: policy.ValidateOrgDomains, IsDefault: policy.IsDefault, Details: object.ToViewDetailsPb( policy.Sequence, diff --git a/internal/command/instance.go b/internal/command/instance.go index ae29a28f6c..1dfc721180 100644 --- a/internal/command/instance.go +++ b/internal/command/instance.go @@ -78,6 +78,7 @@ type InstanceSetup struct { } DomainPolicy struct { UserLoginMustBeDomain bool + ValidateOrgDomains bool } LoginPolicy struct { AllowUsernamePassword bool @@ -242,6 +243,7 @@ func (c *commandNew) SetUpInstance(ctx context.Context, setup *InstanceSetup) (* AddDefaultDomainPolicy( instanceAgg, setup.DomainPolicy.UserLoginMustBeDomain, + setup.DomainPolicy.ValidateOrgDomains, ), AddDefaultLoginPolicy( instanceAgg, diff --git a/internal/command/instance_converter.go b/internal/command/instance_converter.go index 627a3ea341..a548554e8b 100644 --- a/internal/command/instance_converter.go +++ b/internal/command/instance_converter.go @@ -69,6 +69,7 @@ func writeModelToDomainPolicy(wm *InstanceDomainPolicyWriteModel) *domain.Domain return &domain.DomainPolicy{ ObjectRoot: writeModelToObjectRoot(wm.PolicyDomainWriteModel.WriteModel), UserLoginMustBeDomain: wm.UserLoginMustBeDomain, + ValidateOrgDomains: wm.ValidateOrgDomains, } } diff --git a/internal/command/instance_domain_policy.go b/internal/command/instance_domain_policy.go index 4bd7a10667..f82cf9cf89 100644 --- a/internal/command/instance_domain_policy.go +++ b/internal/command/instance_domain_policy.go @@ -10,7 +10,8 @@ import ( func AddDefaultDomainPolicy( a *instance.Aggregate, - userLoginMustBeDomain bool, + userLoginMustBeDomain, + validateOrgDomains bool, ) preparation.Validation { return func() (preparation.CreateCommands, error) { return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) { @@ -18,6 +19,7 @@ func AddDefaultDomainPolicy( return []eventstore.Command{ instance.NewDomainPolicyAddedEvent(ctx, &a.Aggregate, userLoginMustBeDomain, + validateOrgDomains, ), }, nil }, nil diff --git a/internal/command/instance_policy_domain.go b/internal/command/instance_policy_domain.go index a5a00efc96..b98a41c9e8 100644 --- a/internal/command/instance_policy_domain.go +++ b/internal/command/instance_policy_domain.go @@ -37,7 +37,7 @@ func (c *Commands) addDefaultDomainPolicy(ctx context.Context, instanceAgg *even if addedPolicy.State == domain.PolicyStateActive { return nil, caos_errs.ThrowAlreadyExists(nil, "INSTANCE-Lk0dS", "Errors.IAM.DomainPolicy.AlreadyExists") } - return iam_repo.NewDomainPolicyAddedEvent(ctx, instanceAgg, policy.UserLoginMustBeDomain), nil + return iam_repo.NewDomainPolicyAddedEvent(ctx, instanceAgg, policy.UserLoginMustBeDomain, policy.ValidateOrgDomains), nil } func (c *Commands) ChangeDefaultDomainPolicy(ctx context.Context, policy *domain.DomainPolicy) (*domain.DomainPolicy, error) { @@ -50,7 +50,7 @@ func (c *Commands) ChangeDefaultDomainPolicy(ctx context.Context, policy *domain } instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.PolicyDomainWriteModel.WriteModel) - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, instanceAgg, policy.UserLoginMustBeDomain) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, instanceAgg, policy.UserLoginMustBeDomain, policy.ValidateOrgDomains) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "INSTANCE-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") } diff --git a/internal/command/instance_policy_domain_model.go b/internal/command/instance_policy_domain_model.go index 3e487b5344..3de13d1d06 100644 --- a/internal/command/instance_policy_domain_model.go +++ b/internal/command/instance_policy_domain_model.go @@ -55,11 +55,15 @@ func (wm *InstanceDomainPolicyWriteModel) Query() *eventstore.SearchQueryBuilder func (wm *InstanceDomainPolicyWriteModel) NewChangedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - userLoginMustBeDomain bool) (*instance.DomainPolicyChangedEvent, bool) { - changes := make([]policy.OrgPolicyChanges, 0) + userLoginMustBeDomain, + validateOrgDomain bool) (*instance.DomainPolicyChangedEvent, bool) { + changes := make([]policy.DomainPolicyChanges, 0) if wm.UserLoginMustBeDomain != userLoginMustBeDomain { changes = append(changes, policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain)) } + if wm.ValidateOrgDomains != validateOrgDomain { + changes = append(changes, policy.ChangeValidateOrgDomains(validateOrgDomain)) + } if len(changes) == 0 { return nil, false } diff --git a/internal/command/instance_policy_domain_test.go b/internal/command/instance_policy_domain_test.go index f22bed6af3..eefd792c79 100644 --- a/internal/command/instance_policy_domain_test.go +++ b/internal/command/instance_policy_domain_test.go @@ -43,6 +43,7 @@ func TestCommandSide_AddDefaultDomainPolicy(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), ), ), @@ -52,6 +53,7 @@ func TestCommandSide_AddDefaultDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -71,6 +73,7 @@ func TestCommandSide_AddDefaultDomainPolicy(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), ), }, @@ -81,6 +84,7 @@ func TestCommandSide_AddDefaultDomainPolicy(t *testing.T) { ctx: authz.WithInstanceID(context.Background(), "INSTANCE"), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -91,6 +95,7 @@ func TestCommandSide_AddDefaultDomainPolicy(t *testing.T) { ResourceOwner: "INSTANCE", }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, }, @@ -144,6 +149,7 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -160,6 +166,7 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), ), ), @@ -169,6 +176,7 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -185,13 +193,14 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), ), ), expectPush( []*repository.Event{ eventFromEventPusher( - newDefaultDomainPolicyChangedEvent(context.Background(), false), + newDefaultDomainPolicyChangedEvent(context.Background(), false, false), ), }, ), @@ -201,6 +210,7 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: false, + ValidateOrgDomains: false, }, }, res: res{ @@ -210,6 +220,7 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { ResourceOwner: "INSTANCE", }, UserLoginMustBeDomain: false, + ValidateOrgDomains: false, }, }, }, @@ -233,11 +244,12 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { } } -func newDefaultDomainPolicyChangedEvent(ctx context.Context, userLoginMustBeDomain bool) *instance.DomainPolicyChangedEvent { +func newDefaultDomainPolicyChangedEvent(ctx context.Context, userLoginMustBeDomain, validateOrgDomains bool) *instance.DomainPolicyChangedEvent { event, _ := instance.NewDomainPolicyChangedEvent(ctx, &instance.NewAggregate("INSTANCE").Aggregate, - []policy.OrgPolicyChanges{ + []policy.DomainPolicyChanges{ policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain), + policy.ChangeValidateOrgDomains(validateOrgDomains), }, ) return event diff --git a/internal/command/org_converter.go b/internal/command/org_converter.go index 9a13433f63..fff57ba31b 100644 --- a/internal/command/org_converter.go +++ b/internal/command/org_converter.go @@ -17,6 +17,7 @@ func orgWriteModelToDomainPolicy(wm *OrgDomainPolicyWriteModel) *domain.DomainPo return &domain.DomainPolicy{ ObjectRoot: writeModelToObjectRoot(wm.PolicyDomainWriteModel.WriteModel), UserLoginMustBeDomain: wm.UserLoginMustBeDomain, + ValidateOrgDomains: wm.ValidateOrgDomains, } } diff --git a/internal/command/org_domain.go b/internal/command/org_domain.go index 5c3b3cb774..13af09bbe7 100644 --- a/internal/command/org_domain.go +++ b/internal/command/org_domain.go @@ -2,12 +2,11 @@ package command import ( "context" + errs "errors" "strings" "github.com/caos/logging" - errs "errors" - http_utils "github.com/caos/zitadel/internal/api/http" "github.com/caos/zitadel/internal/command/preparation" "github.com/caos/zitadel/internal/crypto" @@ -30,7 +29,15 @@ func AddOrgDomain(a *org.Aggregate, domain string) preparation.Validation { if existing != nil && existing.Verified { return nil, errors.ThrowAlreadyExists(nil, "V2-e1wse", "Errors.Already.Exists") } - return []eventstore.Command{org.NewDomainAddedEvent(ctx, &a.Aggregate, domain)}, nil + domainPolicy, err := domainPolicyWriteModel(ctx, filter) + if err != nil { + return nil, err + } + events := []eventstore.Command{org.NewDomainAddedEvent(ctx, &a.Aggregate, domain)} + if !domainPolicy.ValidateOrgDomains { + events = append(events, org.NewDomainVerifiedEvent(ctx, &a.Aggregate, domain)) + } + return events, nil }, nil } } diff --git a/internal/command/org_domain_test.go b/internal/command/org_domain_test.go index 9908e3de08..a71cc4c31d 100644 --- a/internal/command/org_domain_test.go +++ b/internal/command/org_domain_test.go @@ -47,12 +47,14 @@ func TestAddDomain(t *testing.T) { }, }, { - name: "correct", + name: "correct (should verify domain)", args: args{ a: agg, domain: "domain", filter: func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) { - return nil, nil + return []eventstore.Event{ + org.NewDomainPolicyAddedEvent(ctx, &agg.Aggregate, true, true), + }, nil }, }, want: Want{ @@ -61,6 +63,24 @@ func TestAddDomain(t *testing.T) { }, }, }, + { + name: "correct (should not verify domain)", + args: args{ + a: agg, + domain: "domain", + filter: func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) { + return []eventstore.Event{ + org.NewDomainPolicyAddedEvent(ctx, &agg.Aggregate, true, false), + }, nil + }, + }, + want: Want{ + Commands: []eventstore.Command{ + org.NewDomainAddedEvent(context.Background(), &agg.Aggregate, "domain"), + org.NewDomainVerifiedEvent(context.Background(), &agg.Aggregate, "domain"), + }, + }, + }, { name: "already verified", args: args{ @@ -1022,7 +1042,7 @@ func TestCommandSide_ValidateOrgDomain(t *testing.T) { eventFromEventPusher( org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org2", "org2").Aggregate, - false))), + false, false))), expectPush( []*repository.Event{ eventFromEventPusher(org.NewDomainVerifiedEvent(context.Background(), diff --git a/internal/command/org_policy_domain.go b/internal/command/org_policy_domain.go index f237c26041..97600f567f 100644 --- a/internal/command/org_policy_domain.go +++ b/internal/command/org_policy_domain.go @@ -39,7 +39,7 @@ func (c *Commands) addOrgDomainPolicy(ctx context.Context, orgAgg *eventstore.Ag if addedPolicy.State == domain.PolicyStateActive { return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-1M8ds", "Errors.Org.DomainPolicy.AlreadyExists") } - return org.NewDomainPolicyAddedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain), nil + return org.NewDomainPolicyAddedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain, policy.ValidateOrgDomains), nil } func (c *Commands) ChangeOrgDomainPolicy(ctx context.Context, resourceOwner string, policy *domain.DomainPolicy) (*domain.DomainPolicy, error) { @@ -55,7 +55,7 @@ func (c *Commands) ChangeOrgDomainPolicy(ctx context.Context, resourceOwner stri } orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyDomainWriteModel.WriteModel) - changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain) + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, orgAgg, policy.UserLoginMustBeDomain, policy.ValidateOrgDomains) if !hasChanged { return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-3M9ds", "Errors.Org.LabelPolicy.NotChanged") } diff --git a/internal/command/org_policy_domain_model.go b/internal/command/org_policy_domain_model.go index dfc90f9336..22d51d99f7 100644 --- a/internal/command/org_policy_domain_model.go +++ b/internal/command/org_policy_domain_model.go @@ -56,11 +56,15 @@ func (wm *OrgDomainPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *OrgDomainPolicyWriteModel) NewChangedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - userLoginMustBeDomain bool) (*org.DomainPolicyChangedEvent, bool) { - changes := make([]policy.OrgPolicyChanges, 0) + userLoginMustBeDomain, + validateOrgDomains bool) (*org.DomainPolicyChangedEvent, bool) { + changes := make([]policy.DomainPolicyChanges, 0) if wm.UserLoginMustBeDomain != userLoginMustBeDomain { changes = append(changes, policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain)) } + if wm.ValidateOrgDomains != validateOrgDomains { + changes = append(changes, policy.ChangeValidateOrgDomains(validateOrgDomains)) + } if len(changes) == 0 { return nil, false } diff --git a/internal/command/org_policy_domain_test.go b/internal/command/org_policy_domain_test.go index b61f4f4a5d..233dd9b4b3 100644 --- a/internal/command/org_policy_domain_test.go +++ b/internal/command/org_policy_domain_test.go @@ -45,6 +45,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -61,6 +62,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -71,6 +73,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { orgID: "org1", policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -89,6 +92,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), }, @@ -100,6 +104,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { orgID: "org1", policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -109,6 +114,7 @@ func TestCommandSide_AddDomainPolicy(t *testing.T) { ResourceOwner: "org1", }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, }, @@ -162,6 +168,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { ctx: context.Background(), policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -181,6 +188,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { orgID: "org1", policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -197,6 +205,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -207,6 +216,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { orgID: "org1", policy: &domain.DomainPolicy{ UserLoginMustBeDomain: true, + ValidateOrgDomains: true, }, }, res: res{ @@ -223,13 +233,14 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), expectPush( []*repository.Event{ eventFromEventPusher( - newDomainPolicyChangedEvent(context.Background(), "org1", false), + newDomainPolicyChangedEvent(context.Background(), "org1", false, false), ), }, ), @@ -240,6 +251,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { orgID: "org1", policy: &domain.DomainPolicy{ UserLoginMustBeDomain: false, + ValidateOrgDomains: false, }, }, res: res{ @@ -249,6 +261,7 @@ func TestCommandSide_ChangeDomainPolicy(t *testing.T) { ResourceOwner: "org1", }, UserLoginMustBeDomain: false, + ValidateOrgDomains: false, }, }, }, @@ -330,6 +343,7 @@ func TestCommandSide_RemoveDomainPolicy(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -370,11 +384,12 @@ func TestCommandSide_RemoveDomainPolicy(t *testing.T) { } } -func newDomainPolicyChangedEvent(ctx context.Context, orgID string, userLoginMustBeDomain bool) *org.DomainPolicyChangedEvent { +func newDomainPolicyChangedEvent(ctx context.Context, orgID string, userLoginMustBeDomain, validateOrgDomains bool) *org.DomainPolicyChangedEvent { event, _ := org.NewDomainPolicyChangedEvent(ctx, &org.NewAggregate(orgID, orgID).Aggregate, - []policy.OrgPolicyChanges{ + []policy.DomainPolicyChanges{ policy.ChangeUserLoginMustBeDomain(userLoginMustBeDomain), + policy.ChangeValidateOrgDomains(validateOrgDomains), }, ) return event diff --git a/internal/command/policy_org_model.go b/internal/command/policy_org_model.go index 5c296e68b5..493b42d2f8 100644 --- a/internal/command/policy_org_model.go +++ b/internal/command/policy_org_model.go @@ -10,6 +10,7 @@ type PolicyDomainWriteModel struct { eventstore.WriteModel UserLoginMustBeDomain bool + ValidateOrgDomains bool State domain.PolicyState } @@ -18,11 +19,15 @@ func (wm *PolicyDomainWriteModel) Reduce() error { switch e := event.(type) { case *policy.DomainPolicyAddedEvent: wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + wm.ValidateOrgDomains = e.ValidateOrgDomains wm.State = domain.PolicyStateActive case *policy.DomainPolicyChangedEvent: if e.UserLoginMustBeDomain != nil { wm.UserLoginMustBeDomain = *e.UserLoginMustBeDomain } + if e.ValidateOrgDomains != nil { + wm.ValidateOrgDomains = *e.ValidateOrgDomains + } } } return wm.WriteModel.Reduce() diff --git a/internal/command/user_domain_policy_test.go b/internal/command/user_domain_policy_test.go index c6c7bd747c..ce8c93b579 100644 --- a/internal/command/user_domain_policy_test.go +++ b/internal/command/user_domain_policy_test.go @@ -53,6 +53,7 @@ func Test_customDomainPolicy(t *testing.T) { context.Background(), &org.NewAggregate("id", "ro").Aggregate, true, + true, ), }, nil }, @@ -64,6 +65,7 @@ func Test_customDomainPolicy(t *testing.T) { Events: []eventstore.Event{}, }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, State: domain.PolicyStateActive, }, wantErr: false, @@ -122,6 +124,7 @@ func Test_defaultDomainPolicy(t *testing.T) { context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), }, nil }, @@ -133,6 +136,7 @@ func Test_defaultDomainPolicy(t *testing.T) { Events: []eventstore.Event{}, }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, State: domain.PolicyStateActive, }, wantErr: false, @@ -181,6 +185,7 @@ func Test_DomainPolicy(t *testing.T) { context.Background(), &org.NewAggregate("id", "ro").Aggregate, true, + true, ), }, nil }, @@ -192,6 +197,7 @@ func Test_DomainPolicy(t *testing.T) { Events: []eventstore.Event{}, }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, State: domain.PolicyStateActive, }, wantErr: false, @@ -224,6 +230,7 @@ func Test_DomainPolicy(t *testing.T) { context.Background(), &instance.NewAggregate("INSTANCE").Aggregate, true, + true, ), }, nil }). @@ -236,6 +243,7 @@ func Test_DomainPolicy(t *testing.T) { Events: []eventstore.Event{}, }, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, State: domain.PolicyStateActive, }, wantErr: false, diff --git a/internal/command/user_human_otp_test.go b/internal/command/user_human_otp_test.go index 15dc2bb967..90ee2b7dfe 100644 --- a/internal/command/user_human_otp_test.go +++ b/internal/command/user_human_otp_test.go @@ -179,6 +179,7 @@ func TestCommandSide_AddHumanOTP(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), diff --git a/internal/command/user_human_test.go b/internal/command/user_human_test.go index 17f126b00a..84fe475256 100644 --- a/internal/command/user_human_test.go +++ b/internal/command/user_human_test.go @@ -112,6 +112,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &userAgg.Aggregate, true, + true, ), ), ), @@ -167,6 +168,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &userAgg.Aggregate, true, + true, ), ), ), @@ -282,6 +284,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -398,6 +401,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &userAgg.Aggregate, true, + true, ), ), ), @@ -493,6 +497,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &userAgg.Aggregate, true, + true, ), ), ), @@ -575,6 +580,7 @@ func TestCommandSide_AddHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &userAgg.Aggregate, true, + true, ), ), ), @@ -793,6 +799,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -828,6 +835,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -869,6 +877,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -957,6 +966,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1039,6 +1049,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1143,6 +1154,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1251,6 +1263,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1355,6 +1368,7 @@ func TestCommandSide_ImportHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1556,6 +1570,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -1594,6 +1609,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -1640,6 +1656,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -1702,6 +1719,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -1764,6 +1782,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, false, + true, ), ), ), @@ -1843,6 +1862,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, false, + true, ), ), ), @@ -1980,6 +2000,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -2085,6 +2106,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -2184,6 +2206,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -2305,6 +2328,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &org.NewAggregate("org1", "org1").Aggregate, true, + true, ), ), ), @@ -2875,6 +2899,7 @@ func TestAddHumanCommand(t *testing.T) { context.Background(), &org.NewAggregate("id", "ro").Aggregate, true, + true, ), }, nil }). @@ -2917,6 +2942,7 @@ func TestAddHumanCommand(t *testing.T) { context.Background(), &org.NewAggregate("id", "ro").Aggregate, true, + true, ), }, nil }). diff --git a/internal/command/user_machine_test.go b/internal/command/user_machine_test.go index 0c09bf6c25..7e05115f36 100644 --- a/internal/command/user_machine_test.go +++ b/internal/command/user_machine_test.go @@ -86,6 +86,7 @@ func TestCommandSide_AddMachine(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, false, + true, ), ), ), @@ -113,6 +114,7 @@ func TestCommandSide_AddMachine(t *testing.T) { org.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), diff --git a/internal/command/user_test.go b/internal/command/user_test.go index 195948d148..ed16ccf31a 100644 --- a/internal/command/user_test.go +++ b/internal/command/user_test.go @@ -207,6 +207,7 @@ func TestCommandSide_UsernameChange(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -249,6 +250,7 @@ func TestCommandSide_UsernameChange(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1032,6 +1034,7 @@ func TestCommandSide_RemoveUser(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1096,6 +1099,7 @@ func TestCommandSide_RemoveUser(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), @@ -1153,6 +1157,7 @@ func TestCommandSide_RemoveUser(t *testing.T) { instance.NewDomainPolicyAddedEvent(context.Background(), &user.NewAggregate("user1", "org1").Aggregate, true, + true, ), ), ), diff --git a/internal/domain/policy_org_iam.go b/internal/domain/policy_domain.go similarity index 87% rename from internal/domain/policy_org_iam.go rename to internal/domain/policy_domain.go index 085f52bd55..2ad2fd4b4f 100644 --- a/internal/domain/policy_org_iam.go +++ b/internal/domain/policy_domain.go @@ -8,5 +8,6 @@ type DomainPolicy struct { models.ObjectRoot UserLoginMustBeDomain bool + ValidateOrgDomains bool Default bool } diff --git a/internal/query/org_iam_policy.go b/internal/query/org_iam_policy.go index e082f6a601..b8ff732d32 100644 --- a/internal/query/org_iam_policy.go +++ b/internal/query/org_iam_policy.go @@ -24,6 +24,7 @@ type DomainPolicy struct { State domain.PolicyState UserLoginMustBeDomain bool + ValidateOrgDomains bool IsDefault bool } @@ -60,6 +61,10 @@ var ( name: projection.DomainPolicyUserLoginMustBeDomainCol, table: domainPolicyTable, } + DomainPolicyColValidateOrgDomains = Column{ + name: projection.DomainPolicyValidateOrgDomainsCol, + table: domainPolicyTable, + } DomainPolicyColIsDefault = Column{ name: projection.DomainPolicyIsDefaultCol, table: domainPolicyTable, @@ -120,6 +125,7 @@ func prepareDomainPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*DomainPolicy DomainPolicyColChangeDate.identifier(), DomainPolicyColResourceOwner.identifier(), DomainPolicyColUserLoginMustBeDomain.identifier(), + DomainPolicyColValidateOrgDomains.identifier(), DomainPolicyColIsDefault.identifier(), DomainPolicyColState.identifier(), ). @@ -133,6 +139,7 @@ func prepareDomainPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*DomainPolicy &policy.ChangeDate, &policy.ResourceOwner, &policy.UserLoginMustBeDomain, + &policy.ValidateOrgDomains, &policy.IsDefault, &policy.State, ) diff --git a/internal/query/org_iam_policy_test.go b/internal/query/org_iam_policy_test.go index 2c89746d79..e398270595 100644 --- a/internal/query/org_iam_policy_test.go +++ b/internal/query/org_iam_policy_test.go @@ -34,6 +34,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { ` projections.domain_policies.change_date,`+ ` projections.domain_policies.resource_owner,`+ ` projections.domain_policies.user_login_must_be_domain,`+ + ` projections.domain_policies.validate_org_domains,`+ ` projections.domain_policies.is_default,`+ ` projections.domain_policies.state`+ ` FROM projections.domain_policies`), @@ -60,6 +61,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { ` projections.domain_policies.change_date,`+ ` projections.domain_policies.resource_owner,`+ ` projections.domain_policies.user_login_must_be_domain,`+ + ` projections.domain_policies.validate_org_domains,`+ ` projections.domain_policies.is_default,`+ ` projections.domain_policies.state`+ ` FROM projections.domain_policies`), @@ -70,6 +72,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { "change_date", "resource_owner", "user_login_must_be_domain", + "validate_org_domains", "is_default", "state", }, @@ -81,6 +84,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { "ro", true, true, + true, domain.PolicyStateActive, }, ), @@ -93,6 +97,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { ResourceOwner: "ro", State: domain.PolicyStateActive, UserLoginMustBeDomain: true, + ValidateOrgDomains: true, IsDefault: true, }, }, @@ -107,6 +112,7 @@ func Test_DomainPolicyPrepares(t *testing.T) { ` projections.domain_policies.change_date,`+ ` projections.domain_policies.resource_owner,`+ ` projections.domain_policies.user_login_must_be_domain,`+ + ` projections.domain_policies.validate_org_domains,`+ ` projections.domain_policies.is_default,`+ ` projections.domain_policies.state`+ ` FROM projections.domain_policies`), diff --git a/internal/query/projection/domain_policy.go b/internal/query/projection/domain_policy.go index 8e1313b8ec..04b0e8a998 100644 --- a/internal/query/projection/domain_policy.go +++ b/internal/query/projection/domain_policy.go @@ -22,6 +22,7 @@ const ( DomainPolicySequenceCol = "sequence" DomainPolicyStateCol = "state" DomainPolicyUserLoginMustBeDomainCol = "user_login_must_be_domain" + DomainPolicyValidateOrgDomainsCol = "validate_org_domains" DomainPolicyIsDefaultCol = "is_default" DomainPolicyResourceOwnerCol = "resource_owner" DomainPolicyInstanceIDCol = "instance_id" @@ -43,6 +44,7 @@ func NewDomainPolicyProjection(ctx context.Context, config crdb.StatementHandler crdb.NewColumn(DomainPolicySequenceCol, crdb.ColumnTypeInt64), crdb.NewColumn(DomainPolicyStateCol, crdb.ColumnTypeEnum), crdb.NewColumn(DomainPolicyUserLoginMustBeDomainCol, crdb.ColumnTypeBool), + crdb.NewColumn(DomainPolicyValidateOrgDomainsCol, crdb.ColumnTypeBool), crdb.NewColumn(DomainPolicyIsDefaultCol, crdb.ColumnTypeBool, crdb.Default(false)), crdb.NewColumn(DomainPolicyResourceOwnerCol, crdb.ColumnTypeText), crdb.NewColumn(DomainPolicyInstanceIDCol, crdb.ColumnTypeText), @@ -111,6 +113,7 @@ func (p *DomainPolicyProjection) reduceAdded(event eventstore.Event) (*handler.S handler.NewCol(DomainPolicyIDCol, policyEvent.Aggregate().ID), handler.NewCol(DomainPolicyStateCol, domain.PolicyStateActive), handler.NewCol(DomainPolicyUserLoginMustBeDomainCol, policyEvent.UserLoginMustBeDomain), + handler.NewCol(DomainPolicyValidateOrgDomainsCol, policyEvent.ValidateOrgDomains), handler.NewCol(DomainPolicyIsDefaultCol, isDefault), handler.NewCol(DomainPolicyResourceOwnerCol, policyEvent.Aggregate().ResourceOwner), handler.NewCol(DomainPolicyInstanceIDCol, policyEvent.Aggregate().InstanceID), @@ -134,6 +137,9 @@ func (p *DomainPolicyProjection) reduceChanged(event eventstore.Event) (*handler if policyEvent.UserLoginMustBeDomain != nil { cols = append(cols, handler.NewCol(DomainPolicyUserLoginMustBeDomainCol, *policyEvent.UserLoginMustBeDomain)) } + if policyEvent.ValidateOrgDomains != nil { + cols = append(cols, handler.NewCol(DomainPolicyValidateOrgDomainsCol, *policyEvent.ValidateOrgDomains)) + } return crdb.NewUpdateStatement( &policyEvent, cols, diff --git a/internal/query/projection/domain_policy_test.go b/internal/query/projection/domain_policy_test.go index 708624cd0f..ab7fcdc29f 100644 --- a/internal/query/projection/domain_policy_test.go +++ b/internal/query/projection/domain_policy_test.go @@ -29,7 +29,8 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { repository.EventType(org.DomainPolicyAddedEventType), org.AggregateType, []byte(`{ - "userLoginMustBeDomain": true + "userLoginMustBeDomain": true, + "validateOrgDomains": true }`), ), org.DomainPolicyAddedEventMapper), }, @@ -42,7 +43,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -50,6 +51,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { "agg-id", domain.PolicyStateActive, true, + true, false, "ro-id", "instance-id", @@ -67,7 +69,8 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { repository.EventType(org.DomainPolicyChangedEventType), org.AggregateType, []byte(`{ - "userLoginMustBeDomain": true + "userLoginMustBeDomain": true, + "validateOrgDomains": true }`), ), org.DomainPolicyChangedEventMapper), }, @@ -79,11 +82,12 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain, validate_org_domains) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), true, + true, "agg-id", }, }, @@ -126,7 +130,8 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { repository.EventType(instance.DomainPolicyAddedEventType), instance.AggregateType, []byte(`{ - "userLoginMustBeDomain": true + "userLoginMustBeDomain": true, + "validateOrgDomains": true }`), ), instance.DomainPolicyAddedEventMapper), }, @@ -138,7 +143,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + expectedStmt: "INSERT INTO projections.domain_policies (creation_date, change_date, sequence, id, state, user_login_must_be_domain, validate_org_domains, is_default, resource_owner, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedArgs: []interface{}{ anyArg{}, anyArg{}, @@ -147,6 +152,7 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { domain.PolicyStateActive, true, true, + true, "ro-id", "instance-id", }, @@ -163,7 +169,8 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { repository.EventType(instance.DomainPolicyChangedEventType), instance.AggregateType, []byte(`{ - "userLoginMustBeDomain": true + "userLoginMustBeDomain": true, + "validateOrgDomains": true }`), ), instance.DomainPolicyChangedEventMapper), }, @@ -175,11 +182,12 @@ func TestDomainPolicyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain) = ($1, $2, $3) WHERE (id = $4)", + expectedStmt: "UPDATE projections.domain_policies SET (change_date, sequence, user_login_must_be_domain, validate_org_domains) = ($1, $2, $3, $4) WHERE (id = $5)", expectedArgs: []interface{}{ anyArg{}, uint64(15), true, + true, "agg-id", }, }, diff --git a/internal/repository/instance/policy_domain.go b/internal/repository/instance/policy_domain.go index a3f6abcc20..b085bec2cf 100644 --- a/internal/repository/instance/policy_domain.go +++ b/internal/repository/instance/policy_domain.go @@ -21,7 +21,8 @@ type DomainPolicyAddedEvent struct { func NewDomainPolicyAddedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - userLoginMustBeDomain bool, + userLoginMustBeDomain, + validateOrgDomain bool, ) *DomainPolicyAddedEvent { return &DomainPolicyAddedEvent{ DomainPolicyAddedEvent: *policy.NewDomainPolicyAddedEvent( @@ -30,6 +31,7 @@ func NewDomainPolicyAddedEvent( aggregate, DomainPolicyAddedEventType), userLoginMustBeDomain, + validateOrgDomain, ), } } @@ -50,7 +52,7 @@ type DomainPolicyChangedEvent struct { func NewDomainPolicyChangedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - changes []policy.OrgPolicyChanges, + changes []policy.DomainPolicyChanges, ) (*DomainPolicyChangedEvent, error) { changedEvent, err := policy.NewDomainPolicyChangedEvent( eventstore.NewBaseEventForPush( diff --git a/internal/repository/org/policy_domain.go b/internal/repository/org/policy_domain.go index 9a805275b0..9550b4d2af 100644 --- a/internal/repository/org/policy_domain.go +++ b/internal/repository/org/policy_domain.go @@ -22,7 +22,8 @@ type DomainPolicyAddedEvent struct { func NewDomainPolicyAddedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - userLoginMustBeDomain bool, + userLoginMustBeDomain, + validateOrgDomains bool, ) *DomainPolicyAddedEvent { return &DomainPolicyAddedEvent{ DomainPolicyAddedEvent: *policy.NewDomainPolicyAddedEvent( @@ -31,6 +32,7 @@ func NewDomainPolicyAddedEvent( aggregate, DomainPolicyAddedEventType), userLoginMustBeDomain, + validateOrgDomains, ), } } @@ -51,7 +53,7 @@ type DomainPolicyChangedEvent struct { func NewDomainPolicyChangedEvent( ctx context.Context, aggregate *eventstore.Aggregate, - changes []policy.OrgPolicyChanges, + changes []policy.DomainPolicyChanges, ) (*DomainPolicyChangedEvent, error) { changedEvent, err := policy.NewDomainPolicyChangedEvent( eventstore.NewBaseEventForPush( diff --git a/internal/repository/policy/policy_domain.go b/internal/repository/policy/policy_domain.go index b0baefa9c3..82cb7801a5 100644 --- a/internal/repository/policy/policy_domain.go +++ b/internal/repository/policy/policy_domain.go @@ -20,6 +20,7 @@ type DomainPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` UserLoginMustBeDomain bool `json:"userLoginMustBeDomain,omitempty"` + ValidateOrgDomains bool `json:"validateOrgDomains,omitempty"` } func (e *DomainPolicyAddedEvent) Data() interface{} { @@ -32,12 +33,14 @@ func (e *DomainPolicyAddedEvent) UniqueConstraints() []*eventstore.EventUniqueCo func NewDomainPolicyAddedEvent( base *eventstore.BaseEvent, - userLoginMustBeDomain bool, + userLoginMustBeDomain, + validateOrgDomains bool, ) *DomainPolicyAddedEvent { return &DomainPolicyAddedEvent{ BaseEvent: *base, UserLoginMustBeDomain: userLoginMustBeDomain, + ValidateOrgDomains: validateOrgDomains, } } @@ -58,6 +61,7 @@ type DomainPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` UserLoginMustBeDomain *bool `json:"userLoginMustBeDomain,omitempty"` + ValidateOrgDomains *bool `json:"validateOrgDomains,omitempty"` } func (e *DomainPolicyChangedEvent) Data() interface{} { @@ -70,7 +74,7 @@ func (e *DomainPolicyChangedEvent) UniqueConstraints() []*eventstore.EventUnique func NewDomainPolicyChangedEvent( base *eventstore.BaseEvent, - changes []OrgPolicyChanges, + changes []DomainPolicyChanges, ) (*DomainPolicyChangedEvent, error) { if len(changes) == 0 { return nil, errors.ThrowPreconditionFailed(nil, "POLICY-DAf3h", "Errors.NoChangesFound") @@ -84,7 +88,7 @@ func NewDomainPolicyChangedEvent( return changeEvent, nil } -type OrgPolicyChanges func(*DomainPolicyChangedEvent) +type DomainPolicyChanges func(*DomainPolicyChangedEvent) func ChangeUserLoginMustBeDomain(userLoginMustBeDomain bool) func(*DomainPolicyChangedEvent) { return func(e *DomainPolicyChangedEvent) { @@ -92,6 +96,12 @@ func ChangeUserLoginMustBeDomain(userLoginMustBeDomain bool) func(*DomainPolicyC } } +func ChangeValidateOrgDomains(validateOrgDomain bool) func(*DomainPolicyChangedEvent) { + return func(e *DomainPolicyChangedEvent) { + e.ValidateOrgDomains = &validateOrgDomain + } +} + func DomainPolicyChangedEventMapper(event *repository.Event) (eventstore.Event, error) { e := &DomainPolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), diff --git a/proto/zitadel/admin.proto b/proto/zitadel/admin.proto index 491ea00bef..622b1522d7 100644 --- a/proto/zitadel/admin.proto +++ b/proto/zitadel/admin.proto @@ -3589,6 +3589,7 @@ message GetDomainPolicyResponse { message UpdateDomainPolicyRequest { bool user_login_must_be_domain = 1; + bool validate_org_domains = 2; } message UpdateDomainPolicyResponse { @@ -3637,6 +3638,11 @@ message AddCustomDomainPolicyRequest { description: "the username has to end with the domain of it's organisation" } ]; // the username has to end with the domain of it's organisation (uniqueness is organisation based) + bool validate_org_domains = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "defines if organisation domains should be validated org count as validated automatically" + } + ]; } message AddCustomDomainPolicyResponse { @@ -3663,6 +3669,11 @@ message UpdateCustomDomainPolicyRequest { description: "the username has to end with the domain of it's organisation" } ]; + bool validate_org_domains = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "defines if organisation domains should be validated org count as validated automatically" + } + ]; } message UpdateCustomDomainPolicyResponse { diff --git a/proto/zitadel/policy.proto b/proto/zitadel/policy.proto index 074fe531d9..2e1bcf5d73 100644 --- a/proto/zitadel/policy.proto +++ b/proto/zitadel/policy.proto @@ -35,6 +35,11 @@ message DomainPolicy { description: "defines if the organisation's admin changed the policy" } ]; + bool validate_org_domains = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "defines if organisation domains should be validated org count as validated automatically" + } + ]; } message LabelPolicy {