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:
Lars
2025-01-14 15:44:41 +01:00
committed by GitHub
parent 84997ffe1a
commit d01d003a03
20 changed files with 1029 additions and 95 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/zitadel/zitadel/internal/api/scim/schemas"
"github.com/zitadel/zitadel/internal/api/scim/serrors"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
)
@@ -55,6 +56,28 @@ func buildMetadataKeyQuery(ctx context.Context, key metadata.Key) query.SearchQu
return q
}
func (h *UsersHandler) mapMetadataToDomain(ctx context.Context, user *ScimUser) (md []*domain.Metadata, skippedMetadata []string, err error) {
md = make([]*domain.Metadata, 0, len(metadata.ScimUserRelevantMetadataKeys))
for _, key := range metadata.ScimUserRelevantMetadataKeys {
var value []byte
value, err = getValueForMetadataKey(user, key)
if err != nil {
return
}
if len(value) > 0 {
md = append(md, &domain.Metadata{
Key: string(metadata.ScopeKey(ctx, key)),
Value: value,
})
} else {
skippedMetadata = append(skippedMetadata, string(metadata.ScopeKey(ctx, key)))
}
}
return
}
func (h *UsersHandler) mapMetadataToCommands(ctx context.Context, user *ScimUser) ([]*command.AddMetadataEntry, error) {
md := make([]*command.AddMetadataEntry, 0, len(metadata.ScimUserRelevantMetadataKeys))
for _, key := range metadata.ScimUserRelevantMetadataKeys {