feat: delete metadata on SetOrganizationMetadata api (#11790)

# Which Problems Are Solved

Currently, to delete an Organization metadata key, callers must use a
separate
[DeleteMetadata](https://zitadel.com/docs/reference/api/org/zitadel.org.v2.OrganizationService.DeleteOrganizationMetadata)
API. This increases the complexity on client-side for operations where
metadata need to be synchronized.

# How the Problems Are Solved

Introduce deletion behavior to
[SetOrganizationMetadata](https://zitadel.com/docs/reference/api/org/zitadel.org.v2.OrganizationService.SetOrganizationMetadata):

When a metadata entry is passed with an empty value ("" / empty bytes):

- If the key exists → delete the key
- If the key does not exist → no-op (idempotent, no error)

# Additional Changes

n/a

# Additional Context

Relates to #11776

---------

Co-authored-by: Gayathri Vijayan <[email protected]>
Co-authored-by: Gayathri Vijayan <[email protected]>
This commit is contained in:
Vitor Bari Buccianti
2026-03-10 10:09:51 +00:00
committed by GitHub
co-authored by Gayathri Vijayan Gayathri Vijayan
parent 8b90ddb0b5
commit 62cb5bbb83
9 changed files with 267 additions and 142 deletions
+15
View File
@@ -12,6 +12,7 @@ import (
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
metadata "github.com/zitadel/zitadel/pkg/grpc/metadata/v2"
resources_object "github.com/zitadel/zitadel/pkg/grpc/resources/object/v3alpha"
)
@@ -176,3 +177,17 @@ func diffProto(expected, actual proto.Message) string {
}
return "\n\nDiff:\n" + diff
}
// AssertMetadataEquals verifies that two slices of proto Metadata are equal, comparing both length and content by key-value mapping.
func AssertMetadataEquals(t assert.TestingT, expected []*metadata.Metadata, actual []*metadata.Metadata) {
assert.Equal(t, len(expected), len(actual), "metadata length mismatch")
assert.Equal(t, getMetadataMap(expected), getMetadataMap(actual), "metadata content mismatch")
}
func getMetadataMap(metadataEntries []*metadata.Metadata) map[string][]byte {
metadataByKey := make(map[string][]byte, len(metadataEntries))
for _, md := range metadataEntries {
metadataByKey[md.Key] = md.Value
}
return metadataByKey
}