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
+127
View File
@@ -338,6 +338,133 @@ func TestCommandSide_ChangeUserMachine(t *testing.T) {
},
},
},
{
name: "change machine metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(userAddedEvent),
),
expectPush(
user.NewMetadataSetEvent(
context.Background(),
&userAgg.Aggregate,
"key1",
[]byte("value1"),
),
user.NewMetadataSetEvent(
context.Background(),
&userAgg.Aggregate,
"key3",
[]byte("value3"),
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
machine: &ChangeMachine{
Metadata: []*domain.Metadata{
{
Key: "key1",
Value: []byte("value1"),
},
{
Key: "key3",
Value: []byte("value3"),
},
},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
name: "change machine metadata, delete metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(userAddedEvent),
eventFromEventPusher( // pre-existing metadata
user.NewMetadataSetEvent(
context.Background(),
&userAgg.Aggregate,
"key1",
[]byte("value1")),
),
eventFromEventPusher( // pre-existing metadata
user.NewMetadataSetEvent(
context.Background(),
&userAgg.Aggregate,
"key2",
[]byte("value2")),
),
),
expectPush(
user.NewMetadataRemovedEvent(
context.Background(),
&userAgg.Aggregate,
"key2",
),
),
),
checkPermission: newMockPermissionCheckAllowed(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
machine: &ChangeMachine{
Metadata: []*domain.Metadata{
{
Key: "key1",
Value: []byte("value1"),
},
{
Key: "key2",
Value: []byte(""),
},
},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
name: "change machine metadata, no permission",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(userAddedEvent),
),
),
checkPermission: newMockPermissionCheckNotAllowed(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
machine: &ChangeMachine{
Metadata: []*domain.Metadata{
{
Key: "key1",
Value: []byte("value1"),
},
},
},
},
res: res{
err: func(err error) bool {
return errors.Is(err, zerrors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied"))
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {