mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:27:32 +00:00
fix(projections): user idp link projection (#2583)
* fix(projections): add app * fix(migration): add index for project_id * test: app projection * fix(projections): add idp_user_link * test: idp user link * fix: migration versions * refactor: rename externalIDP to UserIDPLink * fix: interface methods
This commit is contained in:
@@ -145,7 +145,7 @@ func (c *Commands) ReactivateDefaultIDPConfig(ctx context.Context, idpID string)
|
||||
return writeModelToObjectDetails(&existingIDP.IDPConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idpProviders []*domain.IDPProvider, externalIDPs ...*domain.ExternalIDP) (*domain.ObjectDetails, error) {
|
||||
func (c *Commands) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idpProviders []*domain.IDPProvider, externalIDPs ...*domain.UserIDPLink) (*domain.ObjectDetails, error) {
|
||||
existingIDP, err := c.iamIDPConfigWriteModelByID(ctx, idpID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@@ -123,7 +123,7 @@ func (c *Commands) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpPr
|
||||
return writeModelToIDPProvider(&idpModel.IdentityProviderWriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.ExternalIDP) (*domain.ObjectDetails, error) {
|
||||
func (c *Commands) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.UserIDPLink) (*domain.ObjectDetails, error) {
|
||||
if !idpProvider.IsValid() {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-66m9s", "Errors.IAM.LoginPolicy.IDP.Invalid")
|
||||
}
|
||||
@@ -158,7 +158,7 @@ func (c *Commands) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context,
|
||||
return writeModelToObjectDetails(&idpModel.IdentityProviderWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeIDPProviderFromDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, idpProvider *domain.IDPProvider, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.EventPusher {
|
||||
func (c *Commands) removeIDPProviderFromDefaultLoginPolicy(ctx context.Context, iamAgg *eventstore.Aggregate, idpProvider *domain.IDPProvider, cascade bool, cascadeExternalIDPs ...*domain.UserIDPLink) []eventstore.EventPusher {
|
||||
var events []eventstore.EventPusher
|
||||
if cascade {
|
||||
events = append(events, iam_repo.NewIdentityProviderCascadeRemovedEvent(ctx, iamAgg, idpProvider.IDPConfigID))
|
||||
@@ -167,7 +167,7 @@ func (c *Commands) removeIDPProviderFromDefaultLoginPolicy(ctx context.Context,
|
||||
}
|
||||
|
||||
for _, idp := range cascadeExternalIDPs {
|
||||
userEvent, _, err := c.removeHumanExternalIDP(ctx, idp, true)
|
||||
userEvent, _, err := c.removeUserIDPLink(ctx, idp, true)
|
||||
if err != nil {
|
||||
logging.LogWithFields("COMMAND-4nfsf", "userid", idp.AggregateID, "idp-id", idp.IDPConfigID).WithError(err).Warn("could not cascade remove externalidp in remove provider from policy")
|
||||
continue
|
||||
|
@@ -497,7 +497,7 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
provider *domain.IDPProvider
|
||||
cascadeExternalIDPs []*domain.ExternalIDP
|
||||
cascadeExternalIDPs []*domain.UserIDPLink
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
@@ -708,7 +708,7 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
|
||||
provider: &domain.IDPProvider{
|
||||
IDPConfigID: "config1",
|
||||
},
|
||||
cascadeExternalIDPs: []*domain.ExternalIDP{
|
||||
cascadeExternalIDPs: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -751,7 +751,7 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1", "", "externaluser1"),
|
||||
),
|
||||
@@ -764,11 +764,11 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
|
||||
"config1"),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPCascadeRemovedEvent(context.Background(),
|
||||
user.NewUserIDPLinkCascadeRemovedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1", "externaluser1")),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveExternalIDPUniqueConstraint("config1", "externaluser1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUserIDPLinkUniqueConstraint("config1", "externaluser1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -777,7 +777,7 @@ func TestCommandSide_RemoveIDPProviderDefaultLoginPolicy(t *testing.T) {
|
||||
provider: &domain.IDPProvider{
|
||||
IDPConfigID: "config1",
|
||||
},
|
||||
cascadeExternalIDPs: []*domain.ExternalIDP{
|
||||
cascadeExternalIDPs: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
|
@@ -153,7 +153,7 @@ func (c *Commands) ReactivateIDPConfig(ctx context.Context, idpID, orgID string)
|
||||
return writeModelToObjectDetails(&existingIDP.IDPConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveIDPConfig(ctx context.Context, idpID, orgID string, cascadeRemoveProvider bool, cascadeExternalIDPs ...*domain.ExternalIDP) (*domain.ObjectDetails, error) {
|
||||
func (c *Commands) RemoveIDPConfig(ctx context.Context, idpID, orgID string, cascadeRemoveProvider bool, cascadeExternalIDPs ...*domain.UserIDPLink) (*domain.ObjectDetails, error) {
|
||||
existingIDP, err := c.orgIDPConfigWriteModelByID(ctx, idpID, orgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -173,7 +173,7 @@ func (c *Commands) RemoveIDPConfig(ctx context.Context, idpID, orgID string, cas
|
||||
return writeModelToObjectDetails(&existingIDP.IDPConfigWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeIDPConfig(ctx context.Context, existingIDP *OrgIDPConfigWriteModel, cascadeRemoveProvider bool, cascadeExternalIDPs ...*domain.ExternalIDP) ([]eventstore.EventPusher, error) {
|
||||
func (c *Commands) removeIDPConfig(ctx context.Context, existingIDP *OrgIDPConfigWriteModel, cascadeRemoveProvider bool, cascadeExternalIDPs ...*domain.UserIDPLink) ([]eventstore.EventPusher, error) {
|
||||
if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified {
|
||||
return nil, caos_errs.ThrowNotFound(nil, "Org-Yx9vd", "Errors.Org.IDPConfig.NotExisting")
|
||||
}
|
||||
|
@@ -426,7 +426,7 @@ func TestCommands_RemoveIDPConfig(t *testing.T) {
|
||||
idpID string
|
||||
orgID string
|
||||
cascadeRemoveProvider bool
|
||||
cascadeExternalIDPs []*domain.ExternalIDP
|
||||
cascadeExternalIDPs []*domain.UserIDPLink
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
@@ -531,7 +531,7 @@ func TestCommands_RemoveIDPConfig(t *testing.T) {
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&org.NewAggregate("user1", "org1").Aggregate,
|
||||
"idp1",
|
||||
"name",
|
||||
@@ -550,14 +550,14 @@ func TestCommands_RemoveIDPConfig(t *testing.T) {
|
||||
&org.NewAggregate("org1", "org1").Aggregate,
|
||||
"idp1",
|
||||
),
|
||||
user.NewHumanExternalIDPCascadeRemovedEvent(context.Background(),
|
||||
user.NewUserIDPLinkCascadeRemovedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"idp1",
|
||||
"id1",
|
||||
),
|
||||
),
|
||||
uniqueConstraintsFromEventConstraint(idpconfig.NewRemoveIDPConfigNameUniqueConstraint("name1", "org1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveExternalIDPUniqueConstraint("idp1", "id1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUserIDPLinkUniqueConstraint("idp1", "id1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -566,7 +566,7 @@ func TestCommands_RemoveIDPConfig(t *testing.T) {
|
||||
"idp1",
|
||||
"org1",
|
||||
true,
|
||||
[]*domain.ExternalIDP{
|
||||
[]*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
|
@@ -201,7 +201,7 @@ func (c *Commands) AddIDPProviderToLoginPolicy(ctx context.Context, resourceOwne
|
||||
return writeModelToIDPProvider(&idpModel.IdentityProviderWriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveIDPProviderFromLoginPolicy(ctx context.Context, resourceOwner string, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.ExternalIDP) (*domain.ObjectDetails, error) {
|
||||
func (c *Commands) RemoveIDPProviderFromLoginPolicy(ctx context.Context, resourceOwner string, idpProvider *domain.IDPProvider, cascadeExternalIDPs ...*domain.UserIDPLink) (*domain.ObjectDetails, error) {
|
||||
if resourceOwner == "" {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-M0fs9", "Errors.ResourceOwnerMissing")
|
||||
}
|
||||
@@ -239,7 +239,7 @@ func (c *Commands) RemoveIDPProviderFromLoginPolicy(ctx context.Context, resourc
|
||||
return writeModelToObjectDetails(&idpModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeIDPProviderFromLoginPolicy(ctx context.Context, orgAgg *eventstore.Aggregate, idpConfigID string, cascade bool, cascadeExternalIDPs ...*domain.ExternalIDP) []eventstore.EventPusher {
|
||||
func (c *Commands) removeIDPProviderFromLoginPolicy(ctx context.Context, orgAgg *eventstore.Aggregate, idpConfigID string, cascade bool, cascadeExternalIDPs ...*domain.UserIDPLink) []eventstore.EventPusher {
|
||||
var events []eventstore.EventPusher
|
||||
if cascade {
|
||||
events = append(events, org.NewIdentityProviderCascadeRemovedEvent(ctx, orgAgg, idpConfigID))
|
||||
@@ -248,7 +248,7 @@ func (c *Commands) removeIDPProviderFromLoginPolicy(ctx context.Context, orgAgg
|
||||
}
|
||||
|
||||
for _, idp := range cascadeExternalIDPs {
|
||||
event, _, err := c.removeHumanExternalIDP(ctx, idp, true)
|
||||
event, _, err := c.removeUserIDPLink(ctx, idp, true)
|
||||
if err != nil {
|
||||
logging.LogWithFields("COMMAND-n8RRf", "userid", idp.AggregateID, "idpconfigid", idp.IDPConfigID).WithError(err).Warn("could not cascade remove external idp")
|
||||
continue
|
||||
|
@@ -824,7 +824,7 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
|
||||
ctx context.Context
|
||||
resourceOwner string
|
||||
provider *domain.IDPProvider
|
||||
cascadeExternalIDPs []*domain.ExternalIDP
|
||||
cascadeExternalIDPs []*domain.UserIDPLink
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
@@ -1069,7 +1069,7 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
|
||||
Name: "name",
|
||||
Type: domain.IdentityProviderTypeOrg,
|
||||
},
|
||||
cascadeExternalIDPs: []*domain.ExternalIDP{
|
||||
cascadeExternalIDPs: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -1113,7 +1113,7 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1", "", "externaluser1"),
|
||||
),
|
||||
@@ -1126,11 +1126,11 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
|
||||
"config1"),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPCascadeRemovedEvent(context.Background(),
|
||||
user.NewUserIDPLinkCascadeRemovedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1", "externaluser1")),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveExternalIDPUniqueConstraint("config1", "externaluser1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUserIDPLinkUniqueConstraint("config1", "externaluser1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -1140,7 +1140,7 @@ func TestCommandSide_RemoveIDPProviderLoginPolicy(t *testing.T) {
|
||||
provider: &domain.IDPProvider{
|
||||
IDPConfigID: "config1",
|
||||
},
|
||||
cascadeExternalIDPs: []*domain.ExternalIDP{
|
||||
cascadeExternalIDPs: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
|
@@ -131,7 +131,7 @@ func (rm *UniqueConstraintReadModel) Reduce() error {
|
||||
rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain))
|
||||
case *user.UserRemovedEvent:
|
||||
rm.removeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.UniqueUsername)
|
||||
rm.listRemoveUniqueConstraint(e.Aggregate().ID, user.UniqueExternalIDPType)
|
||||
rm.listRemoveUniqueConstraint(e.Aggregate().ID, user.UniqueUserIDPLinkType)
|
||||
case *user.UsernameChangedEvent:
|
||||
policy, err := rm.commandProvider.getOrgIAMPolicy(rm.ctx, e.Aggregate().ResourceOwner)
|
||||
if err != nil {
|
||||
@@ -146,12 +146,12 @@ func (rm *UniqueConstraintReadModel) Reduce() error {
|
||||
continue
|
||||
}
|
||||
rm.changeUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, user.NewAddUsernameUniqueConstraint(e.UserName, e.Aggregate().ResourceOwner, policy.UserLoginMustBeDomain))
|
||||
case *user.HumanExternalIDPAddedEvent:
|
||||
rm.addUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.NewAddExternalIDPUniqueConstraint(e.IDPConfigID, e.ExternalUserID))
|
||||
case *user.HumanExternalIDPRemovedEvent:
|
||||
rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType)
|
||||
case *user.HumanExternalIDPCascadeRemovedEvent:
|
||||
rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueExternalIDPType)
|
||||
case *user.UserIDPLinkAddedEvent:
|
||||
rm.addUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.NewAddUserIDPLinkUniqueConstraint(e.IDPConfigID, e.ExternalUserID))
|
||||
case *user.UserIDPLinkRemovedEvent:
|
||||
rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueUserIDPLinkType)
|
||||
case *user.UserIDPLinkCascadeRemovedEvent:
|
||||
rm.removeUniqueConstraint(e.Aggregate().ID, e.IDPConfigID+e.ExternalUserID, user.UniqueUserIDPLinkType)
|
||||
case *usergrant.UserGrantAddedEvent:
|
||||
rm.addUniqueConstraint(e.Aggregate().ID, e.Aggregate().ID, usergrant.NewAddUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.UserID, e.ProjectID, e.ProjectGrantID))
|
||||
case *usergrant.UserGrantRemovedEvent:
|
||||
@@ -224,9 +224,9 @@ func (rm *UniqueConstraintReadModel) Query() *eventstore.SearchQueryBuilder {
|
||||
user.UserUserNameChangedType,
|
||||
user.UserDomainClaimedType,
|
||||
user.UserRemovedType,
|
||||
user.HumanExternalIDPAddedType,
|
||||
user.HumanExternalIDPRemovedType,
|
||||
user.HumanExternalIDPCascadeRemovedType,
|
||||
user.UserIDPLinkAddedType,
|
||||
user.UserIDPLinkRemovedType,
|
||||
user.UserIDPLinkCascadeRemovedType,
|
||||
usergrant.UserGrantAddedType,
|
||||
usergrant.UserGrantRemovedType,
|
||||
usergrant.UserGrantCascadeRemovedType,
|
||||
|
@@ -188,7 +188,7 @@ func (c *Commands) RemoveUser(ctx context.Context, userID, resourceOwner string,
|
||||
}
|
||||
var events []eventstore.EventPusher
|
||||
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
|
||||
events = append(events, user.NewUserRemovedEvent(ctx, userAgg, existingUser.UserName, existingUser.ExternalIDPs, orgIAMPolicy.UserLoginMustBeDomain))
|
||||
events = append(events, user.NewUserRemovedEvent(ctx, userAgg, existingUser.UserName, existingUser.IDPLinks, orgIAMPolicy.UserLoginMustBeDomain))
|
||||
|
||||
for _, grantID := range cascadingGrantIDs {
|
||||
removeEvent, _, err := c.removeUserGrant(ctx, grantID, "", true)
|
||||
|
@@ -117,7 +117,7 @@ func (c *Commands) importHuman(ctx context.Context, orgID string, human *domain.
|
||||
return events, humanWriteModel, passwordlessCodeWriteModel, code, nil
|
||||
}
|
||||
|
||||
func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, orgMemberRoles []string) (*domain.Human, error) {
|
||||
func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domain.Human, link *domain.UserIDPLink, orgMemberRoles []string) (*domain.Human, error) {
|
||||
if orgID == "" {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-GEdf2", "Errors.ResourceOwnerMissing")
|
||||
}
|
||||
@@ -129,7 +129,7 @@ func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domai
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
|
||||
}
|
||||
userEvents, registeredHuman, err := c.registerHuman(ctx, orgID, human, externalIDP, orgIAMPolicy, pwPolicy)
|
||||
userEvents, registeredHuman, err := c.registerHuman(ctx, orgID, human, link, orgIAMPolicy, pwPolicy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,20 +163,20 @@ func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domai
|
||||
return writeModelToHuman(registeredHuman), nil
|
||||
}
|
||||
|
||||
func (c *Commands) registerHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
|
||||
func (c *Commands) registerHuman(ctx context.Context, orgID string, human *domain.Human, link *domain.UserIDPLink, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
|
||||
if human != nil && human.Username == "" {
|
||||
human.Username = human.EmailAddress
|
||||
}
|
||||
if orgID == "" || !human.IsValid() || externalIDP == nil && (human.Password == nil || human.SecretString == "") {
|
||||
if orgID == "" || !human.IsValid() || link == nil && (human.Password == nil || human.SecretString == "") {
|
||||
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-9dk45", "Errors.User.Invalid")
|
||||
}
|
||||
if human.Password != nil && human.SecretString != "" {
|
||||
human.ChangeRequired = false
|
||||
}
|
||||
return c.createHuman(ctx, orgID, human, externalIDP, true, false, orgIAMPolicy, pwPolicy)
|
||||
return c.createHuman(ctx, orgID, human, link, true, false, orgIAMPolicy, pwPolicy)
|
||||
}
|
||||
|
||||
func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, selfregister, passwordless bool, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
|
||||
func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.Human, link *domain.UserIDPLink, selfregister, passwordless bool, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
|
||||
if err := human.CheckOrgIAMPolicy(orgIAMPolicy); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -216,15 +216,15 @@ func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.
|
||||
events = append(events, createAddHumanEvent(ctx, userAgg, human, orgIAMPolicy.UserLoginMustBeDomain))
|
||||
}
|
||||
|
||||
if externalIDP != nil {
|
||||
event, err := c.addHumanExternalIDP(ctx, userAgg, externalIDP)
|
||||
if link != nil {
|
||||
event, err := c.addUserIDPLink(ctx, userAgg, link)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
events = append(events, event)
|
||||
}
|
||||
|
||||
if human.IsInitialState(passwordless, externalIDP != nil) {
|
||||
if human.IsInitialState(passwordless, link != nil) {
|
||||
initCode, err := domain.NewInitUserCode(c.initializeUserCode)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@@ -1,116 +0,0 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
func (c *Commands) BulkAddedHumanExternalIDP(ctx context.Context, userID, resourceOwner string, externalIDPs []*domain.ExternalIDP) (err error) {
|
||||
if userID == "" {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-03j8f", "Errors.IDMissing")
|
||||
}
|
||||
if len(externalIDPs) == 0 {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-Ek9s", "Errors.User.ExternalIDP.MinimumExternalIDPNeeded")
|
||||
}
|
||||
|
||||
events := make([]eventstore.EventPusher, len(externalIDPs))
|
||||
for i, externalIDP := range externalIDPs {
|
||||
externalIDPWriteModel := NewHumanExternalIDPWriteModel(userID, externalIDP.IDPConfigID, externalIDP.ExternalUserID, resourceOwner)
|
||||
userAgg := UserAggregateFromWriteModel(&externalIDPWriteModel.WriteModel)
|
||||
|
||||
events[i], err = c.addHumanExternalIDP(ctx, userAgg, externalIDP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = c.eventstore.PushEvents(ctx, events...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Commands) addHumanExternalIDP(ctx context.Context, humanAgg *eventstore.Aggregate, externalIDP *domain.ExternalIDP) (eventstore.EventPusher, error) {
|
||||
if externalIDP.AggregateID != "" && humanAgg.ID != externalIDP.AggregateID {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-33M0g", "Errors.IDMissing")
|
||||
}
|
||||
if !externalIDP.IsValid() {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid")
|
||||
}
|
||||
_, err := c.getOrgIDPConfigByID(ctx, externalIDP.IDPConfigID, humanAgg.ResourceOwner)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
_, err = c.getIAMIDPConfigByID(ctx, externalIDP.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-39nfs", "Errors.IDPConfig.NotExisting")
|
||||
}
|
||||
return user.NewHumanExternalIDPAddedEvent(ctx, humanAgg, externalIDP.IDPConfigID, externalIDP.DisplayName, externalIDP.ExternalUserID), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP) (*domain.ObjectDetails, error) {
|
||||
event, externalIDPWriteModel, err := c.removeHumanExternalIDP(ctx, externalIDP, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.PushEvents(ctx, event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(externalIDPWriteModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&externalIDPWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP, cascade bool) (eventstore.EventPusher, *HumanExternalIDPWriteModel, error) {
|
||||
if !externalIDP.IsValid() || externalIDP.AggregateID == "" {
|
||||
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-3M9ds", "Errors.IDMissing")
|
||||
}
|
||||
|
||||
existingExternalIDP, err := c.externalIDPWriteModelByID(ctx, externalIDP.AggregateID, externalIDP.IDPConfigID, externalIDP.ExternalUserID, externalIDP.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if existingExternalIDP.State == domain.ExternalIDPStateUnspecified || existingExternalIDP.State == domain.ExternalIDPStateRemoved {
|
||||
return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-1M9xR", "Errors.User.ExternalIDP.NotFound")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingExternalIDP.WriteModel)
|
||||
if cascade {
|
||||
return user.NewHumanExternalIDPCascadeRemovedEvent(ctx, userAgg, externalIDP.IDPConfigID, externalIDP.ExternalUserID), existingExternalIDP, nil
|
||||
}
|
||||
return user.NewHumanExternalIDPRemovedEvent(ctx, userAgg, externalIDP.IDPConfigID, externalIDP.ExternalUserID), existingExternalIDP, nil
|
||||
}
|
||||
|
||||
func (c *Commands) HumanExternalLoginChecked(ctx context.Context, orgID, userID string, authRequest *domain.AuthRequest) (err error) {
|
||||
if userID == "" {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-5n8sM", "Errors.IDMissing")
|
||||
}
|
||||
|
||||
existingHuman, err := c.getHumanWriteModelByID(ctx, userID, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existingHuman.UserState == domain.UserStateUnspecified || existingHuman.UserState == domain.UserStateDeleted {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dn88J", "Errors.User.NotFound")
|
||||
}
|
||||
|
||||
userAgg := UserAggregateFromWriteModel(&existingHuman.WriteModel)
|
||||
_, err = c.eventstore.PushEvents(ctx, user.NewHumanExternalIDPCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Commands) externalIDPWriteModelByID(ctx context.Context, userID, idpConfigID, externalUserID, resourceOwner string) (writeModel *HumanExternalIDPWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel = NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resourceOwner)
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@@ -1425,7 +1425,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
|
||||
ctx context.Context
|
||||
orgID string
|
||||
human *domain.Human
|
||||
externalIDP *domain.ExternalIDP
|
||||
link *domain.UserIDPLink
|
||||
orgMemberRoles []string
|
||||
}
|
||||
type res struct {
|
||||
@@ -2134,7 +2134,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
|
||||
phoneVerificationCode: tt.fields.secretGenerator,
|
||||
userPasswordAlg: tt.fields.userPasswordAlg,
|
||||
}
|
||||
got, err := r.RegisterHuman(tt.args.ctx, tt.args.orgID, tt.args.human, tt.args.externalIDP, tt.args.orgMemberRoles)
|
||||
got, err := r.RegisterHuman(tt.args.ctx, tt.args.orgID, tt.args.human, tt.args.link, tt.args.orgMemberRoles)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
117
internal/command/user_idp_link.go
Normal file
117
internal/command/user_idp_link.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
)
|
||||
|
||||
func (c *Commands) BulkAddedUserIDPLinks(ctx context.Context, userID, resourceOwner string, links []*domain.UserIDPLink) (err error) {
|
||||
if userID == "" {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-03j8f", "Errors.IDMissing")
|
||||
}
|
||||
if len(links) == 0 {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-Ek9s", "Errors.User.ExternalIDP.MinimumExternalIDPNeeded")
|
||||
}
|
||||
|
||||
events := make([]eventstore.EventPusher, len(links))
|
||||
for i, link := range links {
|
||||
linkWriteModel := NewUserIDPLinkWriteModel(userID, link.IDPConfigID, link.ExternalUserID, resourceOwner)
|
||||
userAgg := UserAggregateFromWriteModel(&linkWriteModel.WriteModel)
|
||||
|
||||
events[i], err = c.addUserIDPLink(ctx, userAgg, link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = c.eventstore.PushEvents(ctx, events...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Commands) addUserIDPLink(ctx context.Context, human *eventstore.Aggregate, link *domain.UserIDPLink) (eventstore.EventPusher, error) {
|
||||
if link.AggregateID != "" && human.ID != link.AggregateID {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-33M0g", "Errors.IDMissing")
|
||||
}
|
||||
if !link.IsValid() {
|
||||
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid")
|
||||
}
|
||||
_, err := c.getOrgIDPConfigByID(ctx, link.IDPConfigID, human.ResourceOwner)
|
||||
if caos_errs.IsNotFound(err) {
|
||||
_, err = c.getIAMIDPConfigByID(ctx, link.IDPConfigID)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-39nfs", "Errors.IDPConfig.NotExisting")
|
||||
}
|
||||
return user.NewUserIDPLinkAddedEvent(ctx, human, link.IDPConfigID, link.DisplayName, link.ExternalUserID), nil
|
||||
}
|
||||
|
||||
func (c *Commands) RemoveUserIDPLink(ctx context.Context, link *domain.UserIDPLink) (*domain.ObjectDetails, error) {
|
||||
event, linkWriteModel, err := c.removeUserIDPLink(ctx, link, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pushedEvents, err := c.eventstore.PushEvents(ctx, event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = AppendAndReduce(linkWriteModel, pushedEvents...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&linkWriteModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) removeUserIDPLink(ctx context.Context, link *domain.UserIDPLink, cascade bool) (eventstore.EventPusher, *UserIDPLinkWriteModel, error) {
|
||||
if !link.IsValid() || link.AggregateID == "" {
|
||||
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-3M9ds", "Errors.IDMissing")
|
||||
}
|
||||
|
||||
existingLink, err := c.userIDPLinkWriteModelByID(ctx, link.AggregateID, link.IDPConfigID, link.ExternalUserID, link.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if existingLink.State == domain.UserIDPLinkStateUnspecified || existingLink.State == domain.UserIDPLinkStateRemoved {
|
||||
return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-1M9xR", "Errors.User.ExternalIDP.NotFound")
|
||||
}
|
||||
userAgg := UserAggregateFromWriteModel(&existingLink.WriteModel)
|
||||
if cascade {
|
||||
return user.NewUserIDPLinkCascadeRemovedEvent(ctx, userAgg, link.IDPConfigID, link.ExternalUserID), existingLink, nil
|
||||
}
|
||||
return user.NewUserIDPLinkRemovedEvent(ctx, userAgg, link.IDPConfigID, link.ExternalUserID), existingLink, nil
|
||||
}
|
||||
|
||||
func (c *Commands) UserIDPLoginChecked(ctx context.Context, orgID, userID string, authRequest *domain.AuthRequest) (err error) {
|
||||
if userID == "" {
|
||||
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-5n8sM", "Errors.IDMissing")
|
||||
}
|
||||
|
||||
existingHuman, err := c.getHumanWriteModelByID(ctx, userID, orgID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existingHuman.UserState == domain.UserStateUnspecified || existingHuman.UserState == domain.UserStateDeleted {
|
||||
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dn88J", "Errors.User.NotFound")
|
||||
}
|
||||
|
||||
userAgg := UserAggregateFromWriteModel(&existingHuman.WriteModel)
|
||||
_, err = c.eventstore.PushEvents(ctx, user.NewUserIDPCheckSucceededEvent(ctx, userAgg, authRequestDomainToAuthRequestInfo(authRequest)))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Commands) userIDPLinkWriteModelByID(ctx context.Context, userID, idpConfigID, externalUserID, resourceOwner string) (writeModel *UserIDPLinkWriteModel, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
writeModel = NewUserIDPLinkWriteModel(userID, idpConfigID, externalUserID, resourceOwner)
|
||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
@@ -6,18 +6,18 @@ import (
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
)
|
||||
|
||||
type HumanExternalIDPWriteModel struct {
|
||||
type UserIDPLinkWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
IDPConfigID string
|
||||
ExternalUserID string
|
||||
DisplayName string
|
||||
|
||||
State domain.ExternalIDPState
|
||||
State domain.UserIDPLinkState
|
||||
}
|
||||
|
||||
func NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resourceOwner string) *HumanExternalIDPWriteModel {
|
||||
return &HumanExternalIDPWriteModel{
|
||||
func NewUserIDPLinkWriteModel(userID, idpConfigID, externalUserID, resourceOwner string) *UserIDPLinkWriteModel {
|
||||
return &UserIDPLinkWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: userID,
|
||||
ResourceOwner: resourceOwner,
|
||||
@@ -27,20 +27,20 @@ func NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resource
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *HumanExternalIDPWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
func (wm *UserIDPLinkWriteModel) AppendEvents(events ...eventstore.EventReader) {
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanExternalIDPAddedEvent:
|
||||
case *user.UserIDPLinkAddedEvent:
|
||||
if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID {
|
||||
continue
|
||||
}
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
case *user.HumanExternalIDPRemovedEvent:
|
||||
case *user.UserIDPLinkRemovedEvent:
|
||||
if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID {
|
||||
continue
|
||||
}
|
||||
wm.WriteModel.AppendEvents(e)
|
||||
case *user.HumanExternalIDPCascadeRemovedEvent:
|
||||
case *user.UserIDPLinkCascadeRemovedEvent:
|
||||
if e.IDPConfigID != wm.IDPConfigID && e.ExternalUserID != wm.ExternalUserID {
|
||||
continue
|
||||
}
|
||||
@@ -51,34 +51,34 @@ func (wm *HumanExternalIDPWriteModel) AppendEvents(events ...eventstore.EventRea
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *HumanExternalIDPWriteModel) Reduce() error {
|
||||
func (wm *UserIDPLinkWriteModel) Reduce() error {
|
||||
for _, event := range wm.Events {
|
||||
switch e := event.(type) {
|
||||
case *user.HumanExternalIDPAddedEvent:
|
||||
case *user.UserIDPLinkAddedEvent:
|
||||
wm.IDPConfigID = e.IDPConfigID
|
||||
wm.DisplayName = e.DisplayName
|
||||
wm.ExternalUserID = e.ExternalUserID
|
||||
wm.State = domain.ExternalIDPStateActive
|
||||
case *user.HumanExternalIDPRemovedEvent:
|
||||
wm.State = domain.ExternalIDPStateRemoved
|
||||
case *user.HumanExternalIDPCascadeRemovedEvent:
|
||||
wm.State = domain.ExternalIDPStateRemoved
|
||||
wm.State = domain.UserIDPLinkStateActive
|
||||
case *user.UserIDPLinkRemovedEvent:
|
||||
wm.State = domain.UserIDPLinkStateRemoved
|
||||
case *user.UserIDPLinkCascadeRemovedEvent:
|
||||
wm.State = domain.UserIDPLinkStateRemoved
|
||||
case *user.UserRemovedEvent:
|
||||
wm.State = domain.ExternalIDPStateRemoved
|
||||
wm.State = domain.UserIDPLinkStateRemoved
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *HumanExternalIDPWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
func (wm *UserIDPLinkWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
ResourceOwner(wm.ResourceOwner).
|
||||
AddQuery().
|
||||
AggregateTypes(user.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
EventTypes(user.HumanExternalIDPAddedType,
|
||||
user.HumanExternalIDPRemovedType,
|
||||
user.HumanExternalIDPCascadeRemovedType,
|
||||
EventTypes(user.UserIDPLinkAddedType,
|
||||
user.UserIDPLinkRemovedType,
|
||||
user.UserIDPLinkCascadeRemovedType,
|
||||
user.UserRemovedType).
|
||||
Builder()
|
||||
}
|
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/repository/user"
|
||||
)
|
||||
|
||||
func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
func TestCommandSide_BulkAddUserIDPLinks(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
@@ -25,7 +25,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx context.Context
|
||||
userID string
|
||||
resourceOwner string
|
||||
externalIDPs []*domain.ExternalIDP
|
||||
links []*domain.UserIDPLink
|
||||
}
|
||||
type res struct {
|
||||
err func(error) bool
|
||||
@@ -46,7 +46,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
userID: "",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
IDPConfigID: "config1",
|
||||
ExternalUserID: "externaluser1",
|
||||
@@ -85,7 +85,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
userID: "user1",
|
||||
resourceOwner: "org1",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user2",
|
||||
@@ -110,7 +110,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
userID: "user1",
|
||||
resourceOwner: "org1",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -137,7 +137,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
userID: "user1",
|
||||
resourceOwner: "org1",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -171,7 +171,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"name",
|
||||
@@ -179,7 +179,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewAddExternalIDPUniqueConstraint("config1", "externaluser1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewAddUserIDPLinkUniqueConstraint("config1", "externaluser1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -187,7 +187,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
userID: "user1",
|
||||
resourceOwner: "org1",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -221,7 +221,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"name",
|
||||
@@ -229,7 +229,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewAddExternalIDPUniqueConstraint("config1", "externaluser1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewAddUserIDPLinkUniqueConstraint("config1", "externaluser1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
@@ -237,7 +237,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
ctx: context.Background(),
|
||||
userID: "user1",
|
||||
resourceOwner: "org1",
|
||||
externalIDPs: []*domain.ExternalIDP{
|
||||
links: []*domain.UserIDPLink{
|
||||
{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
@@ -256,7 +256,7 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
err := r.BulkAddedHumanExternalIDP(tt.args.ctx, tt.args.userID, tt.args.resourceOwner, tt.args.externalIDPs)
|
||||
err := r.BulkAddedUserIDPLinks(tt.args.ctx, tt.args.userID, tt.args.resourceOwner, tt.args.links)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -267,13 +267,13 @@ func TestCommandSide_BulkAddExternalIDPs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
func TestCommandSide_RemoveUserIDPLink(t *testing.T) {
|
||||
type fields struct {
|
||||
eventstore *eventstore.Eventstore
|
||||
}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
externalIDP *domain.ExternalIDP
|
||||
ctx context.Context
|
||||
link *domain.UserIDPLink
|
||||
}
|
||||
type res struct {
|
||||
want *domain.ObjectDetails
|
||||
@@ -294,7 +294,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
externalIDP: &domain.ExternalIDP{
|
||||
link: &domain.UserIDPLink{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
},
|
||||
@@ -315,7 +315,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
externalIDP: &domain.ExternalIDP{
|
||||
link: &domain.UserIDPLink{
|
||||
IDPConfigID: "config1",
|
||||
ExternalUserID: "externaluser1",
|
||||
},
|
||||
@@ -331,7 +331,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"name",
|
||||
@@ -351,7 +351,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
externalIDP: &domain.ExternalIDP{
|
||||
link: &domain.UserIDPLink{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
},
|
||||
@@ -373,7 +373,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
externalIDP: &domain.ExternalIDP{
|
||||
link: &domain.UserIDPLink{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
},
|
||||
@@ -392,7 +392,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"name",
|
||||
@@ -403,20 +403,20 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPRemovedEvent(context.Background(),
|
||||
user.NewUserIDPLinkRemovedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"externaluser1",
|
||||
),
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveExternalIDPUniqueConstraint("config1", "externaluser1")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUserIDPLinkUniqueConstraint("config1", "externaluser1")),
|
||||
),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
externalIDP: &domain.ExternalIDP{
|
||||
link: &domain.UserIDPLink{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "user1",
|
||||
},
|
||||
@@ -436,7 +436,7 @@ func TestCommandSide_RemoveExternalIDP(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
got, err := r.RemoveHumanExternalIDP(tt.args.ctx, tt.args.externalIDP)
|
||||
got, err := r.RemoveUserIDPLink(tt.args.ctx, tt.args.link)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -492,7 +492,7 @@ func TestCommandSide_ExternalLoginCheck(t *testing.T) {
|
||||
t,
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"config1",
|
||||
"name",
|
||||
@@ -543,7 +543,7 @@ func TestCommandSide_ExternalLoginCheck(t *testing.T) {
|
||||
expectPush(
|
||||
[]*repository.Event{
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPCheckSucceededEvent(context.Background(),
|
||||
user.NewUserIDPCheckSucceededEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
&user.AuthRequestInfo{
|
||||
ID: "request1",
|
||||
@@ -574,7 +574,7 @@ func TestCommandSide_ExternalLoginCheck(t *testing.T) {
|
||||
r := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
}
|
||||
err := r.HumanExternalLoginChecked(tt.args.ctx, tt.args.orgID, tt.args.userID, tt.args.authRequest)
|
||||
err := r.UserIDPLoginChecked(tt.args.ctx, tt.args.orgID, tt.args.userID, tt.args.authRequest)
|
||||
if tt.res.err == nil {
|
||||
assert.NoError(t, err)
|
||||
}
|
@@ -13,9 +13,9 @@ import (
|
||||
type UserWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
UserName string
|
||||
ExternalIDPs []*domain.ExternalIDP
|
||||
UserState domain.UserState
|
||||
UserName string
|
||||
IDPLinks []*domain.UserIDPLink
|
||||
UserState domain.UserState
|
||||
}
|
||||
|
||||
func NewUserWriteModel(userID, resourceOwner string) *UserWriteModel {
|
||||
@@ -24,7 +24,7 @@ func NewUserWriteModel(userID, resourceOwner string) *UserWriteModel {
|
||||
AggregateID: userID,
|
||||
ResourceOwner: resourceOwner,
|
||||
},
|
||||
ExternalIDPs: make([]*domain.ExternalIDP, 0),
|
||||
IDPLinks: make([]*domain.UserIDPLink, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,24 +41,24 @@ func (wm *UserWriteModel) Reduce() error {
|
||||
wm.UserState = domain.UserStateInitial
|
||||
case *user.HumanInitializedCheckSucceededEvent:
|
||||
wm.UserState = domain.UserStateActive
|
||||
case *user.HumanExternalIDPAddedEvent:
|
||||
wm.ExternalIDPs = append(wm.ExternalIDPs, &domain.ExternalIDP{IDPConfigID: e.IDPConfigID, ExternalUserID: e.ExternalUserID})
|
||||
case *user.HumanExternalIDPRemovedEvent:
|
||||
idx, _ := wm.ExternalIDPByID(e.IDPConfigID, e.ExternalUserID)
|
||||
case *user.UserIDPLinkAddedEvent:
|
||||
wm.IDPLinks = append(wm.IDPLinks, &domain.UserIDPLink{IDPConfigID: e.IDPConfigID, ExternalUserID: e.ExternalUserID})
|
||||
case *user.UserIDPLinkRemovedEvent:
|
||||
idx, _ := wm.IDPLinkByID(e.IDPConfigID, e.ExternalUserID)
|
||||
if idx < 0 {
|
||||
continue
|
||||
}
|
||||
copy(wm.ExternalIDPs[idx:], wm.ExternalIDPs[idx+1:])
|
||||
wm.ExternalIDPs[len(wm.ExternalIDPs)-1] = nil
|
||||
wm.ExternalIDPs = wm.ExternalIDPs[:len(wm.ExternalIDPs)-1]
|
||||
case *user.HumanExternalIDPCascadeRemovedEvent:
|
||||
idx, _ := wm.ExternalIDPByID(e.IDPConfigID, e.ExternalUserID)
|
||||
copy(wm.IDPLinks[idx:], wm.IDPLinks[idx+1:])
|
||||
wm.IDPLinks[len(wm.IDPLinks)-1] = nil
|
||||
wm.IDPLinks = wm.IDPLinks[:len(wm.IDPLinks)-1]
|
||||
case *user.UserIDPLinkCascadeRemovedEvent:
|
||||
idx, _ := wm.IDPLinkByID(e.IDPConfigID, e.ExternalUserID)
|
||||
if idx < 0 {
|
||||
continue
|
||||
}
|
||||
copy(wm.ExternalIDPs[idx:], wm.ExternalIDPs[idx+1:])
|
||||
wm.ExternalIDPs[len(wm.ExternalIDPs)-1] = nil
|
||||
wm.ExternalIDPs = wm.ExternalIDPs[:len(wm.ExternalIDPs)-1]
|
||||
copy(wm.IDPLinks[idx:], wm.IDPLinks[idx+1:])
|
||||
wm.IDPLinks[len(wm.IDPLinks)-1] = nil
|
||||
wm.IDPLinks = wm.IDPLinks[:len(wm.IDPLinks)-1]
|
||||
case *user.MachineAddedEvent:
|
||||
wm.UserName = e.UserName
|
||||
wm.UserState = domain.UserStateActive
|
||||
@@ -96,9 +96,9 @@ func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
user.HumanAddedType,
|
||||
user.HumanRegisteredType,
|
||||
user.HumanInitializedCheckSucceededType,
|
||||
user.HumanExternalIDPAddedType,
|
||||
user.HumanExternalIDPRemovedType,
|
||||
user.HumanExternalIDPCascadeRemovedType,
|
||||
user.UserIDPLinkAddedType,
|
||||
user.UserIDPLinkRemovedType,
|
||||
user.UserIDPLinkCascadeRemovedType,
|
||||
user.MachineAddedEventType,
|
||||
user.UserUserNameChangedType,
|
||||
user.MachineChangedEventType,
|
||||
@@ -149,8 +149,8 @@ func hasUserState(check domain.UserState, states ...domain.UserState) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (wm *UserWriteModel) ExternalIDPByID(idpID, externalUserID string) (idx int, idp *domain.ExternalIDP) {
|
||||
for idx, idp = range wm.ExternalIDPs {
|
||||
func (wm *UserWriteModel) IDPLinkByID(idpID, externalUserID string) (idx int, idp *domain.UserIDPLink) {
|
||||
for idx, idp = range wm.IDPLinks {
|
||||
if idp.IDPConfigID == idpID && idp.ExternalUserID == externalUserID {
|
||||
return idx, idp
|
||||
}
|
||||
|
@@ -1078,7 +1078,7 @@ func TestCommandSide_RemoveUser(t *testing.T) {
|
||||
),
|
||||
),
|
||||
eventFromEventPusher(
|
||||
user.NewHumanExternalIDPAddedEvent(context.Background(),
|
||||
user.NewUserIDPLinkAddedEvent(context.Background(),
|
||||
&user.NewAggregate("user1", "org1").Aggregate,
|
||||
"idpConfigID",
|
||||
"displayName",
|
||||
@@ -1107,7 +1107,7 @@ func TestCommandSide_RemoveUser(t *testing.T) {
|
||||
),
|
||||
},
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUsernameUniqueConstraint("username", "org1", true)),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveExternalIDPUniqueConstraint("idpConfigID", "externalUserID")),
|
||||
uniqueConstraintsFromEventConstraint(user.NewRemoveUserIDPLinkUniqueConstraint("idpConfigID", "externalUserID")),
|
||||
),
|
||||
),
|
||||
},
|
||||
|
Reference in New Issue
Block a user