Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
53f5e85
more merge conflicts
alkalescent Mar 11, 2024
2ee64a6
remove commented out file
alkalescent Mar 11, 2024
8ec2b58
fix subject mapping test
alkalescent Mar 11, 2024
264d2f1
clean up
alkalescent Mar 12, 2024
915a548
Merge branch 'main' into feature/check-members
alkalescent Mar 12, 2024
91198e3
change fqn table on condition
alkalescent Mar 12, 2024
4da80e4
better fqn support
alkalescent Mar 12, 2024
ca6ef6d
Merge branch 'main' into feature/check-members-merge-0313
jakedoublev Mar 13, 2024
6a35e05
rename migration files to reorder
jakedoublev Mar 13, 2024
716022f
placeholder to bring in subject mappings into the value
jakedoublev Mar 13, 2024
968d523
unmarshaling improvements with successful members provision on get va…
jakedoublev Mar 13, 2024
c5c1514
join value members for get attribute call
alkalescent Mar 14, 2024
5e1f51e
join value members for list subject mappings call
alkalescent Mar 14, 2024
477f928
clean up
alkalescent Mar 14, 2024
a7fffe7
join value members for get resource mapping call
alkalescent Mar 14, 2024
5ceeb0e
clean up
alkalescent Mar 14, 2024
e0cd4d9
join value members for list all attr vals call
alkalescent Mar 14, 2024
65316a0
clean up
alkalescent Mar 14, 2024
95112d7
join value members for list attr vals call
alkalescent Mar 14, 2024
e618d92
fix deep equality test
alkalescent Mar 14, 2024
ece2fed
clean up
alkalescent Mar 14, 2024
53b5550
again
alkalescent Mar 14, 2024
f1dc6ef
Merge branch 'main' into feature/check-members-merge-0313
alkalescent Mar 14, 2024
3ad315e
Update migrations/20240313000000_create_val_members.md
alkalescent Mar 14, 2024
08ffa28
remove debug statement
alkalescent Mar 14, 2024
bb2a8fa
rename table
alkalescent Mar 14, 2024
df41d3b
remove db triggers
alkalescent Mar 14, 2024
66398db
Merge branch 'main' into feature/check-members-merge-0313
alkalescent Mar 14, 2024
ad5df0d
update ERD
alkalescent Mar 14, 2024
adc0ff1
remove set
alkalescent Mar 14, 2024
0be9b32
Merge branch 'main' into feature/check-members-merge-0313
alkalescent Mar 14, 2024
2c349d5
add value member test to resource mapping
alkalescent Mar 14, 2024
b4d590b
add value member test to subject mapping
alkalescent Mar 14, 2024
35199ba
Merge branch 'main' into feature/check-members-merge-0313
alkalescent Mar 14, 2024
ef02242
add tests for value member foreign key violations and invalid uuids
alkalescent Mar 14, 2024
8234843
add unique constraint violation test
alkalescent Mar 14, 2024
2f3d6e8
remove debug statement
alkalescent Mar 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ var (
fmt.Print("migration down applied successfully")
},
}

migrateUpCmd = &cobra.Command{
Use: "up",
Short: "Run database migrations up to the latest version",
Expand Down
2 changes: 1 addition & 1 deletion docs/grpc/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion docs/openapi/policy/attributes/attributes.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 57 additions & 2 deletions integration/attribute_values_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package integration
import (
"context"
"log/slog"
"sort"
"testing"

"github.com/opentdf/platform/internal/db"
Expand Down Expand Up @@ -138,7 +139,24 @@ func (s *AttributeValuesSuite) Test_CreateAttributeValue_NoMembers_Succeeds() {
assert.Equal(s.T(), len(createdValue.Members), len(got.Members))
assert.EqualValues(s.T(), createdValue.Metadata.Labels, got.Metadata.Labels)
}

func equalMembers(t *testing.T, v1 *policy.Value, v2 *policy.Value, withFqn bool) {
m1 := v1.Members
m2 := v2.Members
sort.Slice(m1, func(x, y int) bool {
return m1[x].Id < m1[y].Id
})
sort.Slice(m2, func(x, y int) bool {
return m2[x].Id < m2[y].Id
})
for idx := range m1 {
assert.Equal(t, m1[idx].Id, m2[idx].Id)
assert.Equal(t, m1[idx].Value, m2[idx].Value)
if withFqn {
assert.Equal(t, m1[idx].Fqn, m2[idx].Fqn)
}
assert.Equal(t, m1[idx].Active.Value, m2[idx].Active.Value)
}
}
func (s *AttributeValuesSuite) Test_CreateAttributeValue_WithMembers_Succeeds() {
attrDef := s.f.GetAttributeKey("example.net/attr/attr1")
metadata := &common.MetadataMutable{
Expand All @@ -165,7 +183,16 @@ func (s *AttributeValuesSuite) Test_CreateAttributeValue_WithMembers_Succeeds()
assert.Equal(s.T(), createdValue.Id, got.Id)
assert.Equal(s.T(), createdValue.Value, got.Value)
assert.EqualValues(s.T(), createdValue.Metadata.Labels, got.Metadata.Labels)
assert.EqualValues(s.T(), createdValue.Members, got.Members)
assert.Equal(s.T(), len(createdValue.Members), len(got.Members))

assert.True(s.T(), len(got.Members) > 0)
equalMembers(s.T(), createdValue, got, true)

// test uniqueness
createdValue, err = s.db.PolicyClient.CreateAttributeValue(s.ctx, attrDef.Id, value)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), createdValue)
assert.ErrorIs(s.T(), err, db.ErrUniqueConstraintViolation)
}

func (s *AttributeValuesSuite) Test_CreateAttributeValue_WithInvalidAttributeId_Fails() {
Expand All @@ -178,6 +205,34 @@ func (s *AttributeValuesSuite) Test_CreateAttributeValue_WithInvalidAttributeId_
assert.ErrorIs(s.T(), err, db.ErrForeignKeyViolation)
}

func (s *AttributeValuesSuite) Test_CreateAttributeValue_WithInvalidMember_Fails() {
attrDef := s.f.GetAttributeKey("example.net/attr/attr2")
metadata := &common.MetadataMutable{
Labels: map[string]string{
"name": "testing create with members",
},
}

value := &attributes.CreateAttributeValueRequest{
Value: "value3",
Members: []string{
nonExistentAttributeValueUuid,
},
Metadata: metadata,
}
createdValue, err := s.db.PolicyClient.CreateAttributeValue(s.ctx, attrDef.Id, value)
assert.Nil(s.T(), createdValue)
assert.NotNil(s.T(), err)
assert.ErrorIs(s.T(), err, db.ErrForeignKeyViolation)

attrDef = s.f.GetAttributeKey("example.net/attr/attr3")
value.Members[0] = "not a uuid"
createdValue, err = s.db.PolicyClient.CreateAttributeValue(s.ctx, attrDef.Id, value)
assert.Nil(s.T(), createdValue)
assert.NotNil(s.T(), err)
assert.ErrorIs(s.T(), err, db.ErrUuidInvalid)
}

func (s *AttributeValuesSuite) Test_UpdateAttributeValue() {
fixedLabel := "fixed label"
updateLabel := "update label"
Expand Down
13 changes: 12 additions & 1 deletion integration/resource_mappings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (s *ResourceMappingsSuite) getResourceMappingFixtures() []fixtures.FixtureD
s.f.GetResourceMappingKey("resource_mapping_to_attribute_value1"),
s.f.GetResourceMappingKey("resource_mapping_to_attribute_value2"),
s.f.GetResourceMappingKey("resource_mapping_to_attribute_value3"),
s.f.GetResourceMappingKey("resource_mapping_to_attribute_value4"),
}
}

Expand Down Expand Up @@ -115,13 +116,23 @@ func (s *ResourceMappingsSuite) Test_ListResourceMappings() {
func (s *ResourceMappingsSuite) Test_GetResourceMapping() {
// make sure we can get all fixtures
testData := s.getResourceMappingFixtures()
for _, testMapping := range testData {
testedMembers := false
for idx, testMapping := range testData {
mapping, err := s.db.PolicyClient.GetResourceMapping(s.ctx, testMapping.Id)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), mapping)
assert.Equal(s.T(), testMapping.Id, mapping.Id)
assert.Equal(s.T(), testMapping.AttributeValueId, mapping.AttributeValue.Id)
assert.Equal(s.T(), testMapping.Terms, mapping.Terms)
av, err := s.db.PolicyClient.GetAttributeValue(s.ctx, testMapping.AttributeValueId)
assert.Nil(s.T(), err)
if len(av.Members) > 0 {
testedMembers = true
}
if idx == len(testData)-1 {
assert.True(s.T(), testedMembers, "expected to test at least one attribute value member")
}
equalMembers(s.T(), av, mapping.AttributeValue, false)
}
}

