mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-12 19:14:23 +00:00
48f535afa1
fix: remove Domain and User correctly in DomainPolicyUsernamesWriteModel
182 lines
5.6 KiB
Go
182 lines
5.6 KiB
Go
package command
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/repository/org"
|
|
"github.com/zitadel/zitadel/internal/repository/policy"
|
|
"github.com/zitadel/zitadel/internal/repository/user"
|
|
)
|
|
|
|
type PolicyDomainWriteModel struct {
|
|
eventstore.WriteModel
|
|
|
|
UserLoginMustBeDomain bool
|
|
ValidateOrgDomains bool
|
|
SMTPSenderAddressMatchesInstanceDomain bool
|
|
State domain.PolicyState
|
|
}
|
|
|
|
func (wm *PolicyDomainWriteModel) Reduce() error {
|
|
for _, event := range wm.Events {
|
|
switch e := event.(type) {
|
|
case *policy.DomainPolicyAddedEvent:
|
|
wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain
|
|
wm.ValidateOrgDomains = e.ValidateOrgDomains
|
|
wm.SMTPSenderAddressMatchesInstanceDomain = e.SMTPSenderAddressMatchesInstanceDomain
|
|
wm.State = domain.PolicyStateActive
|
|
case *policy.DomainPolicyChangedEvent:
|
|
if e.UserLoginMustBeDomain != nil {
|
|
wm.UserLoginMustBeDomain = *e.UserLoginMustBeDomain
|
|
}
|
|
if e.ValidateOrgDomains != nil {
|
|
wm.ValidateOrgDomains = *e.ValidateOrgDomains
|
|
}
|
|
if e.SMTPSenderAddressMatchesInstanceDomain != nil {
|
|
wm.SMTPSenderAddressMatchesInstanceDomain = *e.SMTPSenderAddressMatchesInstanceDomain
|
|
}
|
|
case *policy.DomainPolicyRemovedEvent:
|
|
wm.State = domain.PolicyStateRemoved
|
|
}
|
|
}
|
|
return wm.WriteModel.Reduce()
|
|
}
|
|
|
|
type DomainPolicyUsernamesWriteModel struct {
|
|
eventstore.WriteModel
|
|
|
|
PrimaryDomain string
|
|
VerifiedDomains []string
|
|
Users []*domainPolicyUsers
|
|
}
|
|
|
|
type domainPolicyUsers struct {
|
|
id string
|
|
username string
|
|
}
|
|
|
|
func NewDomainPolicyUsernamesWriteModel(orgID string) *DomainPolicyUsernamesWriteModel {
|
|
return &DomainPolicyUsernamesWriteModel{
|
|
WriteModel: eventstore.WriteModel{
|
|
ResourceOwner: orgID,
|
|
},
|
|
Users: make([]*domainPolicyUsers, 0),
|
|
}
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) AppendEvents(events ...eventstore.Event) {
|
|
wm.WriteModel.AppendEvents(events...)
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) Reduce() error {
|
|
for _, event := range wm.Events {
|
|
switch e := event.(type) {
|
|
case *org.DomainVerifiedEvent:
|
|
wm.VerifiedDomains = append(wm.VerifiedDomains, e.Domain)
|
|
case *org.DomainRemovedEvent:
|
|
wm.removeDomain(e.Domain)
|
|
case *org.DomainPrimarySetEvent:
|
|
wm.PrimaryDomain = e.Domain
|
|
case *user.HumanAddedEvent:
|
|
wm.Users = append(wm.Users, &domainPolicyUsers{id: e.Aggregate().ID, username: e.UserName})
|
|
case *user.HumanRegisteredEvent:
|
|
wm.Users = append(wm.Users, &domainPolicyUsers{id: e.Aggregate().ID, username: e.UserName})
|
|
case *user.MachineAddedEvent:
|
|
wm.Users = append(wm.Users, &domainPolicyUsers{id: e.Aggregate().ID, username: e.UserName})
|
|
case *user.UsernameChangedEvent:
|
|
for _, user := range wm.Users {
|
|
if user.id == e.Aggregate().ID {
|
|
user.username = e.UserName
|
|
break
|
|
}
|
|
}
|
|
case *user.DomainClaimedEvent:
|
|
for _, user := range wm.Users {
|
|
if user.id == e.Aggregate().ID {
|
|
user.username = e.UserName
|
|
break
|
|
}
|
|
}
|
|
case *user.UserRemovedEvent:
|
|
wm.removeUser(e.Aggregate().ID)
|
|
}
|
|
}
|
|
return wm.WriteModel.Reduce()
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) removeDomain(domain string) {
|
|
for i, verifiedDomain := range wm.VerifiedDomains {
|
|
if verifiedDomain == domain {
|
|
wm.VerifiedDomains[i] = wm.VerifiedDomains[len(wm.VerifiedDomains)-1]
|
|
wm.VerifiedDomains[len(wm.VerifiedDomains)-1] = ""
|
|
wm.VerifiedDomains = wm.VerifiedDomains[:len(wm.VerifiedDomains)-1]
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) removeUser(userID string) {
|
|
for i, user := range wm.Users {
|
|
if user.id == userID {
|
|
wm.Users[i] = wm.Users[len(wm.Users)-1]
|
|
wm.Users[len(wm.Users)-1] = nil
|
|
wm.Users = wm.Users[:len(wm.Users)-1]
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
|
ResourceOwner(wm.ResourceOwner).
|
|
AddQuery().
|
|
AggregateTypes(org.AggregateType, user.AggregateType).
|
|
EventTypes(
|
|
org.OrgDomainVerifiedEventType,
|
|
org.OrgDomainRemovedEventType,
|
|
org.OrgDomainPrimarySetEventType,
|
|
user.HumanAddedType,
|
|
user.HumanRegisteredType,
|
|
user.MachineAddedEventType,
|
|
user.UserUserNameChangedType,
|
|
user.UserDomainClaimedType,
|
|
user.UserRemovedType,
|
|
).
|
|
Builder()
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) NewUsernameChangedEvents(ctx context.Context, userLoginMustBeDomain bool) []eventstore.Command {
|
|
events := make([]eventstore.Command, 0, len(wm.Users))
|
|
for _, changeUser := range wm.Users {
|
|
events = append(events, user.NewUsernameChangedEvent(ctx,
|
|
&user.NewAggregate(changeUser.id, wm.ResourceOwner).Aggregate,
|
|
changeUser.username,
|
|
wm.newUsername(changeUser.username, userLoginMustBeDomain),
|
|
userLoginMustBeDomain,
|
|
user.UsernameChangedEventWithPolicyChange()),
|
|
)
|
|
}
|
|
return events
|
|
}
|
|
|
|
func (wm *DomainPolicyUsernamesWriteModel) newUsername(username string, userLoginMustBeDomain bool) string {
|
|
if !userLoginMustBeDomain {
|
|
// if the UserLoginMustBeDomain will be false, then it's currently true
|
|
// which means the usernames must be suffixed to ensure their uniqueness
|
|
// and the preferred login name remains the same
|
|
return username + "@" + wm.PrimaryDomain
|
|
}
|
|
// the UserLoginMustBeDomain is currently false
|
|
// which means the usernames might already be suffixed by a verified domain
|
|
// so let's remove a potential duplicate suffix
|
|
for _, verifiedDomain := range wm.VerifiedDomains {
|
|
if index := strings.LastIndex(username, "@"+verifiedDomain); index > 0 {
|
|
return username[:index]
|
|
}
|
|
}
|
|
return username
|
|
}
|