mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat: replace user scim v2 endpoint (#9163)
# Which Problems Are Solved - Adds support for the replace user SCIM v2 endpoint # How the Problems Are Solved - Adds support for the replace user SCIM v2 endpoint under `PUT /scim/v2/{orgID}/Users/{id}` # Additional Changes - Respect the `Active` field in the SCIM v2 create user endpoint `POST /scim/v2/{orgID}/Users` - Eventually consistent read endpoints used in SCIM tests are wrapped in `assert.EventuallyWithT` to work around race conditions # Additional Context Part of #8140
This commit is contained in:
@@ -14,11 +14,14 @@ import (
|
||||
)
|
||||
|
||||
type ChangeHuman struct {
|
||||
ID string
|
||||
Username *string
|
||||
Profile *Profile
|
||||
Email *Email
|
||||
Phone *Phone
|
||||
ID string
|
||||
State *domain.UserState
|
||||
Username *string
|
||||
Profile *Profile
|
||||
Email *Email
|
||||
Phone *Phone
|
||||
Metadata []*domain.Metadata
|
||||
MetadataKeysToRemove []string
|
||||
|
||||
Password *Password
|
||||
|
||||
@@ -100,6 +103,15 @@ func (h *ChangeHuman) Changed() bool {
|
||||
if h.Password != nil {
|
||||
return true
|
||||
}
|
||||
if h.State != nil {
|
||||
return true
|
||||
}
|
||||
if len(h.Metadata) > 0 {
|
||||
return true
|
||||
}
|
||||
if len(h.MetadataKeysToRemove) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -229,6 +241,10 @@ func (c *Commands) AddUserHuman(ctx context.Context, resourceOwner string, human
|
||||
)
|
||||
}
|
||||
|
||||
if human.SetInactive {
|
||||
cmds = append(cmds, user.NewUserDeactivatedEvent(ctx, &existingHuman.Aggregate().Aggregate))
|
||||
}
|
||||
|
||||
if len(cmds) == 0 {
|
||||
human.Details = writeModelToObjectDetails(&existingHuman.WriteModel)
|
||||
return nil
|
||||
@@ -270,6 +286,7 @@ func (c *Commands) ChangeUserHuman(ctx context.Context, human *ChangeHuman, alg
|
||||
}
|
||||
}
|
||||
|
||||
userAgg := UserAggregateFromWriteModelCtx(ctx, &existingHuman.WriteModel)
|
||||
cmds := make([]eventstore.Command, 0)
|
||||
if human.Username != nil {
|
||||
cmds, err = c.changeUsername(ctx, cmds, existingHuman, *human.Username)
|
||||
@@ -302,6 +319,58 @@ func (c *Commands) ChangeUserHuman(ctx context.Context, human *ChangeHuman, alg
|
||||
}
|
||||
}
|
||||
|
||||
for _, md := range human.Metadata {
|
||||
cmd, err := c.setUserMetadata(ctx, userAgg, md)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
|
||||
for _, mdKey := range human.MetadataKeysToRemove {
|
||||
cmd, err := c.removeUserMetadata(ctx, userAgg, mdKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
|
||||
if human.State != nil {
|
||||
// only allow toggling between active and inactive
|
||||
// any other target state is not supported
|
||||
// the existing human's state has to be the
|
||||
switch {
|
||||
case isUserStateActive(*human.State):
|
||||
if isUserStateActive(existingHuman.UserState) {
|
||||
// user is already active => no change needed
|
||||
break
|
||||
}
|
||||
|
||||
// do not allow switching from other states than active (e.g. locked)
|
||||
if !isUserStateInactive(existingHuman.UserState) {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "USER2-statex1", "Errors.User.State.Invalid")
|
||||
}
|
||||
|
||||
cmds = append(cmds, user.NewUserReactivatedEvent(ctx, &existingHuman.Aggregate().Aggregate))
|
||||
case isUserStateInactive(*human.State):
|
||||
if isUserStateInactive(existingHuman.UserState) {
|
||||
// user is already inactive => no change needed
|
||||
break
|
||||
}
|
||||
|
||||
// do not allow switching from other states than active (e.g. locked)
|
||||
if !isUserStateActive(existingHuman.UserState) {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "USER2-statex2", "Errors.User.State.Invalid")
|
||||
}
|
||||
|
||||
cmds = append(cmds, user.NewUserDeactivatedEvent(ctx, &existingHuman.Aggregate().Aggregate))
|
||||
default:
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "USER2-statex3", "Errors.User.State.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
if len(cmds) == 0 {
|
||||
human.Details = writeModelToObjectDetails(&existingHuman.WriteModel)
|
||||
return nil
|
||||
|
Reference in New Issue
Block a user