feat: migrate unique constraints v1 to v2 (#1274)

* fix: unique migration

* fix: unique migration

* fix: remove migrations

* fix: member events
This commit is contained in:
Fabi 2021-02-15 13:31:24 +01:00 committed by GitHub
parent 3bc3ef1f2c
commit ee86eb4399
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 630 additions and 173 deletions

View File

@ -179,3 +179,5 @@ SetUp:
Greeting: Hello {{.FirstName}} {{.LastName}},
Text: The domain {{.Domain}} has been claimed by an organisation. Your current user {{.Username}} is not part of this organisation. Therefore you'll have to change your email when you login. We have created a temporary username ({{.TempUsername}}) for this login.
ButtonText: Login
Step11:
MigrateV1EventstoreToV2: true

View File

@ -16,6 +16,7 @@ type IAMSetUp struct {
Step8 *command.Step8
Step9 *command.Step9
Step10 *command.Step10
Step11 *command.Step11
}
func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
@ -32,6 +33,7 @@ func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) {
setup.Step8,
setup.Step9,
setup.Step10,
setup.Step11,
} {
if step.Step() <= currentDone {
continue

View File

@ -290,6 +290,8 @@ Errors:
NotInactive: Benutzer Berechtigung ist nicht deaktiviert
NoPermissionForProject: Benutzer hat keine Rechte auf diesem Projekt
RoleKeyNotFound: Rolle konnte nicht gefunden werden
Member:
AlreadyExists: Member existiert bereits
IDPConfig:
AlreadyExists: IDP Konfiguration mit diesem Name existiert bereits
Changes:

View File

@ -286,6 +286,8 @@ Errors:
NotInactive: User grant is not deactivated
NoPermissionForProject: User has no permissions on this project
RoleKeyNotFound: Role not found
Member:
AlreadyExists: Member already exists
IDPConfig:
AlreadyExists: IDP Configuration with this name already exists
Changes:

View File

@ -66,7 +66,7 @@ func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain
return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotExisting")
}
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, config.IDPConfigID, config.Name, config.StylingType)
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, existingIDP.ResourceOwner, config.IDPConfigID, config.Name, config.StylingType)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged")
}

View File

@ -84,13 +84,16 @@ func (wm *IAMIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventRead
func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
ctx context.Context,
resourceOwner,
configID,
name string,
stylingType domain.IDPConfigStylingType,
) (*iam.IDPConfigChangedEvent, bool) {
changes := make([]idpconfig.IDPConfigChanges, 0)
oldName := ""
if wm.Name != name {
oldName = wm.Name
changes = append(changes, idpconfig.ChangeName(name))
}
if stylingType.Valid() && wm.StylingType != stylingType {
@ -99,7 +102,7 @@ func (wm *IAMIDPConfigWriteModel) NewChangedEvent(
if len(changes) == 0 {
return nil, false
}
changeEvent, err := iam.NewIDPConfigChangedEvent(ctx, configID, changes)
changeEvent, err := iam.NewIDPConfigChangedEvent(ctx, resourceOwner, configID, oldName, changes)
if err != nil {
return nil, false
}

View File

@ -42,7 +42,7 @@ func (r *CommandSide) addIAMMember(ctx context.Context, iamAgg *iam_repo.Aggrega
return errors.ThrowAlreadyExists(nil, "IAM-sdgQ4", "Errors.IAM.Member.AlreadyExists")
}
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, iamAgg.ID(), member.UserID, member.Roles...))
return nil
}
@ -89,7 +89,7 @@ func (r *CommandSide) RemoveIAMMember(ctx context.Context, userID string) error
}
iamAgg := IAMAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, userID))
iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, iamAgg.ID(), userID))
return r.eventstore.PushAggregate(ctx, m, iamAgg)
}

View File

@ -27,14 +27,6 @@ func NewIAMWriteModel() *IAMWriteModel {
func (wm *IAMWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
//for _, event := range events {
// switch e := event.(type) {
// case *iam.LabelPolicyAddedEvent:
// wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyAddedEvent)
// case *iam.LabelPolicyChangedEvent:
// wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyChangedEvent)
// }
//}
}
func (wm *IAMWriteModel) Reduce() error {
@ -61,17 +53,6 @@ func (wm *IAMWriteModel) Query() *eventstore.SearchQueryBuilder {
ResourceOwner(wm.ResourceOwner)
}
//
//func (wm *IAMLabelPolicyWriteModel) HasChanged(primaryColor, secondaryColor string) bool {
// if primaryColor != "" && wm.PrimaryColor != primaryColor {
// return true
// }
// if secondaryColor != "" && wm.SecondaryColor != secondaryColor {
// return true
// }
// return false
//}
func IAMAggregateFromWriteModel(wm *eventstore.WriteModel) *iam.Aggregate {
return &iam.Aggregate{
Aggregate: *eventstore.AggregateFromWriteModel(wm, iam.AggregateType, iam.AggregateVersion),

View File

@ -67,7 +67,13 @@ func (r *CommandSide) ChangeIDPConfig(ctx context.Context, config *domain.IDPCon
return nil, caos_errs.ThrowNotFound(nil, "Org-4M9so", "Errors.Org.IDPConfig.NotExisting")
}
changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, config.IDPConfigID, config.Name, config.StylingType)
changedEvent, hasChanged := existingIDP.NewChangedEvent(
ctx,
existingIDP.ResourceOwner,
config.IDPConfigID,
config.Name,
config.StylingType)
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-4M9vs", "Errors.Org.LabelPolicy.NotChanged")
}

View File

@ -84,13 +84,16 @@ func (wm *OrgIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventRead
func (wm *OrgIDPConfigWriteModel) NewChangedEvent(
ctx context.Context,
resourceOwner,
configID,
name string,
stylingType domain.IDPConfigStylingType,
) (*org.IDPConfigChangedEvent, bool) {
changes := make([]idpconfig.IDPConfigChanges, 0)
oldName := ""
if wm.Name != name {
oldName = wm.Name
changes = append(changes, idpconfig.ChangeName(name))
}
if stylingType.Valid() && wm.StylingType != stylingType {
@ -99,7 +102,7 @@ func (wm *OrgIDPConfigWriteModel) NewChangedEvent(
if len(changes) == 0 {
return nil, false
}
changeEvent, err := org.NewIDPConfigChangedEvent(ctx, configID, changes)
changeEvent, err := org.NewIDPConfigChangedEvent(ctx, resourceOwner, configID, oldName, changes)
if err != nil {
return nil, false
}

View File

@ -42,7 +42,7 @@ func (r *CommandSide) addOrgMember(ctx context.Context, orgAgg *org.Aggregate, a
return errors.ThrowAlreadyExists(nil, "Org-PtXi1", "Errors.Org.Member.AlreadyExists")
}
orgAgg.PushEvents(org.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
orgAgg.PushEvents(org.NewMemberAddedEvent(ctx, orgAgg.ID(), member.UserID, member.Roles...))
return nil
}
@ -89,7 +89,7 @@ func (r *CommandSide) RemoveOrgMember(ctx context.Context, orgID, userID string)
}
orgAgg := OrgAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
orgAgg.PushEvents(org.NewMemberRemovedEvent(ctx, userID))
orgAgg.PushEvents(org.NewMemberRemovedEvent(ctx, orgAgg.ID(), userID))
return r.eventstore.PushAggregate(ctx, m, orgAgg)
}

View File

@ -84,7 +84,7 @@ func (r *CommandSide) ChangeProject(ctx context.Context, projectChange *domain.P
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound")
}
changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck)
changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, existingProject.ResourceOwner, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck)
if err != nil {
return nil, err
}
@ -141,7 +141,7 @@ func (r *CommandSide) ReactivateProject(ctx context.Context, projectID string, r
}
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
projectAgg.PushEvents(project.NewProjectDeactivatedEvent(ctx))
projectAgg.PushEvents(project.NewProjectReactivatedEvent(ctx))
return r.eventstore.PushAggregate(ctx, existingProject, projectAgg)
}

View File

@ -8,7 +8,6 @@ import (
"github.com/caos/zitadel/internal/telemetry/tracing"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/project"
"github.com/caos/zitadel/internal/v2/repository/usergrant"
"reflect"
)
@ -123,7 +122,7 @@ func (r *CommandSide) removeRoleFromProjectGrant(ctx context.Context, projectAgg
)
} else {
projectAgg.PushEvents(
usergrant.NewUserGrantCascadeChangedEvent(ctx, existingProjectGrant.RoleKeys),
project.NewGrantCascadeChangedEvent(ctx, projectGrantID, existingProjectGrant.RoleKeys),
)
}

View File

@ -46,7 +46,7 @@ func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *project.
return errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists")
}
projectAgg.PushEvents(project.NewProjectMemberAddedEvent(ctx, member.UserID, member.Roles...))
projectAgg.PushEvents(project.NewProjectMemberAddedEvent(ctx, projectAgg.ID(), member.UserID, member.Roles...))
return nil
}
@ -93,7 +93,7 @@ func (r *CommandSide) RemoveProjectMember(ctx context.Context, projectID, userID
}
projectAgg := ProjectAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
projectAgg.PushEvents(project.NewProjectMemberRemovedEvent(ctx, userID))
projectAgg.PushEvents(project.NewProjectMemberRemovedEvent(ctx, projectAgg.ID(), userID))
return r.eventstore.PushAggregate(ctx, m, projectAgg)
}

View File

@ -72,6 +72,7 @@ func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder {
func (wm *ProjectWriteModel) NewChangedEvent(
ctx context.Context,
resourceOwner,
name string,
projectRoleAssertion,
projectRoleCheck bool,
@ -79,7 +80,9 @@ func (wm *ProjectWriteModel) NewChangedEvent(
changes := make([]project.ProjectChanges, 0)
var err error
oldName := ""
if wm.Name != name {
oldName = wm.Name
changes = append(changes, project.ChangeName(name))
}
if wm.ProjectRoleAssertion != projectRoleAssertion {
@ -91,7 +94,7 @@ func (wm *ProjectWriteModel) NewChangedEvent(
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := project.NewProjectChangeEvent(ctx, changes)
changeEvent, err := project.NewProjectChangeEvent(ctx, resourceOwner, oldName, changes)
if err != nil {
return nil, false, err
}

View File

@ -51,7 +51,6 @@ func (r *CommandSide) addProjectRoles(ctx context.Context, projectAgg *project.A
projectRole.DisplayName,
projectRole.Group,
projectID,
resourceOwner,
),
)
}
@ -107,7 +106,7 @@ func (r *CommandSide) RemoveProjectRole(ctx context.Context, projectID, key, res
}
aggregates := make([]eventstore.Aggregater, 0)
projectAgg := ProjectAggregateFromWriteModel(&existingRole.WriteModel)
projectAgg.PushEvents(project.NewRoleRemovedEvent(ctx, key, projectID, existingRole.ResourceOwner))
projectAgg.PushEvents(project.NewRoleRemovedEvent(ctx, key, projectID))
for _, projectGrantID := range cascadingProjectGrantIds {
_, err = r.removeRoleFromProjectGrant(ctx, projectAgg, projectID, projectGrantID, key, true)
if err != nil {

View File

@ -0,0 +1,35 @@
package command
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
)
type Step11 struct {
MigrateV1EventstoreToV2 bool
}
func (s *Step11) Step() domain.Step {
return domain.Step11
}
func (s *Step11) execute(ctx context.Context, commandSide *CommandSide) error {
return commandSide.SetupStep11(ctx, s)
}
func (r *CommandSide) SetupStep11(ctx context.Context, step *Step11) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
uniqueConstraints := NewUniqueConstraintReadModel(ctx, r)
err := r.eventstore.FilterToQueryReducer(ctx, uniqueConstraints)
if err != nil {
return nil, err
}
iamAgg.PushEvents(iam_repo.NewMigrateUniqueConstraintEvent(ctx, uniqueConstraints.UniqueConstraints))
logging.Log("SETUP-M9fsd").Info("migrate v1 eventstore to v2")
return iamAgg, nil
}
return r.setup(ctx, step, fn)
}

View File

@ -0,0 +1,255 @@
package command
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/idpconfig"
"github.com/caos/zitadel/internal/v2/repository/member"
"github.com/caos/zitadel/internal/v2/repository/org"
"github.com/caos/zitadel/internal/v2/repository/policy"
"github.com/caos/zitadel/internal/v2/repository/project"
"github.com/caos/zitadel/internal/v2/repository/user"
"github.com/caos/zitadel/internal/v2/repository/usergrant"
)
type UniqueConstraintReadModel struct {
eventstore.WriteModel
UniqueConstraints []*domain.UniqueConstraintMigration
commandProvider commandProvider
ctx context.Context
}
type commandProvider interface {
getOrgIAMPolicy(ctx context.Context, orgID string) (*domain.OrgIAMPolicy, error)
}
func NewUniqueConstraintReadModel(ctx context.Context, provider commandProvider) *UniqueConstraintReadModel {
return &UniqueConstraintReadModel{
ctx: ctx,
commandProvider: provider,
}
}
func (rm *UniqueConstraintReadModel) AppendEvents(events ...eventstore.EventReader) {
rm.WriteModel.AppendEvents(events...)
}
func (rm *UniqueConstraintReadModel) Reduce() error {
for _, event := range rm.Events {
switch e := event.(type) {
case *org.OrgAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name))
case *org.OrgChangedEvent:
rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Name))
case *org.DomainVerificationAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), org.NewAddOrgNameUniqueConstraint(e.Domain))
case *org.DomainRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), org.UniqueOrgDomain)
case *iam.IDPConfigAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner()))
case *iam.IDPConfigChangedEvent:
rm.changeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner()))
case *iam.IDPConfigRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.UniqueIDPConfigNameType)
case *org.IDPConfigAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(e.Name, e.ResourceOwner()))
case *org.IDPConfigChangedEvent:
rm.changeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner()))
case *org.IDPConfigRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.ConfigID, idpconfig.UniqueIDPConfigNameType)
case *iam.MailTextAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.AggregateID(), e.MailTextType, e.Language))
case *org.MailTextAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.NewAddMailTextUniqueConstraint(e.AggregateID(), e.MailTextType, e.Language))
case *org.MailTextRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.MailTextType+e.Language, policy.UniqueMailText)
case *project.ProjectAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), project.NewAddProjectNameUniqueConstraint(e.Name, e.ResourceOwner()))
case *project.ProjectChangeEvent:
rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), project.NewAddProjectNameUniqueConstraint(*e.Name, e.ResourceOwner()))
case *project.ProjectRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), project.UniqueProjectnameType)
case *project.ApplicationAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.AggregateID()))
case *project.ApplicationChangedEvent:
rm.changeUniqueConstraint(e.AggregateID(), e.AppID, project.NewAddApplicationUniqueConstraint(e.Name, e.AggregateID()))
case *project.ApplicationRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AppID, project.UniqueAppNameType)
case *project.GrantAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.GrantID, project.NewAddProjectGrantUniqueConstraint(e.GrantedOrgID, e.AggregateID()))
case *project.GrantRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.GrantID, project.UniqueGrantType)
case *project.GrantMemberAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.GrantID+e.UserID, project.NewAddProjectGrantMemberUniqueConstraint(e.AggregateID(), e.UserID, e.GrantID))
case *project.GrantMemberRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.GrantID+e.UserID, project.UniqueProjectGrantMemberType)
case *project.RoleAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.Key, project.NewAddProjectRoleUniqueConstraint(e.Key, e.AggregateID()))
case *project.RoleRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.Key, project.UniqueRoleType)
case *user.HumanAddedEvent:
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner())
if err != nil {
logging.Log("COMMAND-0k9Gs").WithError(err).Error("could not read policy for human added event unique constraint")
continue
}
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain))
case *user.HumanRegisteredEvent:
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner())
if err != nil {
logging.Log("COMMAND-m9fod").WithError(err).Error("could not read policy for human registered event unique constraint")
continue
}
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain))
case *user.MachineAddedEvent:
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner())
if err != nil {
logging.Log("COMMAND-2n8vs").WithError(err).Error("could not read policy for machine added event unique constraint")
continue
}
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain))
case *user.UserRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.UniqueUsername)
case *user.UsernameChangedEvent:
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner())
if err != nil {
logging.Log("COMMAND-5n8gk").WithError(err).Error("could not read policy for username changed event unique constraint")
continue
}
rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain))
case *user.DomainClaimedEvent:
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.ResourceOwner())
if err != nil {
logging.Log("COMMAND-xb8uf").WithError(err).Error("could not read policy for domain claimed event unique constraint")
continue
}
rm.changeUniqueConstraint(e.AggregateID(), e.AggregateID(), user.NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), policy.UserLoginMustBeDomain))
case *user.HumanExternalIDPAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID))
case *user.HumanExternalIDPRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType)
case *user.HumanExternalIDPCascadeRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType)
case *usergrant.UserGrantAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID, e.ProjectGrantID))
case *usergrant.UserGrantRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.UniqueUserGrant)
case *usergrant.UserGrantCascadeRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.AggregateID(), usergrant.UniqueUserGrant)
case *iam.MemberAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID))
case *iam.MemberRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember)
case *org.MemberAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID))
case *org.MemberRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember)
case *project.MemberAddedEvent:
rm.addUniqueConstraint(e.AggregateID(), e.UserID, member.NewAddMemberUniqueConstraint(e.AggregateID(), e.UserID))
case *project.MemberRemovedEvent:
rm.removeUniqueConstraint(e.AggregateID(), e.UserID, member.UniqueMember)
}
}
return nil
}
func (rm *UniqueConstraintReadModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
AggregateIDs(rm.AggregateID).
ResourceOwner(rm.ResourceOwner).
EventTypes(
org.OrgAddedEventType,
org.OrgChangedEventType,
org.OrgDomainVerifiedEventType,
org.OrgDomainRemovedEventType,
iam.IDPConfigAddedEventType,
iam.IDPConfigChangedEventType,
iam.IDPConfigRemovedEventType,
org.IDPConfigAddedEventType,
org.IDPConfigChangedEventType,
org.IDPConfigRemovedEventType,
iam.MailTextAddedEventType,
org.MailTextAddedEventType,
org.MailTextRemovedEventType,
project.ProjectAddedType,
project.ProjectChangedType,
project.ProjectRemovedType,
project.ApplicationAddedType,
project.ApplicationChangedType,
project.ApplicationRemovedType,
project.GrantAddedType,
project.GrantRemovedType,
project.GrantMemberAddedType,
project.GrantMemberRemovedType,
project.RoleAddedType,
project.RoleRemovedType,
user.HumanAddedType,
user.HumanRegisteredType,
user.MachineAddedEventType,
user.UserUserNameChangedType,
user.UserDomainClaimedType,
user.UserRemovedType,
user.HumanExternalIDPAddedType,
user.HumanExternalIDPRemovedType,
user.HumanExternalIDPCascadeRemovedType,
usergrant.UserGrantAddedType,
usergrant.UserGrantRemovedType,
usergrant.UserGrantCascadeRemovedType,
iam.MemberAddedEventType,
iam.MemberRemovedEventType,
org.MemberAddedEventType,
org.MemberRemovedEventType,
project.MemberAddedType,
project.MemberRemovedType,
)
}
func (rm *UniqueConstraintReadModel) getUniqueConstraint(aggregateID, objectID, constraintType string) *domain.UniqueConstraintMigration {
for _, uniqueConstraint := range rm.UniqueConstraints {
if uniqueConstraint.AggregateID == aggregateID && uniqueConstraint.ObjectID == objectID && uniqueConstraint.UniqueType == constraintType {
return uniqueConstraint
}
}
return nil
}
func (rm *UniqueConstraintReadModel) addUniqueConstraint(aggregateID, objectID string, constraint *eventstore.EventUniqueConstraint) {
migrateUniqueConstraint := &domain.UniqueConstraintMigration{
AggregateID: aggregateID,
ObjectID: objectID,
UniqueType: constraint.UniqueType,
UniqueField: constraint.UniqueField,
ErrorMessage: constraint.ErrorMessage,
}
rm.UniqueConstraints = append(rm.UniqueConstraints, migrateUniqueConstraint)
}
func (rm *UniqueConstraintReadModel) changeUniqueConstraint(aggregateID, objectID string, constraint *eventstore.EventUniqueConstraint) {
for i, uniqueConstraint := range rm.UniqueConstraints {
if uniqueConstraint.AggregateID == aggregateID && uniqueConstraint.ObjectID == objectID && uniqueConstraint.UniqueType == constraint.UniqueType {
rm.UniqueConstraints[i] = &domain.UniqueConstraintMigration{
AggregateID: aggregateID,
ObjectID: objectID,
UniqueType: constraint.UniqueType,
UniqueField: constraint.UniqueField,
ErrorMessage: constraint.ErrorMessage,
}
return
}
}
}
func (rm *UniqueConstraintReadModel) removeUniqueConstraint(aggregateID, objectID, constraintType string) {
for i, uniqueConstraint := range rm.UniqueConstraints {
if uniqueConstraint.AggregateID == aggregateID && uniqueConstraint.ObjectID == objectID && uniqueConstraint.UniqueType == constraintType {
copy(rm.UniqueConstraints[i:], rm.UniqueConstraints[i+1:])
rm.UniqueConstraints[len(rm.UniqueConstraints)-1] = nil
rm.UniqueConstraints = rm.UniqueConstraints[:len(rm.UniqueConstraints)-1]
return
}
}
}

View File

@ -218,11 +218,16 @@ func (r *CommandSide) userDomainClaimed(ctx context.Context, userID string) (_ *
changedUserGrant := NewUserWriteModel(userID, existingUser.ResourceOwner)
userAgg := UserAggregateFromWriteModel(&changedUserGrant.WriteModel)
orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, existingUser.ResourceOwner)
if err != nil {
return nil, nil, err
}
id, err := r.idGenerator.Next()
if err != nil {
return nil, nil, err
}
userAgg.PushEvents(user.NewDomainClaimedEvent(ctx, fmt.Sprintf("%s@temporary.%s", id, r.iamDomain)))
userAgg.PushEvents(user.NewDomainClaimedEvent(ctx, fmt.Sprintf("%s@temporary.%s", id, r.iamDomain), existingUser.UserName, orgIAMPolicy.UserLoginMustBeDomain))
return userAgg, changedUserGrant, nil
}

View File

@ -251,11 +251,21 @@ func (r *CommandSide) removeUserGrant(ctx context.Context, grantID, resourceOwne
userGrantAgg := UserGrantAggregateFromWriteModel(&removeUserGrant.WriteModel)
if !cascade {
userGrantAgg.PushEvents(
usergrant.NewUserGrantRemovedEvent(ctx, existingUserGrant.ResourceOwner, existingUserGrant.UserID, existingUserGrant.ProjectID),
usergrant.NewUserGrantRemovedEvent(
ctx,
existingUserGrant.ResourceOwner,
existingUserGrant.UserID,
existingUserGrant.ProjectID,
existingUserGrant.ProjectGrantID),
)
} else {
userGrantAgg.PushEvents(
usergrant.NewUserGrantCascadeRemovedEvent(ctx, existingUserGrant.ResourceOwner, existingUserGrant.UserID, existingUserGrant.ProjectID),
usergrant.NewUserGrantCascadeRemovedEvent(
ctx,
existingUserGrant.ResourceOwner,
existingUserGrant.UserID,
existingUserGrant.ProjectID,
existingUserGrant.ProjectGrantID),
)
}

View File

@ -37,7 +37,7 @@ func (wm *HumanExternalIDPWriteModel) Reduce() error {
case *user.HumanExternalIDPAddedEvent:
wm.IDPConfigID = e.IDPConfigID
wm.DisplayName = e.DisplayName
wm.ExternalUserID = e.UserID
wm.ExternalUserID = e.ExternalUserID
wm.State = domain.ExternalIDPStateActive
case *user.HumanExternalIDPRemovedEvent:
wm.State = domain.ExternalIDPStateRemoved

View File

@ -13,6 +13,7 @@ const (
Step8
Step9
Step10
Step11
//StepCount marks the the length of possible steps (StepCount-1 == last possible step)
StepCount
)

View File

@ -0,0 +1,9 @@
package domain
type UniqueConstraintMigration struct {
AggregateID string
ObjectID string
UniqueType string
UniqueField string
ErrorMessage string
}

View File

@ -9,6 +9,7 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(SetupDoneEventType, SetupStepMapper).
RegisterFilterEventMapper(GlobalOrgSetEventType, GlobalOrgSetMapper).
RegisterFilterEventMapper(ProjectSetEventType, ProjectSetMapper).
RegisterFilterEventMapper(UniqueConstraintsMigratedEventType, MigrateUniqueConstraintEventMapper).
RegisterFilterEventMapper(LabelPolicyAddedEventType, LabelPolicyAddedEventMapper).
RegisterFilterEventMapper(LabelPolicyChangedEventType, LabelPolicyChangedEventMapper).
RegisterFilterEventMapper(LoginPolicyAddedEventType, LoginPolicyAddedEventMapper).
@ -33,6 +34,10 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(LoginPolicyIDPProviderAddedEventType, IdentityProviderAddedEventMapper).
RegisterFilterEventMapper(LoginPolicyIDPProviderRemovedEventType, IdentityProviderRemovedEventMapper).
RegisterFilterEventMapper(LoginPolicyIDPProviderCascadeRemovedEventType, IdentityProviderCascadeRemovedEventMapper).
RegisterFilterEventMapper(LoginPolicySecondFactorAddedEventType, SecondFactorAddedEventMapper).
RegisterFilterEventMapper(LoginPolicySecondFactorRemovedEventType, SecondFactorRemovedEventMapper).
RegisterFilterEventMapper(LoginPolicyMultiFactorAddedEventType, MultiFactorAddedEventMapper).
RegisterFilterEventMapper(LoginPolicyMultiFactorRemovedEventType, MultiFactorRemovedEventMapper).
RegisterFilterEventMapper(MailTemplateAddedEventType, MailTemplateAddedEventMapper).
RegisterFilterEventMapper(MailTemplateChangedEventType, MailTemplateChangedEventMapper).
RegisterFilterEventMapper(MailTextAddedEventType, MailTextAddedEventMapper).

View File

@ -59,12 +59,15 @@ type IDPConfigChangedEvent struct {
func NewIDPConfigChangedEvent(
ctx context.Context,
configID string,
resourceOwner,
configID,
oldName string,
changes []idpconfig.IDPConfigChanges,
) (*IDPConfigChangedEvent, error) {
changeEvent, err := idpconfig.NewIDPConfigChangedEvent(
eventstore.NewBaseEventForPush(ctx, IDPConfigChangedEventType),
eventstore.NewBaseEventForPushWithResourceOwner(ctx, IDPConfigChangedEventType, resourceOwner),
configID,
oldName,
changes,
)
if err != nil {

View File

@ -19,6 +19,7 @@ type MemberAddedEvent struct {
func NewMemberAddedEvent(
ctx context.Context,
aggregateID,
userID string,
roles ...string,
) *MemberAddedEvent {
@ -29,6 +30,7 @@ func NewMemberAddedEvent(
ctx,
MemberAddedEventType,
),
aggregateID,
userID,
roles...,
),
@ -80,6 +82,7 @@ type MemberRemovedEvent struct {
func NewMemberRemovedEvent(
ctx context.Context,
aggregateID,
userID string,
) *MemberRemovedEvent {
@ -89,6 +92,7 @@ func NewMemberRemovedEvent(
ctx,
MemberRemovedEventType,
),
aggregateID,
userID,
),
}

View File

@ -0,0 +1,54 @@
package iam
import (
"context"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
)
const (
UniqueConstraintsMigratedEventType eventstore.EventType = "iam.unique.constraints.migrated"
)
type MigrateUniqueConstraintEvent struct {
eventstore.BaseEvent `json:"-"`
uniqueConstraintMigrations []*domain.UniqueConstraintMigration `json:"-"`
}
func NewAddMigrateUniqueConstraint(uniqueMigration *domain.UniqueConstraintMigration) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueMigration.UniqueType,
uniqueMigration.UniqueField,
uniqueMigration.ErrorMessage)
}
func (e *MigrateUniqueConstraintEvent) Data() interface{} {
return nil
}
func (e *MigrateUniqueConstraintEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
constraints := make([]*eventstore.EventUniqueConstraint, len(e.uniqueConstraintMigrations))
for i, uniqueMigration := range e.uniqueConstraintMigrations {
constraints[i] = NewAddMigrateUniqueConstraint(uniqueMigration)
}
return constraints
}
func NewMigrateUniqueConstraintEvent(ctx context.Context, uniqueConstraintMigrations []*domain.UniqueConstraintMigration) *MigrateUniqueConstraintEvent {
return &MigrateUniqueConstraintEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
UniqueConstraintsMigratedEventType,
),
uniqueConstraintMigrations: uniqueConstraintMigrations,
}
}
func MigrateUniqueConstraintEventMapper(event *repository.Event) (eventstore.EventReader, error) {
return &MigrateUniqueConstraintEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}, nil
}

View File

@ -31,7 +31,7 @@ func NewLoginPolicySecondFactorAddedEvent(
}
}
func SecondFactorAddedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) {
func SecondFactorAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := policy.SecondFactorAddedEventMapper(event)
if err != nil {
return nil, err
@ -58,7 +58,7 @@ func NewLoginPolicySecondFactorRemovedEvent(
}
}
func SecondFactorRemovedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) {
func SecondFactorRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := policy.SecondFactorRemovedEventMapper(event)
if err != nil {
return nil, err
@ -84,7 +84,7 @@ func NewLoginPolicyMultiFactorAddedEvent(
}
}
func MultiFactorAddedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) {
func MultiFactorAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := policy.MultiFactorAddedEventMapper(event)
if err != nil {
return nil, err
@ -111,7 +111,7 @@ func NewLoginPolicyMultiFactorRemovedEvent(
}
}
func MultiFactorRemovedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) {
func MultiFactorRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := policy.MultiFactorRemovedEventMapper(event)
if err != nil {
return nil, err

View File

@ -10,19 +10,19 @@ import (
)
const (
uniqueIDPConfigNameType = "idp_config_names"
UniqueIDPConfigNameType = "idp_config_names"
)
func NewAddIDPConfigNameUniqueConstraint(idpConfigName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueIDPConfigNameType,
UniqueIDPConfigNameType,
idpConfigName+resourceOwner,
"Errors.IDPConfig.AlreadyExists")
}
func NewRemoveIDPConfigNameUniqueConstraint(idpConfigName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueIDPConfigNameType,
UniqueIDPConfigNameType,
idpConfigName+resourceOwner)
}
@ -78,6 +78,7 @@ type IDPConfigChangedEvent struct {
ConfigID string `json:"idpConfigId"`
Name *string `json:"name,omitempty"`
StylingType *domain.IDPConfigStylingType `json:"stylingType,omitempty"`
oldName string `json:"-"`
}
func (e *IDPConfigChangedEvent) Data() interface{} {
@ -85,12 +86,19 @@ func (e *IDPConfigChangedEvent) Data() interface{} {
}
func (e *IDPConfigChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
if e.oldName == "" {
return nil
}
return []*eventstore.EventUniqueConstraint{
NewRemoveIDPConfigNameUniqueConstraint(e.oldName, e.ResourceOwner()),
NewAddIDPConfigNameUniqueConstraint(*e.Name, e.ResourceOwner()),
}
}
func NewIDPConfigChangedEvent(
base *eventstore.BaseEvent,
configID string,
configID,
oldName string,
changes []IDPConfigChanges,
) (*IDPConfigChangedEvent, error) {
if len(changes) == 0 {
@ -99,6 +107,7 @@ func NewIDPConfigChangedEvent(
changeEvent := &IDPConfigChangedEvent{
BaseEvent: *base,
ConfigID: configID,
oldName: oldName,
}
for _, change := range changes {
change(changeEvent)

View File

@ -2,22 +2,39 @@ package member
import (
"encoding/json"
"fmt"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
)
const (
UniqueMember = "member"
AddedEventType = "member.added"
ChangedEventType = "member.changed"
RemovedEventType = "member.removed"
)
func NewAddMemberUniqueConstraint(aggregateID, userID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
UniqueMember,
fmt.Sprintf("%s:%s", aggregateID, userID),
"Errors.Member.AlreadyExists")
}
func NewRemoveMemberUniqueConstraint(aggregateID, userID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
UniqueMember,
fmt.Sprintf("%s:%s", aggregateID, userID),
)
}
type MemberAddedEvent struct {
eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"`
UserID string `json:"userId"`
aggregateID string
}
func (e *MemberAddedEvent) Data() interface{} {
@ -25,17 +42,19 @@ func (e *MemberAddedEvent) Data() interface{} {
}
func (e *MemberAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
return []*eventstore.EventUniqueConstraint{NewAddMemberUniqueConstraint(e.aggregateID, e.UserID)}
}
func NewMemberAddedEvent(
base *eventstore.BaseEvent,
aggregateID,
userID string,
roles ...string,
) *MemberAddedEvent {
return &MemberAddedEvent{
BaseEvent: *base,
aggregateID: aggregateID,
Roles: roles,
UserID: userID,
}
@ -98,6 +117,7 @@ type MemberRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
UserID string `json:"userId"`
aggregateID string
}
func (e *MemberRemovedEvent) Data() interface{} {
@ -105,16 +125,18 @@ func (e *MemberRemovedEvent) Data() interface{} {
}
func (e *MemberRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
return []*eventstore.EventUniqueConstraint{NewRemoveMemberUniqueConstraint(e.aggregateID, e.UserID)}
}
func NewRemovedEvent(
base *eventstore.BaseEvent,
aggregateID,
userID string,
) *MemberRemovedEvent {
return &MemberRemovedEvent{
BaseEvent: *base,
aggregateID: aggregateID,
UserID: userID,
}
}

View File

@ -12,7 +12,7 @@ import (
)
const (
uniqueOrgDomain = "org_domain"
UniqueOrgDomain = "org_domain"
domainEventPrefix = orgEventTypePrefix + "domain."
OrgDomainAddedEventType = domainEventPrefix + "added"
OrgDomainVerificationAddedEventType = domainEventPrefix + "verification.added"
@ -24,14 +24,14 @@ const (
func NewAddOrgDomainUniqueConstraint(orgDomain string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueOrgDomain,
UniqueOrgDomain,
orgDomain,
"Errors.Org.Domain.AlreadyExists")
}
func NewRemoveOrgDomainUniqueConstraint(orgDomain string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueOrgDomain,
UniqueOrgDomain,
orgDomain)
}
@ -84,7 +84,7 @@ func (e *DomainVerificationAddedEvent) Data() interface{} {
}
func (e *DomainVerificationAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddOrgDomainUniqueConstraint(e.Domain)}
return nil
}
func NewDomainVerificationAddedEvent(
@ -162,7 +162,7 @@ func (e *DomainVerifiedEvent) Data() interface{} {
}
func (e *DomainVerifiedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
return []*eventstore.EventUniqueConstraint{NewAddOrgDomainUniqueConstraint(e.Domain)}
}
func NewDomainVerifiedEvent(ctx context.Context, domain string) *DomainVerifiedEvent {

View File

@ -49,5 +49,12 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(MailTemplateRemovedEventType, MailTemplateRemovedEventMapper).
RegisterFilterEventMapper(MailTextAddedEventType, MailTextAddedEventMapper).
RegisterFilterEventMapper(MailTextChangedEventType, MailTextChangedEventMapper).
RegisterFilterEventMapper(MailTextRemovedEventType, MailTextRemovedEventMapper)
RegisterFilterEventMapper(MailTextRemovedEventType, MailTextRemovedEventMapper).
RegisterFilterEventMapper(IDPConfigAddedEventType, IDPConfigAddedEventMapper).
RegisterFilterEventMapper(IDPConfigChangedEventType, IDPConfigChangedEventMapper).
RegisterFilterEventMapper(IDPConfigRemovedEventType, IDPConfigRemovedEventMapper).
RegisterFilterEventMapper(IDPConfigDeactivatedEventType, IDPConfigDeactivatedEventMapper).
RegisterFilterEventMapper(IDPConfigReactivatedEventType, IDPConfigReactivatedEventMapper).
RegisterFilterEventMapper(IDPOIDCConfigAddedEventType, IDPOIDCConfigAddedEventMapper).
RegisterFilterEventMapper(IDPOIDCConfigChangedEventType, IDPOIDCConfigChangedEventMapper)
}

View File

@ -59,12 +59,15 @@ type IDPConfigChangedEvent struct {
func NewIDPConfigChangedEvent(
ctx context.Context,
configID string,
resourceOwner,
configID,
oldName string,
changes []idpconfig.IDPConfigChanges,
) (*IDPConfigChangedEvent, error) {
changeEvent, err := idpconfig.NewIDPConfigChangedEvent(
eventstore.NewBaseEventForPush(ctx, IDPConfigChangedEventType),
eventstore.NewBaseEventForPushWithResourceOwner(ctx, IDPConfigChangedEventType, resourceOwner),
configID,
oldName,
changes,
)
if err != nil {

View File

@ -19,6 +19,7 @@ type MemberAddedEvent struct {
func NewMemberAddedEvent(
ctx context.Context,
aggregateID,
userID string,
roles ...string,
) *MemberAddedEvent {
@ -28,6 +29,7 @@ func NewMemberAddedEvent(
ctx,
MemberAddedEventType,
),
aggregateID,
userID,
roles...,
),
@ -80,6 +82,7 @@ type MemberRemovedEvent struct {
func NewMemberRemovedEvent(
ctx context.Context,
aggregateID,
userID string,
) *MemberRemovedEvent {
@ -89,6 +92,7 @@ func NewMemberRemovedEvent(
ctx,
MemberRemovedEventType,
),
aggregateID,
userID,
),
}

View File

@ -71,6 +71,7 @@ type OrgChangedEvent struct {
eventstore.BaseEvent `json:"-"`
Name string `json:"name,omitempty"`
oldName string `json:"-"`
}
func (e *OrgChangedEvent) Data() interface{} {
@ -78,16 +79,20 @@ func (e *OrgChangedEvent) Data() interface{} {
}
func (e *OrgChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
return []*eventstore.EventUniqueConstraint{
NewRemoveOrgDomainUniqueConstraint(e.oldName),
NewAddOrgNameUniqueConstraint(e.Name),
}
}
func NewOrgChangedEvent(ctx context.Context, name string) *OrgChangedEvent {
func NewOrgChangedEvent(ctx context.Context, oldName, newName string) *OrgChangedEvent {
return &OrgChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OrgChangedEventType,
),
Name: name,
Name: newName,
oldName: oldName,
}
}

View File

@ -9,7 +9,7 @@ import (
)
const (
uniqueMailText = "mail_text"
UniqueMailText = "mail_text"
mailTextPolicyPrefix = mailPolicyPrefix + "text."
MailTextPolicyAddedEventType = mailTextPolicyPrefix + "added"
MailTextPolicyChangedEventType = mailTextPolicyPrefix + "changed"
@ -18,14 +18,14 @@ const (
func NewAddMailTextUniqueConstraint(aggregateID, mailTextType, langugage string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueMailText,
UniqueMailText,
fmt.Sprintf("%v:%v:%v", aggregateID, mailTextType, langugage),
"Errors.Org.AlreadyExists")
}
func NewRemoveMailTextUniqueConstraint(aggregateID, mailTextType, langugage string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueMailText,
UniqueMailText,
fmt.Sprintf("%v:%v:%v", aggregateID, mailTextType, langugage))
}

View File

@ -11,7 +11,7 @@ import (
)
const (
uniqueAppNameType = "appname"
UniqueAppNameType = "appname"
applicationEventTypePrefix = projectEventTypePrefix + "application."
ApplicationAddedType = applicationEventTypePrefix + "added"
ApplicationChangedType = applicationEventTypePrefix + "changed"
@ -22,14 +22,14 @@ const (
func NewAddApplicationUniqueConstraint(name, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueAppNameType,
UniqueAppNameType,
fmt.Sprintf("%s:%s", name, projectID),
"Errors.Project.App.AlreadyExists")
}
func NewRemoveApplicationUniqueConstraint(name, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueAppNameType,
UniqueAppNameType,
fmt.Sprintf("%s:%s", name, projectID))
}

View File

@ -18,7 +18,7 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(RoleRemovedType, RoleRemovedEventMapper).
RegisterFilterEventMapper(GrantAddedType, GrantAddedEventMapper).
RegisterFilterEventMapper(GrantChangedType, GrantChangedEventMapper).
RegisterFilterEventMapper(GrantCascadeChangedType, GrantChangedEventMapper).
RegisterFilterEventMapper(GrantCascadeChangedType, GrantCascadeChangedEventMapper).
RegisterFilterEventMapper(GrantDeactivatedType, GrantDeactivateEventMapper).
RegisterFilterEventMapper(GrantReactivatedType, GrantReactivatedEventMapper).
RegisterFilterEventMapper(GrantRemovedType, GrantRemovedEventMapper).
@ -26,7 +26,7 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(GrantMemberChangedType, GrantMemberChangedEventMapper).
RegisterFilterEventMapper(GrantMemberRemovedType, GrantMemberRemovedEventMapper).
RegisterFilterEventMapper(ApplicationAddedType, ApplicationAddedEventMapper).
RegisterFilterEventMapper(ApplicationChangedType, ApplicationAddedEventMapper).
RegisterFilterEventMapper(ApplicationChangedType, ApplicationChangedEventMapper).
RegisterFilterEventMapper(ApplicationRemovedType, ApplicationRemovedEventMapper).
RegisterFilterEventMapper(ApplicationDeactivatedType, ApplicationDeactivatedEventMapper).
RegisterFilterEventMapper(ApplicationReactivatedType, ApplicationReactivatedEventMapper).

View File

@ -10,7 +10,7 @@ import (
)
var (
uniqueGrantType = "project_Grant"
UniqueGrantType = "project_grant"
grantEventTypePrefix = projectEventTypePrefix + "grant."
GrantAddedType = grantEventTypePrefix + "added"
GrantChangedType = grantEventTypePrefix + "changed"
@ -22,14 +22,14 @@ var (
func NewAddProjectGrantUniqueConstraint(grantedOrgID, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueRoleType,
UniqueRoleType,
fmt.Sprintf("%s:%s", grantedOrgID, projectID),
"Errors.Project.Grant.AlreadyExists")
}
func NewRemoveProjectGrantUniqueConstraint(grantedOrgID, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueRoleType,
UniqueRoleType,
fmt.Sprintf("%s:%s", grantedOrgID, projectID))
}

View File

@ -11,7 +11,7 @@ import (
)
var (
uniqueProjectGrantType = "project_grant"
UniqueProjectGrantMemberType = "project_grant_member"
GrantMemberAddedType = grantEventTypePrefix + member.AddedEventType
GrantMemberChangedType = grantEventTypePrefix + member.ChangedEventType
GrantMemberRemovedType = grantEventTypePrefix + member.RemovedEventType
@ -19,14 +19,14 @@ var (
func NewAddProjectGrantMemberUniqueConstraint(projectID, userID, grantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueProjectGrantType,
UniqueProjectGrantMemberType,
fmt.Sprintf("%s:%s:%s", projectID, userID, grantID),
"Errors.Project.Member.AlreadyExists")
}
func NewRemoveProjectGrantMemberUniqueConstraint(projectID, userID, grantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueProjectGrantType,
UniqueProjectGrantMemberType,
fmt.Sprintf("%s:%s:%s", projectID, userID, grantID),
)
}

View File

@ -19,6 +19,7 @@ type MemberAddedEvent struct {
func NewProjectMemberAddedEvent(
ctx context.Context,
aggregateID,
userID string,
roles ...string,
) *MemberAddedEvent {
@ -28,6 +29,7 @@ func NewProjectMemberAddedEvent(
ctx,
MemberAddedType,
),
aggregateID,
userID,
roles...,
),
@ -80,6 +82,7 @@ type MemberRemovedEvent struct {
func NewProjectMemberRemovedEvent(
ctx context.Context,
aggregateID,
userID string,
) *MemberRemovedEvent {
@ -89,6 +92,7 @@ func NewProjectMemberRemovedEvent(
ctx,
MemberRemovedType,
),
aggregateID,
userID,
),
}

View File

@ -10,7 +10,7 @@ import (
)
const (
uniqueProjectnameType = "project_names"
UniqueProjectnameType = "project_names"
projectEventTypePrefix = eventstore.EventType("project.")
ProjectAddedType = projectEventTypePrefix + "added"
ProjectChangedType = projectEventTypePrefix + "changed"
@ -21,14 +21,14 @@ const (
func NewAddProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueProjectnameType,
UniqueProjectnameType,
projectName+resourceOwner,
"Errors.Project.AlreadyExists")
}
func NewRemoveProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueProjectnameType,
UniqueProjectnameType,
projectName+resourceOwner)
}
@ -78,6 +78,7 @@ type ProjectChangeEvent struct {
Name *string `json:"name,omitempty"`
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
oldName string
}
func (e *ProjectChangeEvent) Data() interface{} {
@ -85,19 +86,27 @@ func (e *ProjectChangeEvent) Data() interface{} {
}
func (e *ProjectChangeEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
if e.oldName != "" {
return []*eventstore.EventUniqueConstraint{
NewRemoveProjectNameUniqueConstraint(e.oldName, e.ResourceOwner()),
NewAddProjectNameUniqueConstraint(*e.Name, e.ResourceOwner()),
}
}
return nil
}
func NewProjectChangeEvent(
ctx context.Context,
resourceOwner, oldName string,
changes []ProjectChanges) (*ProjectChangeEvent, error) {
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-mV9xc", "Errors.NoChangesFound")
}
changeEvent := &ProjectChangeEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
ProjectChangedType,
resourceOwner,
),
}
for _, change := range changes {

View File

@ -10,24 +10,24 @@ import (
)
var (
uniqueRoleType = "project_role"
UniqueRoleType = "project_role"
roleEventTypePrefix = projectEventTypePrefix + "role."
RoleAddedType = roleEventTypePrefix + "added"
RoleChangedType = roleEventTypePrefix + "changed"
RoleRemovedType = roleEventTypePrefix + "removed"
)
func NewAddProjectRoleUniqueConstraint(roleKey, projectID, resourceOwner string) *eventstore.EventUniqueConstraint {
func NewAddProjectRoleUniqueConstraint(roleKey, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s:%s", roleKey, projectID, resourceOwner),
UniqueRoleType,
fmt.Sprintf("%s:%s", roleKey, projectID),
"Errors.Project.Role.AlreadyExists")
}
func NewRemoveProjectRoleUniqueConstraint(roleKey, projectID, resourceOwner string) *eventstore.EventUniqueConstraint {
func NewRemoveProjectRoleUniqueConstraint(roleKey, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s:%s", roleKey, projectID, resourceOwner))
UniqueRoleType,
fmt.Sprintf("%s:%s", roleKey, projectID))
}
type RoleAddedEvent struct {
@ -44,15 +44,14 @@ func (e *RoleAddedEvent) Data() interface{} {
}
func (e *RoleAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddProjectRoleUniqueConstraint(e.Key, e.projectID, e.ResourceOwner())}
return []*eventstore.EventUniqueConstraint{NewAddProjectRoleUniqueConstraint(e.Key, e.projectID)}
}
func NewRoleAddedEvent(ctx context.Context, key, displayName, group, projectID, resourceOwner string) *RoleAddedEvent {
func NewRoleAddedEvent(ctx context.Context, key, displayName, group, projectID string) *RoleAddedEvent {
return &RoleAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
RoleAddedType,
resourceOwner,
),
Key: key,
DisplayName: displayName,
@ -144,7 +143,7 @@ type RoleRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
Key string `json:"key,omitempty"`
projectID string
projectID string `json:"-"`
}
func (e *RoleRemovedEvent) Data() interface{} {
@ -152,15 +151,14 @@ func (e *RoleRemovedEvent) Data() interface{} {
}
func (e *RoleRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveProjectRoleUniqueConstraint(e.Key, e.projectID, e.ResourceOwner())}
return []*eventstore.EventUniqueConstraint{NewRemoveProjectRoleUniqueConstraint(e.Key, e.projectID)}
}
func NewRoleRemovedEvent(ctx context.Context, key, projectID, resourceOwner string) *RoleRemovedEvent {
func NewRoleRemovedEvent(ctx context.Context, key, projectID string) *RoleRemovedEvent {
return &RoleRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
RoleRemovedType,
resourceOwner,
),
Key: key,
projectID: projectID,

View File

@ -43,7 +43,7 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
RegisterFilterEventMapper(UserRemovedType, UserRemovedEventMapper).
RegisterFilterEventMapper(UserTokenAddedType, UserTokenAddedEventMapper).
RegisterFilterEventMapper(UserDomainClaimedType, DomainClaimedEventMapper).
RegisterFilterEventMapper(UserDomainClaimedSentType, DomainClaimedEventMapper).
RegisterFilterEventMapper(UserDomainClaimedSentType, DomainClaimedSentEventMapper).
RegisterFilterEventMapper(UserUserNameChangedType, UsernameChangedEventMapper).
RegisterFilterEventMapper(HumanAddedType, HumanAddedEventMapper).
RegisterFilterEventMapper(HumanRegisteredType, HumanRegisteredEventMapper).

View File

@ -9,7 +9,7 @@ import (
)
const (
uniqueExternalIDPType = "external_idps"
UniqueExternalIDPType = "external_idps"
externalIDPEventPrefix = humanEventPrefix + "externalidp."
externalLoginEventPrefix = humanEventPrefix + "externallogin."
@ -22,14 +22,14 @@ const (
func NewAddExternalIDPUniqueConstraint(idpConfigID, externalUserID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueExternalIDPType,
UniqueExternalIDPType,
idpConfigID+externalUserID,
"Errors.User.ExternalIDP.AlreadyExists")
}
func NewRemoveExternalIDPUniqueConstraint(idpConfigID, externalUserID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueExternalIDPType,
UniqueExternalIDPType,
idpConfigID+externalUserID)
}
@ -37,7 +37,7 @@ type HumanExternalIDPAddedEvent struct {
eventstore.BaseEvent `json:"-"`
IDPConfigID string `json:"idpConfigId,omitempty"`
UserID string `json:"userId,omitempty"`
ExternalUserID string `json:"userId,omitempty"`
DisplayName string `json:"displayName,omitempty"`
}
@ -46,7 +46,7 @@ func (e *HumanExternalIDPAddedEvent) Data() interface{} {
}
func (e *HumanExternalIDPAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.UserID)}
return []*eventstore.EventUniqueConstraint{NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)}
}
func NewHumanExternalIDPAddedEvent(ctx context.Context, idpConfigID, displayName, externalUserID string) *HumanExternalIDPAddedEvent {
@ -57,7 +57,7 @@ func NewHumanExternalIDPAddedEvent(ctx context.Context, idpConfigID, displayName
),
IDPConfigID: idpConfigID,
DisplayName: displayName,
UserID: externalUserID,
ExternalUserID: externalUserID,
}
}
@ -78,7 +78,7 @@ type HumanExternalIDPRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
IDPConfigID string `json:"idpConfigId"`
UserID string `json:"userId,omitempty"`
ExternalUserID string `json:"userId,omitempty"`
}
func (e *HumanExternalIDPRemovedEvent) Data() interface{} {
@ -86,7 +86,7 @@ func (e *HumanExternalIDPRemovedEvent) Data() interface{} {
}
func (e *HumanExternalIDPRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.UserID)}
return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)}
}
func NewHumanExternalIDPRemovedEvent(ctx context.Context, idpConfigID, externalUserID string) *HumanExternalIDPRemovedEvent {
@ -96,7 +96,7 @@ func NewHumanExternalIDPRemovedEvent(ctx context.Context, idpConfigID, externalU
HumanExternalIDPRemovedType,
),
IDPConfigID: idpConfigID,
UserID: externalUserID,
ExternalUserID: externalUserID,
}
}
@ -117,7 +117,7 @@ type HumanExternalIDPCascadeRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
IDPConfigID string `json:"idpConfigId"`
UserID string `json:"userId,omitempty"`
ExternalUserID string `json:"userId,omitempty"`
}
func (e *HumanExternalIDPCascadeRemovedEvent) Data() interface{} {
@ -125,7 +125,7 @@ func (e *HumanExternalIDPCascadeRemovedEvent) Data() interface{} {
}
func (e *HumanExternalIDPCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.UserID)}
return []*eventstore.EventUniqueConstraint{NewRemoveExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID)}
}
func NewHumanExternalIDPCascadeRemovedEvent(ctx context.Context, idpConfigID, externalUserID string) *HumanExternalIDPCascadeRemovedEvent {
@ -135,7 +135,7 @@ func NewHumanExternalIDPCascadeRemovedEvent(ctx context.Context, idpConfigID, ex
HumanExternalIDPCascadeRemovedType,
),
IDPConfigID: idpConfigID,
UserID: externalUserID,
ExternalUserID: externalUserID,
}
}

