Merge branch 'main' into clean-transactional-propsal

This commit is contained in:
adlerhurst
2025-07-30 07:42:11 +02:00
117 changed files with 5490 additions and 1075 deletions

View File

@@ -275,13 +275,13 @@ func OrgReactivatedEventMapper(event eventstore.Event) (eventstore.Event, error)
}
type OrgRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
name string
usernames []string
loginMustBeDomain bool
domains []string
externalIDPs []*domain.UserIDPLink
samlEntityIDs []string
eventstore.BaseEvent `json:"-"`
name string
usernames []string
organizationScopedUsernames bool
domains []string
externalIDPs []*domain.UserIDPLink
samlEntityIDs []string
}
func (e *OrgRemovedEvent) Payload() interface{} {
@@ -293,7 +293,7 @@ func (e *OrgRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
NewRemoveOrgNameUniqueConstraint(e.name),
}
for _, name := range e.usernames {
constraints = append(constraints, user.NewRemoveUsernameUniqueConstraint(name, e.Aggregate().ID, e.loginMustBeDomain))
constraints = append(constraints, user.NewRemoveUsernameUniqueConstraint(name, e.Aggregate().ID, e.organizationScopedUsernames))
}
for _, domain := range e.domains {
constraints = append(constraints, NewRemoveOrgDomainUniqueConstraint(domain))
@@ -314,19 +314,19 @@ func (e *OrgRemovedEvent) Fields() []*eventstore.FieldOperation {
}
}
func NewOrgRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string, usernames []string, loginMustBeDomain bool, domains []string, externalIDPs []*domain.UserIDPLink, samlEntityIDs []string) *OrgRemovedEvent {
func NewOrgRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name string, usernames []string, organizationScopedUsernames bool, domains []string, externalIDPs []*domain.UserIDPLink, samlEntityIDs []string) *OrgRemovedEvent {
return &OrgRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
aggregate,
OrgRemovedEventType,
),
name: name,
usernames: usernames,
domains: domains,
externalIDPs: externalIDPs,
samlEntityIDs: samlEntityIDs,
loginMustBeDomain: loginMustBeDomain,
name: name,
usernames: usernames,
domains: domains,
externalIDPs: externalIDPs,
samlEntityIDs: samlEntityIDs,
organizationScopedUsernames: organizationScopedUsernames,
}
}

View File

@@ -0,0 +1,23 @@
package organization_settings
import "github.com/zitadel/zitadel/internal/eventstore"
const (
AggregateType = "organization_settings"
AggregateVersion = "v1"
)
type Aggregate struct {
eventstore.Aggregate
}
func NewAggregate(id, resourceOwner string) *Aggregate {
return &Aggregate{
Aggregate: eventstore.Aggregate{
Type: AggregateType,
Version: AggregateVersion,
ID: id,
ResourceOwner: resourceOwner,
},
}
}

View File

@@ -0,0 +1,8 @@
package organization_settings
import "github.com/zitadel/zitadel/internal/eventstore"
func init() {
eventstore.RegisterFilterEventMapper(AggregateType, OrganizationSettingsSetEventType, eventstore.GenericEventMapper[OrganizationSettingsSetEvent])
eventstore.RegisterFilterEventMapper(AggregateType, OrganizationSettingsRemovedEventType, eventstore.GenericEventMapper[OrganizationSettingsRemovedEvent])
}

View File