Expand Down
8 changes: 7 additions & 1 deletion integration/subject_mappings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func (s *SubjectMappingsSuite) TestUpdateSubjectMapping_NonExistentSubjectCondit
}

func (s *SubjectMappingsSuite) TestGetSubjectMapping() {
fixture := s.f.GetSubjectMappingKey("subject_mapping_subject_attribute3")
fixture := s.f.GetSubjectMappingKey("subject_mapping_subject_attribute2")

sm, err := s.db.PolicyClient.GetSubjectMapping(s.ctx, fixture.Id)
assert.Nil(s.T(), err)
Expand All @@ -367,6 +367,12 @@ func (s *SubjectMappingsSuite) TestGetSubjectMapping() {
assert.Equal(s.T(), "custom:\""+fixture.Actions[i].Custom+"\"", a.String())
}
}
got, err := s.db.PolicyClient.GetAttributeValue(s.ctx, fixture.AttributeValueId)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), got)
assert.Equal(s.T(), fixture.AttributeValueId, got.Id)
assert.True(s.T(), len(got.Members) > 0)
equalMembers(s.T(), got, sm.AttributeValue, false)
}

func (s *SubjectMappingsSuite) TestGetSubjectMapping_NonExistentId_Fails() {
Expand Down
1 change: 0 additions & 1 deletion internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"net"

sq "github.com/Masterminds/squirrel"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/jackc/pgx/v5/pgxpool"
Expand Down
33 changes: 33 additions & 0 deletions internal/fixtures/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ type FixtureDataAttributeValue struct {
Active bool `yaml:"active"`
}

type FixtureDataValueMember struct {
Id string `yaml:"id"`
ValueID string `yaml:"value_id"`
MemberID string `yaml:"member_id"`
}

type FixtureDataAttributeValueKeyAccessServer struct {
ValueID string `yaml:"value_id"`
KeyAccessServerID string `yaml:"key_access_server_id"`
Expand Down Expand Up @@ -123,6 +129,10 @@ type FixtureData struct {
Metadata FixtureMetadata `yaml:"metadata"`
Data map[string]FixtureDataKasRegistry `yaml:"data"`
} `yaml:"kas_registry"`
ValueMembers struct {
Metadata FixtureMetadata `yaml:"metadata"`
Data map[string]FixtureDataValueMember `yaml:"data"`
} `yaml:"attribute_value_members"`
}

func LoadFixtureData(file string) {
Expand Down Expand Up @@ -176,6 +186,14 @@ func (f *Fixtures) GetAttributeValueKey(key string) FixtureDataAttributeValue {
return av
}

func (f *Fixtures) GetValueMemberKey(key string) FixtureDataValueMember {
if fixtureData.ValueMembers.Data[key].Id == "" {
slog.Error("could not find value-members", slog.String("id", key))
panic("could not find value-members")
}
return fixtureData.ValueMembers.Data[key]
}

func (f *Fixtures) GetSubjectMappingKey(key string) FixtureDataSubjectMapping {
sm, ok := fixtureData.SubjectMappings.Data[key]
if !ok || sm.Id == "" {
Expand Down Expand Up @@ -225,6 +243,8 @@ func (f *Fixtures) Provision() {
a := f.provisionAttribute()
slog.Info("📦 provisioning attribute value data")
aV := f.provisionAttributeValues()
slog.Info("📦 provisioning value member data")
vM := f.provisionValueMembers()
slog.Info("📦 provisioning subject condition set data")
sc := f.provisionSubjectConditionSet()
slog.Info("📦 provisioning subject mapping data")
Expand All @@ -242,6 +262,7 @@ func (f *Fixtures) Provision() {
slog.Int64("namespaces", n),
slog.Int64("attributes", a),
slog.Int64("attribute_values", aV),
slog.Int64("attribute_value_members", vM),
slog.Int64("subject_mappings", sM),
slog.Int64("subject_condition_set", sc),
slog.Int64("resource_mappings", rM),
Expand Down Expand Up @@ -304,6 +325,18 @@ func (f *Fixtures) provisionAttributeValues() int64 {
return f.provision(fixtureData.AttributeValues.Metadata.TableName, fixtureData.AttributeValues.Metadata.Columns, values)
}

func (f *Fixtures) provisionValueMembers() int64 {
values := make([][]string, 0, len(fixtureData.ValueMembers.Data))
for _, d := range fixtureData.ValueMembers.Data {
values = append(values, []string{
f.db.StringWrap(d.Id),
f.db.StringWrap(d.ValueID),
f.db.StringWrap(d.MemberID),
})
}
return f.provision(fixtureData.ValueMembers.Metadata.TableName, fixtureData.ValueMembers.Metadata.Columns, values)
}

func (f *Fixtures) provisionSubjectConditionSet() int64 {
values := make([][]string, 0, len(fixtureData.SubjectConditionSet.Data))
for _, d := range fixtureData.SubjectConditionSet.Data {
Expand Down
29 changes: 25 additions & 4 deletions internal/fixtures/policy_fixtures.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ attribute_values:
attribute_definition_id: 6a261d68-0899-4e17-bb2f-124abba7c09c
value: value2
members:
# example.com/attr/attr2/value/value1
- 0fd363db-27b1-4210-b77b-8c82fe044d41
# example.net/attr/attr1/value/value1
- 532e5957-28f7-466d-91e2-493e9431cd83
# pivots value: example.com/attr/attr2/value/value1
- bf461e97-a918-4aa5-83ad-9bb768a58d12
# pivots value: example.net/attr/attr1/value/value1
- ddd9c539-2a2b-47ba-aad3-95b54dd022ef
active: true

example.com/attr/attr2/value/value1:
Expand Down Expand Up @@ -187,6 +187,22 @@ attribute_value_key_access_servers:
- value_id: 74babca6-016f-4f3e-a99b-4e46ea8d0fd8
key_access_server_id: e36640a6-61c5-4d4c-a45b-0e0a26d1c45f

attribute_value_members:
metadata:
table_name: attribute_value_members
columns:
- id
- value_id
- member_id
data:
member1:
id: bf461e97-a918-4aa5-83ad-9bb768a58d12
value_id: 2fe8dea1-3555-498c-afe9-99724f35f3d3
member_id: 0fd363db-27b1-4210-b77b-8c82fe044d41
member2:
id: ddd9c539-2a2b-47ba-aad3-95b54dd022ef
value_id: 2fe8dea1-3555-498c-afe9-99724f35f3d3
member_id: 532e5957-28f7-466d-91e2-493e9431cd83
##
# Subject Mappings -> 1 Group of Subject Condition Sets
##
Expand Down Expand Up @@ -386,6 +402,11 @@ resource_mappings:
attribute_value_id: 04bd2657-de10-46bc-a88f-5d687de4816b
terms:
- helloworld
resource_mapping_to_attribute_value4:
id: f99d1c97-ad8a-40c8-8148-6539764e2743
attribute_value_id: 2fe8dea1-3555-498c-afe9-99724f35f3d3
terms:
- with_members

##
# KAS Registry (key access server registry)
Expand Down
29 changes: 29 additions & 0 deletions migrations/20240313000000_create_val_members.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Diagram for 20240223000000_create_val_members.sql

```mermaid
---
title: Attribute Value Mermaid Diagram
nodes: |
---

erDiagram
AttributeValue ||--o{ ValueMember: "has group members"

AttributeValue {
uuid id PK
uuid namespace_id FK
uuid attribute_definition_id FK
varchar value
jsonb metadata
compIdx comp_key UK "ns_id + ad_id + value"
bool active
}

ValueMember {
uuid id PK
uuid value_id FK
uuid member_id FK
compIdx comp_key UK "value_id + member_id"
}

```
18 changes: 18 additions & 0 deletions migrations/20240313000000_create_val_members.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- +goose Up
-- +goose StatementBegin

CREATE TABLE IF NOT EXISTS attribute_value_members
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
value_id UUID NOT NULL REFERENCES attribute_values(id),
member_id UUID NOT NULL REFERENCES attribute_values(id),
UNIQUE (value_id, member_id)
);

-- +goose StatementEnd

-- +goose Down

-- +goose StatementBegin
DROP TABLE IF EXISTS attribute_value_members;
-- +goose StatementEnd
Loading