From ef058c8de650fec20ee3f48b2e4dc0c82144305e Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:58:14 +0200 Subject: [PATCH] fix: org remove taken into account during username changes (#10617) # Which Problems Are Solved For instance settings related to username changes, already removed organizations were still processed. # How the Problems Are Solved Do no process already removed organizations. # Additional Changes None # Additional Context None --------- Co-authored-by: Marco A. --- .../command/instance_policy_domain_model.go | 18 ++- .../command/instance_policy_domain_test.go | 111 ++++++++++++++++++ 2 files changed, 118 insertions(+), 11 deletions(-) diff --git a/internal/command/instance_policy_domain_model.go b/internal/command/instance_policy_domain_model.go index 0ae6015dc..19ddedd8c 100644 --- a/internal/command/instance_policy_domain_model.go +++ b/internal/command/instance_policy_domain_model.go @@ -2,6 +2,7 @@ package command import ( "context" + "slices" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/eventstore" @@ -96,17 +97,11 @@ func (wm *DomainPolicyOrgsWriteModel) AppendEvents(events ...eventstore.Event) { func (wm *DomainPolicyOrgsWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *org.OrgAddedEvent: - wm.OrgIDs = append(wm.OrgIDs, e.Aggregate().ID) - case *org.DomainPolicyAddedEvent: - for i, orgID := range wm.OrgIDs { - if orgID == e.Aggregate().ID { - wm.OrgIDs[i] = wm.OrgIDs[len(wm.OrgIDs)-1] - wm.OrgIDs = wm.OrgIDs[:len(wm.OrgIDs)-1] - break - } - } - case *org.DomainPolicyRemovedEvent: + // organization irrelevant if removed or with custom policy + case *org.OrgRemovedEvent, *org.DomainPolicyAddedEvent: + wm.OrgIDs = slices.DeleteFunc(wm.OrgIDs, func(orgID string) bool { return orgID == e.Aggregate().ID }) + // organization relevant if added without custom policy or custom policy is removed + case *org.OrgAddedEvent, *org.DomainPolicyRemovedEvent: wm.OrgIDs = append(wm.OrgIDs, e.Aggregate().ID) } } @@ -119,6 +114,7 @@ func (wm *DomainPolicyOrgsWriteModel) Query() *eventstore.SearchQueryBuilder { AggregateTypes(org.AggregateType). EventTypes( org.OrgAddedEventType, + org.OrgRemovedEventType, org.DomainPolicyAddedEventType, org.DomainPolicyRemovedEventType). Builder() diff --git a/internal/command/instance_policy_domain_test.go b/internal/command/instance_policy_domain_test.go index 17c975b80..a8ce4c24c 100644 --- a/internal/command/instance_policy_domain_test.go +++ b/internal/command/instance_policy_domain_test.go @@ -325,6 +325,117 @@ func TestCommandSide_ChangeDefaultDomainPolicy(t *testing.T) { }, }, }, + { + name: "change, ok, org removed", + fields: fields{ + eventstore: expectEventstore( + expectFilter( + eventFromEventPusher( + instance.NewDomainPolicyAddedEvent(context.Background(), + &instance.NewAggregate("INSTANCE").Aggregate, + true, + true, + true, + ), + ), + ), + // domainPolicyOrgs + expectFilter( + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &org.NewAggregate("org1").Aggregate, + "org1", + ), + ), + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &org.NewAggregate("org2").Aggregate, + "org2", + ), + ), + eventFromEventPusher( + org.NewDomainPolicyAddedEvent(context.Background(), + &org.NewAggregate("org2").Aggregate, + false, + false, + false, + ), + ), + eventFromEventPusher( + org.NewOrgAddedEvent(context.Background(), + &org.NewAggregate("org3").Aggregate, + "org3", + ), + ), + eventFromEventPusher( + org.NewOrgRemovedEvent(context.Background(), + &org.NewAggregate("org3").Aggregate, + "org", + []string{}, + false, + []string{}, + []*domain.UserIDPLink{}, + []string{}, + ), + ), + ), + // domainPolicyUsernames for each org + // org1 + expectFilterOrganizationSettings("org1", false, false), + expectFilter( + eventFromEventPusher( + org.NewDomainPrimarySetEvent( + context.Background(), + &org.NewAggregate("org1").Aggregate, + "org1.com", + ), + ), + eventFromEventPusher( + org.NewDomainPrimarySetEvent(context.Background(), + &org.NewAggregate("org1").Aggregate, + "org1.com", + ), + ), + eventFromEventPusher( + user.NewHumanAddedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "user1", + "firstname", + "lastname", + "nickname", + "displayname", + language.English, + domain.GenderUnspecified, + "user1@org1.com", + false, + ), + ), + ), + expectPush( + newDefaultDomainPolicyChangedEvent(context.Background(), false, false, false), + user.NewUsernameChangedEvent(context.Background(), + &user.NewAggregate("user1", "org1").Aggregate, + "user1", + "user1@org1.com", + false, + false, + user.UsernameChangedEventWithPolicyChange(true), + ), + ), + ), + }, + args: args{ + ctx: authz.WithInstanceID(context.Background(), "INSTANCE"), + userLoginMustBeDomain: false, + validateOrgDomains: false, + smtpSenderAddressMatchesInstanceDomain: false, + }, + res: res{ + want: &domain.ObjectDetails{ + ResourceOwner: "INSTANCE", + }, + }, + }, { name: "change, organization scoped usernames, ok", fields: fields{