View File

@ -10,7 +10,7 @@ import (
)
const (
uniqueUsername = "usernames"
UniqueUsername = "usernames"
userEventTypePrefix = eventstore.EventType("user.")
UserLockedType = userEventTypePrefix + "locked"
UserUnlockedType = userEventTypePrefix + "unlocked"
@ -29,7 +29,7 @@ func NewAddUsernameUniqueConstraint(userName, resourceOwner string, userLoginMus
uniqueUserName = userName + resourceOwner
}
return eventstore.NewAddEventUniqueConstraint(
uniqueUsername,
UniqueUsername,
uniqueUserName,
"Errors.User.AlreadyExists")
}
@ -40,7 +40,7 @@ func NewRemoveUsernameUniqueConstraint(userName, resourceOwner string, userLogin
uniqueUserName = userName + resourceOwner
}
return eventstore.NewRemoveEventUniqueConstraint(
uniqueUsername,
UniqueUsername,
uniqueUserName)
}
@ -246,6 +246,8 @@ type DomainClaimedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
oldUserName string `json:"-"`
userLoginMustBeDomain bool `json:"-"`
}
func (e *DomainClaimedEvent) Data() interface{} {
@ -253,12 +255,17 @@ func (e *DomainClaimedEvent) Data() interface{} {
}
func (e *DomainClaimedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
return []*eventstore.EventUniqueConstraint{
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.ResourceOwner(), e.userLoginMustBeDomain),
NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain),
}
}
func NewDomainClaimedEvent(
ctx context.Context,
userName string,
userName,
oldUserName string,
userLoginMustBeDomain bool,
) *DomainClaimedEvent {
return &DomainClaimedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
@ -266,6 +273,8 @@ func NewDomainClaimedEvent(
UserDomainClaimedType,
),
UserName: userName,
oldUserName: oldUserName,
userLoginMustBeDomain: userLoginMustBeDomain,
}
}
@ -314,8 +323,8 @@ type UsernameChangedEvent struct {
eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"`
OldUserName string
UserLoginMustBeDomain bool
oldUserName string `json:"-"`
userLoginMustBeDomain bool `json:"-"`
}
func (e *UsernameChangedEvent) Data() interface{} {
@ -324,8 +333,8 @@ func (e *UsernameChangedEvent) Data() interface{} {
func (e *UsernameChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{
NewRemoveUsernameUniqueConstraint(e.OldUserName, e.ResourceOwner(), e.UserLoginMustBeDomain),
NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.UserLoginMustBeDomain),
NewRemoveUsernameUniqueConstraint(e.oldUserName, e.ResourceOwner(), e.userLoginMustBeDomain),
NewAddUsernameUniqueConstraint(e.UserName, e.ResourceOwner(), e.userLoginMustBeDomain),
}
}
@ -341,8 +350,8 @@ func NewUsernameChangedEvent(
UserUserNameChangedType,
),
UserName: newUserName,
OldUserName: oldUserName,
UserLoginMustBeDomain: userLoginMustBeDomain,
oldUserName: oldUserName,
userLoginMustBeDomain: userLoginMustBeDomain,
}
}

View File

@ -10,7 +10,7 @@ import (
)
const (
uniqueUserGrant = "user_grant"
UniqueUserGrant = "user_grant"
userGrantEventTypePrefix = eventstore.EventType("user.grant.")
UserGrantAddedType = userGrantEventTypePrefix + "added"
UserGrantChangedType = userGrantEventTypePrefix + "changed"
@ -21,17 +21,17 @@ const (
UserGrantReactivatedType = userGrantEventTypePrefix + "reactivated"
)
func NewAddUserGrantUniqueConstraint(resourceOwner, userID, projectID string) *eventstore.EventUniqueConstraint {
func NewAddUserGrantUniqueConstraint(resourceOwner, userID, projectID, projectGrantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueUserGrant,
fmt.Sprintf("%s:%s:%s", resourceOwner, userID, projectID),
UniqueUserGrant,
fmt.Sprintf("%s:%s:%s:%v", resourceOwner, userID, projectID, projectGrantID),
"Errors.UserGrant.AlreadyExists")
}
func NewRemoveUserGrantUniqueConstraint(resourceOwner, userID, projectID string) *eventstore.EventUniqueConstraint {
func NewRemoveUserGrantUniqueConstraint(resourceOwner, userID, projectID, projectGrantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueUserGrant,
fmt.Sprintf("%s:%s:%s", resourceOwner, userID, projectID))
UniqueUserGrant,
fmt.Sprintf("%s:%s:%s:%S", resourceOwner, userID, projectID, projectGrantID))
}
type UserGrantAddedEvent struct {
@ -48,7 +48,7 @@ func (e *UserGrantAddedEvent) Data() interface{} {
}
func (e *UserGrantAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID)}
return []*eventstore.EventUniqueConstraint{NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID, e.ProjectGrantID)}
}
func NewUserGrantAddedEvent(
@ -162,8 +162,9 @@ func UserGrantCascadeChangedEventMapper(event *repository.Event) (eventstore.Eve
type UserGrantRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
userID string
projectID string
userID string `json:"-"`
projectID string `json:"-"`
projectGrantID string `json:"-"`
}
func (e *UserGrantRemovedEvent) Data() interface{} {
@ -171,10 +172,10 @@ func (e *UserGrantRemovedEvent) Data() interface{} {
}
func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)}
return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID, e.projectGrantID)}
}
func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantRemovedEvent {
func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projectID, projectGrantID string) *UserGrantRemovedEvent {
return &UserGrantRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
@ -183,6 +184,7 @@ func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projec
),
userID: userID,
projectID: projectID,
projectGrantID: projectGrantID,
}
}
@ -194,8 +196,9 @@ func UserGrantRemovedEventMapper(event *repository.Event) (eventstore.EventReade
type UserGrantCascadeRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
userID string
projectID string
userID string `json:"-"`
projectID string `json:"-"`
projectGrantID string `json:"-"`
}
func (e *UserGrantCascadeRemovedEvent) Data() interface{} {
@ -203,10 +206,10 @@ func (e *UserGrantCascadeRemovedEvent) Data() interface{} {
}
func (e *UserGrantCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)}
return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID, e.projectGrantID)}
}
func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantCascadeRemovedEvent {
func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID, projectGrantID string) *UserGrantCascadeRemovedEvent {
return &UserGrantCascadeRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
@ -215,6 +218,7 @@ func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID,
),
userID: userID,
projectID: projectID,
projectGrantID: projectGrantID,
}
}