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. <marco@zitadel.com>
This commit is contained in:
Stefan Benz
2025-09-08 15:58:14 +02:00
committed by GitHub
parent 75774eb64c
commit ef058c8de6
2 changed files with 118 additions and 11 deletions

View File

@@ -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()

View File

@@ -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{