feat: set metadata field in UpdateUser endpoint (#11747)

# Which Problems Are Solved

To be able to update metadata via the `UpdateUser` endpoint.

# How the Problems Are Solved
This is achieved by:
* adding the `Metadata` field to `UpdateUserRequest`
* update the server layer to convert/set metadata fields to domain layer
metadata
* update the command layer to handle metadata updates

# Additional Changes

N/A

# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/11369,
https://github.com/zitadel/zitadel/issues/11759
- Follow-up for PR https://github.com/zitadel/zitadel/pull/11719

---------

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Gayathri Vijayan
2026-03-09 10:47:32 +01:00
committed by GitHub
co-authored by Copilot
parent 5b12690757
commit 282b2486d9
14 changed files with 896 additions and 165 deletions
+115
View File
@@ -704,6 +704,121 @@ func TestCommandSide_BulkSetUserMetadata(t *testing.T) {
},
},
},
{
name: "add and delete metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
),
),
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key2",
[]byte("value2"),
),
),
),
expectPush(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("updated_value1"),
),
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key2",
),
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key3",
[]byte("value3"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key1", Value: []byte("updated_value1")},
{Key: "key2"},
{Key: "key3", Value: []byte("value3")},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
name: "delete non existing key, ok (ignored)",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key2"},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {