From af94126f11b5c40625e25a104a33bb5469a7cf04 Mon Sep 17 00:00:00 2001 From: Mary Dickson Date: Mon, 20 Apr 2026 16:16:14 -0700 Subject: [PATCH 1/2] feat(sdk): add ergonomic Resource constructors for authorization Add ForAttributeValues and ForRegisteredResourceValueFqn helpers to reduce boilerplate when building Resource objects for authorization calls. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Mary Dickson --- protocol/go/authorization/v2/resource.gen.go | 26 +++++++ .../go/internal/authorization/v2/resource.go | 28 ++++++++ .../authorization/v2/resource_test.go | 71 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 protocol/go/authorization/v2/resource.gen.go create mode 100644 protocol/go/internal/authorization/v2/resource.go create mode 100644 protocol/go/internal/authorization/v2/resource_test.go diff --git a/protocol/go/authorization/v2/resource.gen.go b/protocol/go/authorization/v2/resource.gen.go new file mode 100644 index 0000000000..cf7db3ed07 --- /dev/null +++ b/protocol/go/authorization/v2/resource.gen.go @@ -0,0 +1,26 @@ +// Code generated by protocol/codegen. DO NOT EDIT. + +package authorizationv2 + +// ForAttributeValues returns a Resource containing the given attribute value FQNs. +// This is the most common Resource variant, used when authorizing against +// attribute values attached to data (e.g. those on a TDF). +func ForAttributeValues(fqns ...string) *Resource { + return &Resource{ + Resource: &Resource_AttributeValues_{ + AttributeValues: &Resource_AttributeValues{ + Fqns: fqns, + }, + }, + } +} + +// ForRegisteredResourceValueFqn returns a Resource that references a single +// registered resource value by its fully qualified name, as stored in platform policy. +func ForRegisteredResourceValueFqn(fqn string) *Resource { + return &Resource{ + Resource: &Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: fqn, + }, + } +} diff --git a/protocol/go/internal/authorization/v2/resource.go b/protocol/go/internal/authorization/v2/resource.go new file mode 100644 index 0000000000..294b8219c4 --- /dev/null +++ b/protocol/go/internal/authorization/v2/resource.go @@ -0,0 +1,28 @@ +package authorizationv2 + +import ( + authorizationv2 "github.com/opentdf/platform/protocol/go/authorization/v2" +) + +// ForAttributeValues returns a Resource containing the given attribute value FQNs. +// This is the most common Resource variant, used when authorizing against +// attribute values attached to data (e.g. those on a TDF). +func ForAttributeValues(fqns ...string) *authorizationv2.Resource { + return &authorizationv2.Resource{ + Resource: &authorizationv2.Resource_AttributeValues_{ + AttributeValues: &authorizationv2.Resource_AttributeValues{ + Fqns: fqns, + }, + }, + } +} + +// ForRegisteredResourceValueFqn returns a Resource that references a single +// registered resource value by its fully qualified name, as stored in platform policy. +func ForRegisteredResourceValueFqn(fqn string) *authorizationv2.Resource { + return &authorizationv2.Resource{ + Resource: &authorizationv2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: fqn, + }, + } +} diff --git a/protocol/go/internal/authorization/v2/resource_test.go b/protocol/go/internal/authorization/v2/resource_test.go new file mode 100644 index 0000000000..0d883e0b1e --- /dev/null +++ b/protocol/go/internal/authorization/v2/resource_test.go @@ -0,0 +1,71 @@ +package authorizationv2 + +import ( + "testing" + + authorizationv2proto "github.com/opentdf/platform/protocol/go/authorization/v2" +) + +func TestForAttributeValues(t *testing.T) { + fqns := []string{ + "https://example.com/attr/department/value/finance", + "https://example.com/attr/level/value/public", + } + r := ForAttributeValues(fqns...) + + av, ok := r.GetResource().(*authorizationv2proto.Resource_AttributeValues_) + if !ok { + t.Fatal("expected AttributeValues resource") + } + got := av.AttributeValues.GetFqns() + if len(got) != len(fqns) { + t.Fatalf("fqns len = %d, want %d", len(got), len(fqns)) + } + for i, fqn := range fqns { + if got[i] != fqn { + t.Errorf("fqns[%d] = %q, want %q", i, got[i], fqn) + } + } +} + +func TestForAttributeValues_Single(t *testing.T) { + fqn := "https://example.com/attr/department/value/finance" + r := ForAttributeValues(fqn) + + av, ok := r.GetResource().(*authorizationv2proto.Resource_AttributeValues_) + if !ok { + t.Fatal("expected AttributeValues resource") + } + got := av.AttributeValues.GetFqns() + if len(got) != 1 { + t.Fatalf("fqns len = %d, want 1", len(got)) + } + if got[0] != fqn { + t.Errorf("fqns[0] = %q, want %q", got[0], fqn) + } +} + +func TestForRegisteredResourceValueFqn(t *testing.T) { + fqn := "https://example.com/attr/department/value/finance" + r := ForRegisteredResourceValueFqn(fqn) + + rr, ok := r.GetResource().(*authorizationv2proto.Resource_RegisteredResourceValueFqn) + if !ok { + t.Fatal("expected RegisteredResourceValueFqn resource") + } + if rr.RegisteredResourceValueFqn != fqn { + t.Errorf("fqn = %q, want %q", rr.RegisteredResourceValueFqn, fqn) + } +} + +func TestForRegisteredResourceValueFqn_EmptyString(t *testing.T) { + r := ForRegisteredResourceValueFqn("") + + rr, ok := r.GetResource().(*authorizationv2proto.Resource_RegisteredResourceValueFqn) + if !ok { + t.Fatal("expected RegisteredResourceValueFqn resource") + } + if rr.RegisteredResourceValueFqn != "" { + t.Errorf("fqn = %q, want empty string", rr.RegisteredResourceValueFqn) + } +} From b5fa102c56c8c428f94c9cfbf578a7d9f4860aec Mon Sep 17 00:00:00 2001 From: Mary Dickson Date: Tue, 21 Apr 2026 08:11:17 -0700 Subject: [PATCH 2/2] chore(sdk): add zero-args test for ForAttributeValues Document the behavior of ForAttributeValues() called with no arguments, which produces a Resource with a nil FQN slice. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Mary Dickson --- .../go/internal/authorization/v2/resource_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/protocol/go/internal/authorization/v2/resource_test.go b/protocol/go/internal/authorization/v2/resource_test.go index 0d883e0b1e..9918252a3c 100644 --- a/protocol/go/internal/authorization/v2/resource_test.go +++ b/protocol/go/internal/authorization/v2/resource_test.go @@ -45,6 +45,19 @@ func TestForAttributeValues_Single(t *testing.T) { } } +func TestForAttributeValues_ZeroArgs(t *testing.T) { + r := ForAttributeValues() + + av, ok := r.GetResource().(*authorizationv2proto.Resource_AttributeValues_) + if !ok { + t.Fatal("expected AttributeValues resource") + } + got := av.AttributeValues.GetFqns() + if len(got) != 0 { + t.Fatalf("fqns len = %d, want 0", len(got)) + } +} + func TestForRegisteredResourceValueFqn(t *testing.T) { fqn := "https://example.com/attr/department/value/finance" r := ForRegisteredResourceValueFqn(fqn)