@@ -0,0 +1,96 @@
package organization_settings
import (
"context"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/user"
)
const (
organizationSettingsPrefix = "settings.organization."
OrganizationSettingsSetEventType = organizationSettingsPrefix + "set"
OrganizationSettingsRemovedEventType = organizationSettingsPrefix + "removed"
)
type OrganizationSettingsSetEvent struct {
*eventstore.BaseEvent `json:"-"`
OrganizationScopedUsernames bool `json:"organizationScopedUsernames,omitempty"`
oldOrganizationScopedUsernames bool
usernameChanges []string
}
func (e *OrganizationSettingsSetEvent) SetBaseEvent(b *eventstore.BaseEvent) {
e.BaseEvent = b
}
func (e *OrganizationSettingsSetEvent) Payload() any {
return e
}
func (e *OrganizationSettingsSetEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
if len(e.usernameChanges) == 0 || e.oldOrganizationScopedUsernames == e.OrganizationScopedUsernames {
return []*eventstore.UniqueConstraint{}
}
changes := make([]*eventstore.UniqueConstraint, len(e.usernameChanges)*2)
for i, username := range e.usernameChanges {
changes[i*2] = user.NewRemoveUsernameUniqueConstraint(username, e.Aggregate().ResourceOwner, e.oldOrganizationScopedUsernames)
changes[i*2+1] = user.NewAddUsernameUniqueConstraint(username, e.Aggregate().ResourceOwner, e.OrganizationScopedUsernames)
}
return changes
}
func NewOrganizationSettingsAddedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
usernameChanges []string,
organizationScopedUsernames bool,
oldOrganizationScopedUsernames bool,
) *OrganizationSettingsSetEvent {
return &OrganizationSettingsSetEvent{
BaseEvent: eventstore.NewBaseEventForPush(
ctx, aggregate, OrganizationSettingsSetEventType,
),
OrganizationScopedUsernames: organizationScopedUsernames,
oldOrganizationScopedUsernames: oldOrganizationScopedUsernames,
usernameChanges: usernameChanges,
}
}
type OrganizationSettingsRemovedEvent struct {
*eventstore.BaseEvent `json:"-"`
organizationScopedUsernames bool
oldOrganizationScopedUsernames bool
usernameChanges []string
}
func (e *OrganizationSettingsRemovedEvent) SetBaseEvent(b *eventstore.BaseEvent) {
e.BaseEvent = b
}
func (e *OrganizationSettingsRemovedEvent) Payload() any {
return e
}
func (e *OrganizationSettingsRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return user.NewUsernameUniqueConstraints(e.usernameChanges, e.Aggregate().ResourceOwner, e.organizationScopedUsernames, e.oldOrganizationScopedUsernames)
}
func NewOrganizationSettingsRemovedEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
usernameChanges []string,
organizationScopedUsernames bool,
oldOrganizationScopedUsernames bool,
) *OrganizationSettingsRemovedEvent {
return &OrganizationSettingsRemovedEvent{
BaseEvent: eventstore.NewBaseEventForPush(
ctx, aggregate, OrganizationSettingsRemovedEventType,
),
organizationScopedUsernames: organizationScopedUsernames,
oldOrganizationScopedUsernames: oldOrganizationScopedUsernames,
usernameChanges: usernameChanges,
}
}

View File

@@ -2,6 +2,7 @@ package policy
import (
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/zerrors"
)
@@ -122,6 +123,10 @@ func DomainPolicyChangedEventMapper(event eventstore.Event) (eventstore.Event, e
type DomainPolicyRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
usernameChanges []string
userLoginMustBeDomain bool
oldUserLoginMustBeDomain bool
}
func (e *DomainPolicyRemovedEvent) Payload() interface{} {
@@ -129,7 +134,7 @@ func (e *DomainPolicyRemovedEvent) Payload() interface{} {
}
func (e *DomainPolicyRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return nil
return user.NewUsernameUniqueConstraints(e.usernameChanges, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain, e.oldUserLoginMustBeDomain)
}
func NewDomainPolicyRemovedEvent(base *eventstore.BaseEvent) *DomainPolicyRemovedEvent {
@@ -143,3 +148,9 @@ func DomainPolicyRemovedEventMapper(event eventstore.Event) (eventstore.Event, e
BaseEvent: *eventstore.BaseEventFromRepo(event),
}, nil
}
func (e *DomainPolicyRemovedEvent) AddUniqueConstraintChanges(usernameChanges []string, userLoginMustBeDomain, oldUserLoginMustBeDomain bool) {
e.usernameChanges = usernameChanges
e.userLoginMustBeDomain = userLoginMustBeDomain
e.oldUserLoginMustBeDomain = oldUserLoginMustBeDomain
}

View File

@@ -31,8 +31,8 @@ const (
type HumanAddedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
userLoginMustBeDomain bool
UserName string `json:"userName"`
orgScopedUsername bool
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
@@ -63,7 +63,7 @@ func (e *HumanAddedEvent) Payload() interface{} {
}
func (e *HumanAddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain)}
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.orgScopedUsername)}
}
func (e *HumanAddedEvent) AddAddressData(
@@ -106,7 +106,7 @@ func NewHumanAddedEvent(
preferredLanguage language.Tag,
gender domain.Gender,
emailAddress domain.EmailAddress,
userLoginMustBeDomain bool,
orgScopedUsername bool,
) *HumanAddedEvent {
return &HumanAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
@@ -114,15 +114,15 @@ func NewHumanAddedEvent(
aggregate,
HumanAddedType,
),
UserName: userName,
FirstName: firstName,
LastName: lastName,
NickName: nickName,
DisplayName: displayName,
PreferredLanguage: preferredLanguage,
Gender: gender,
EmailAddress: emailAddress,
userLoginMustBeDomain: userLoginMustBeDomain,
UserName: userName,
FirstName: firstName,
LastName: lastName,
NickName: nickName,
DisplayName: displayName,
PreferredLanguage: preferredLanguage,
Gender: gender,
EmailAddress: emailAddress,
orgScopedUsername: orgScopedUsername,
}
}
@@ -139,22 +139,24 @@ func HumanAddedEventMapper(event eventstore.Event) (eventstore.Event, error) {
}
type HumanRegisteredEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
userLoginMustBeDomain bool
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
NickName string `json:"nickName,omitempty"`
DisplayName string `json:"displayName,omitempty"`
PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"`
Gender domain.Gender `json:"gender,omitempty"`
EmailAddress domain.EmailAddress `json:"email,omitempty"`
PhoneNumber domain.PhoneNumber `json:"phone,omitempty"`
Country string `json:"country,omitempty"`
Locality string `json:"locality,omitempty"`
PostalCode string `json:"postalCode,omitempty"`
Region string `json:"region,omitempty"`
StreetAddress string `json:"streetAddress,omitempty"`
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
orgScopedUsername bool
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
NickName string `json:"nickName,omitempty"`
DisplayName string `json:"displayName,omitempty"`
PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"`
Gender domain.Gender `json:"gender,omitempty"`
EmailAddress domain.EmailAddress `json:"email,omitempty"`
PhoneNumber domain.PhoneNumber `json:"phone,omitempty"`
Country string `json:"country,omitempty"`
Locality string `json:"locality,omitempty"`
PostalCode string `json:"postalCode,omitempty"`
Region string `json:"region,omitempty"`
StreetAddress string `json:"streetAddress,omitempty"`
// New events only use EncodedHash. However, the secret field
// is preserved to handle events older than the switch to Passwap.
@@ -170,7 +172,7 @@ func (e *HumanRegisteredEvent) Payload() interface{} {
}
func (e *HumanRegisteredEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain)}
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.orgScopedUsername)}
}
func (e *HumanRegisteredEvent) AddAddressData(
@@ -213,7 +215,7 @@ func NewHumanRegisteredEvent(
preferredLanguage language.Tag,
gender domain.Gender,
emailAddress domain.EmailAddress,
userLoginMustBeDomain bool,
orgScopedUsername bool,
userAgentID string,
) *HumanRegisteredEvent {
return &HumanRegisteredEvent{
@@ -222,16 +224,16 @@ func NewHumanRegisteredEvent(
aggregate,
HumanRegisteredType,
),
UserName: userName,
FirstName: firstName,
LastName: lastName,
NickName: nickName,
DisplayName: displayName,
PreferredLanguage: preferredLanguage,
Gender: gender,
EmailAddress: emailAddress,
userLoginMustBeDomain: userLoginMustBeDomain,
UserAgentID: userAgentID,
UserName: userName,
FirstName: firstName,
LastName: lastName,
NickName: nickName,
DisplayName: displayName,
PreferredLanguage: preferredLanguage,
Gender: gender,
EmailAddress: emailAddress,
orgScopedUsername: orgScopedUsername,
UserAgentID: userAgentID,
}
}

View File

@@ -17,8 +17,8 @@ const (
type MachineAddedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
userLoginMustBeDomain bool
UserName string `json:"userName"`
orgScopedUsername bool
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
@@ -30,7 +30,7 @@ func (e *MachineAddedEvent) Payload() interface{} {
}
func (e *MachineAddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain)}
return []*eventstore.UniqueConstraint{NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.orgScopedUsername)}
}
func NewMachineAddedEvent(
@@ -39,7 +39,7 @@ func NewMachineAddedEvent(
userName,
name,
description string,
userLoginMustBeDomain bool,
orgScopedUsername bool,
accessTokenType domain.OIDCTokenType,
) *MachineAddedEvent {
return &MachineAddedEvent{
@@ -48,11 +48,11 @@ func NewMachineAddedEvent(
aggregate,
MachineAddedEventType,
),
UserName: userName,
Name: name,
Description: description,
userLoginMustBeDomain: userLoginMustBeDomain,
AccessTokenType: accessTokenType,
UserName: userName,
Name: name,
Description: description,
orgScopedUsername: orgScopedUsername,
AccessTokenType: accessTokenType,
}
}

View File

@@ -27,9 +27,9 @@ const (
UserUserNameChangedType = userEventTypePrefix + "username.changed"
)
func NewAddUsernameUniqueConstraint(userName, resourceOwner string, userLoginMustBeDomain bool) *eventstore.UniqueConstraint {
func NewAddUsernameUniqueConstraint(userName, resourceOwner string, orgScopedUsername bool) *eventstore.UniqueConstraint {
uniqueUserName := userName
if userLoginMustBeDomain {
if orgScopedUsername {
uniqueUserName = userName + resourceOwner
}
return eventstore.NewAddEventUniqueConstraint(
@@ -38,9 +38,9 @@ func NewAddUsernameUniqueConstraint(userName, resourceOwner string, userLoginMus
"Errors.User.AlreadyExists")
}
func NewRemoveUsernameUniqueConstraint(userName, resourceOwner string, userLoginMustBeDomain bool) *eventstore.UniqueConstraint {
func NewRemoveUsernameUniqueConstraint(userName, resourceOwner string, orgScopedUsername bool) *eventstore.UniqueConstraint {
uniqueUserName := userName
if userLoginMustBeDomain {
if orgScopedUsername {
uniqueUserName = userName + resourceOwner
}
return eventstore.NewRemoveUniqueConstraint(
@@ -48,6 +48,18 @@ func NewRemoveUsernameUniqueConstraint(userName, resourceOwner string, userLogin
uniqueUserName)
}
func NewUsernameUniqueConstraints(usernameChanges []string, resourceOwner string, orgScopedUsername, oldOrgScopedUsername bool) []*eventstore.UniqueConstraint {
if len(usernameChanges) == 0 || oldOrgScopedUsername == orgScopedUsername {
return []*eventstore.UniqueConstraint{}
}
changes := make([]*eventstore.UniqueConstraint, len(usernameChanges)*2)
for i, username := range usernameChanges {
changes[i*2] = NewRemoveUsernameUniqueConstraint(username, resourceOwner, oldOrgScopedUsername)
changes[i*2+1] = NewAddUsernameUniqueConstraint(username, resourceOwner, orgScopedUsername)
}
return changes
}
type UserLockedEvent struct {
eventstore.BaseEvent `json:"-"`
}
@@ -165,7 +177,7 @@ type UserRemovedEvent struct {
userName string
externalIDPs []*domain.UserIDPLink
loginMustBeDomain bool
orgScopedUsername bool
}
func (e *UserRemovedEvent) Payload() interface{} {
@@ -175,7 +187,7 @@ func (e *UserRemovedEvent) Payload() interface{} {
func (e *UserRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
events := make([]*eventstore.UniqueConstraint, 0)
if e.userName != "" {
events = append(events, NewRemoveUsernameUniqueConstraint(e.userName, e.Aggregate().ResourceOwner, e.loginMustBeDomain))
events = append(events, NewRemoveUsernameUniqueConstraint(e.userName, e.Aggregate().ResourceOwner, e.orgScopedUsername))
}
for _, idp := range e.externalIDPs {
events = append(events, NewRemoveUserIDPLinkUniqueConstraint(idp.IDPConfigID, idp.ExternalUserID))
@@ -188,7 +200,7 @@ func NewUserRemovedEvent(
aggregate *eventstore.Aggregate,
userName string,
externalIDPs []*domain.UserIDPLink,
userLoginMustBeDomain bool,
orgScopedUsername bool,
) *UserRemovedEvent {
return &UserRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
@@ -198,7 +210,7 @@ func NewUserRemovedEvent(
),
userName: userName,
externalIDPs: externalIDPs,
loginMustBeDomain: userLoginMustBeDomain,
orgScopedUsername: orgScopedUsername,
}
}
@@ -393,10 +405,10 @@ func UserTokenRemovedEventMapper(event eventstore.Event) (eventstore.Event, erro
type DomainClaimedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
TriggeredAtOrigin string `json:"triggerOrigin,omitempty"`
oldUserName string
userLoginMustBeDomain bool
UserName string `json:"userName"`
TriggeredAtOrigin string `json:"triggerOrigin,omitempty"`
oldUserName string
orgScopedUsername bool
}
func (e *DomainClaimedEvent) Payload() interface{} {
@@ -405,8 +417,8 @@ func (e *DomainClaimedEvent) Payload() interface{} {
func (e *DomainClaimedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain),
NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain),
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, e.orgScopedUsername),
NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.orgScopedUsername),
}
}
@@ -419,7 +431,7 @@ func NewDomainClaimedEvent(
aggregate *eventstore.Aggregate,
userName,
oldUserName string,
userLoginMustBeDomain bool,
orgScopedUsername bool,
) *DomainClaimedEvent {
return &DomainClaimedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
@@ -427,10 +439,10 @@ func NewDomainClaimedEvent(
aggregate,
UserDomainClaimedType,
),
UserName: userName,
oldUserName: oldUserName,
userLoginMustBeDomain: userLoginMustBeDomain,
TriggeredAtOrigin: http.DomainContext(ctx).Origin(),
UserName: userName,
oldUserName: oldUserName,
orgScopedUsername: orgScopedUsername,
TriggeredAtOrigin: http.DomainContext(ctx).Origin(),
}
}
@@ -480,10 +492,11 @@ func DomainClaimedSentEventMapper(event eventstore.Event) (eventstore.Event, err
type UsernameChangedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
oldUserName string
userLoginMustBeDomain bool
oldUserLoginMustBeDomain bool
UserName string `json:"userName"`
oldUserName string
userLoginMustBeDomain bool
oldUserLoginMustBeDomain bool
organizationScopedUsernames bool
}
func (e *UsernameChangedEvent) Payload() interface{} {
@@ -491,9 +504,20 @@ func (e *UsernameChangedEvent) Payload() interface{} {
}
func (e *UsernameChangedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
newSetting := e.userLoginMustBeDomain || e.organizationScopedUsernames
oldSetting := e.oldUserLoginMustBeDomain || e.organizationScopedUsernames
// changes only necessary if username changed or setting for usernames changed
// if user login must be domain is set, there is a possibility that the username changes
// organization scoped usernames are included here so that the unique constraint only gets changed if necessary
if e.oldUserName == e.UserName &&
newSetting == oldSetting {
return []*eventstore.UniqueConstraint{}
}
return []*eventstore.UniqueConstraint{
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, e.oldUserLoginMustBeDomain),
NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, e.userLoginMustBeDomain),
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.Aggregate().ResourceOwner, oldSetting),
NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, newSetting),
}
}
@@ -503,6 +527,7 @@ func NewUsernameChangedEvent(
oldUserName,
newUserName string,
userLoginMustBeDomain bool,
organizationScopedUsernames bool,
opts ...UsernameChangedEventOption,
) *UsernameChangedEvent {
event := &UsernameChangedEvent{
@@ -511,10 +536,11 @@ func NewUsernameChangedEvent(
aggregate,
UserUserNameChangedType,
),
UserName: newUserName,
oldUserName: oldUserName,
userLoginMustBeDomain: userLoginMustBeDomain,
oldUserLoginMustBeDomain: userLoginMustBeDomain,
UserName: newUserName,
oldUserName: oldUserName,
userLoginMustBeDomain: userLoginMustBeDomain,
oldUserLoginMustBeDomain: userLoginMustBeDomain,
organizationScopedUsernames: organizationScopedUsernames,
}
for _, opt := range opts {
opt(event)
@@ -526,9 +552,9 @@ type UsernameChangedEventOption func(*UsernameChangedEvent)
// UsernameChangedEventWithPolicyChange signals that the change occurs because of / during a domain policy change
// (will ensure the unique constraint change is handled correctly)
func UsernameChangedEventWithPolicyChange() UsernameChangedEventOption {
func UsernameChangedEventWithPolicyChange(oldUserLoginMustBeDomain bool) UsernameChangedEventOption {
return func(e *UsernameChangedEvent) {
e.oldUserLoginMustBeDomain = !e.userLoginMustBeDomain
e.oldUserLoginMustBeDomain = oldUserLoginMustBeDomain
}
}