From 6201328575f0dd711683fbbd7424437d5f3f6a48 Mon Sep 17 00:00:00 2001 From: zachmann Date: Tue, 12 May 2026 13:10:12 +0200 Subject: [PATCH 1/2] add tests for contacts essential policy handling in metadata policies --- metadataPolicy_test.go | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/metadataPolicy_test.go b/metadataPolicy_test.go index ea7a9fb..e72b4ef 100644 --- a/metadataPolicy_test.go +++ b/metadataPolicy_test.go @@ -167,3 +167,91 @@ func TestMergeAndApplyMetadataPolicies(t *testing.T) { ) } } + +func TestContactsEssentialPolicy(t *testing.T) { + tests := []struct { + name string + policy MetadataPolicy + metadata OpenIDRelyingPartyMetadata + expectedContacts []string + expectError bool + }{ + { + name: "contacts essential true with contacts provided", + policy: MetadataPolicy{ + "contacts": MetadataPolicyEntry{ + "essential": true, + }, + }, + metadata: OpenIDRelyingPartyMetadata{ + Contacts: []string{"contact@example.com"}, + }, + expectedContacts: []string{"contact@example.com"}, + expectError: false, + }, + { + name: "contacts essential true without empty contacts", + policy: MetadataPolicy{ + "contacts": MetadataPolicyEntry{ + "essential": true, + }, + }, + metadata: OpenIDRelyingPartyMetadata{Contacts: []string{}}, + expectedContacts: []string{}, + expectError: false, + }, + { + name: "contacts essential true without contacts", + policy: MetadataPolicy{ + "contacts": MetadataPolicyEntry{ + "essential": true, + }, + }, + metadata: OpenIDRelyingPartyMetadata{}, + expectedContacts: nil, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + result, err := applyPolicy(&tt.metadata, tt.policy, "") + if tt.expectError { + if err == nil { + t.Fatalf("expected error, but got none") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + resolved, ok := result.(*OpenIDRelyingPartyMetadata) + if !ok { + t.Fatalf("result is not OpenIDRelyingPartyMetadata") + } + + if len(tt.expectedContacts) == 0 && len(resolved.Contacts) == 0 { + return + } + + if len(tt.expectedContacts) != len(resolved.Contacts) { + t.Fatalf( + "contacts length mismatch: expected %d, got %d", + len(tt.expectedContacts), len(resolved.Contacts), + ) + } + + for i, expected := range tt.expectedContacts { + if resolved.Contacts[i] != expected { + t.Fatalf( + "contacts mismatch at index %d: expected %s, got %s", + i, expected, resolved.Contacts[i], + ) + } + } + }, + ) + } +} From fd1a5b9a48857b7c8b5e0bccc8e0eebadb239fe9 Mon Sep 17 00:00:00 2001 From: zachmann Date: Tue, 12 May 2026 15:51:38 +0200 Subject: [PATCH 2/2] fix handling of essential policy values to correctly validate unset and empty metadata values (bug with arrays) --- policyoperators.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/policyoperators.go b/policyoperators.go index 882e81b..c2ec76a 100644 --- a/policyoperators.go +++ b/policyoperators.go @@ -350,9 +350,12 @@ var policyOperatorEssential = NewPolicyOperator( if policyValue == nil { return value, valueSet, nil } - if essential, eok := policyValue.(bool); eok && essential && - (value == nil || (!utils.IsSlice(value) && reflect.ValueOf(value).IsZero())) { - return nil, valueSet, errors.Errorf("metadata value for '%s' not set but required", pathInfo) + if essential, eok := policyValue.(bool); eok && essential { + isNotSet := !valueSet && (value == nil || (utils.IsSlice(value) && reflect.ValueOf(value).IsNil()) || (!utils.IsSlice(value) && reflect.ValueOf(value).IsZero())) + isEmptyNonSlice := valueSet && !utils.IsSlice(value) && reflect.ValueOf(value).IsZero() + if isNotSet || isEmptyNonSlice { + return nil, valueSet, errors.Errorf("metadata value for '%s' not set but required", pathInfo) + } } return value, valueSet, nil },