diff --git a/internal/iapl/default.go b/internal/iapl/default.go index 8daacd96..e9454d3f 100644 --- a/internal/iapl/default.go +++ b/internal/iapl/default.go @@ -1,8 +1,8 @@ package iapl -// DefaultPolicy generates the default policy for permissions-api. -func DefaultPolicy() Policy { - policyDocument := PolicyDocument{ +// DefaultPolicyDocument returns the default policy document for permissions-api. +func DefaultPolicyDocument() PolicyDocument { + return PolicyDocument{ ResourceTypes: []ResourceType{ { Name: "role", @@ -204,6 +204,11 @@ func DefaultPolicy() Policy { }, }, } +} + +// DefaultPolicy generates the default policy for permissions-api. +func DefaultPolicy() Policy { + policyDocument := DefaultPolicyDocument() policy := NewPolicy(policyDocument) if err := policy.Validate(); err != nil { diff --git a/internal/query/relations.go b/internal/query/relations.go index 340fb658..b29a94ce 100644 --- a/internal/query/relations.go +++ b/internal/query/relations.go @@ -40,12 +40,12 @@ func (e *engine) validateRelationship(rel types.Relationship) error { return err } - for _, typeRel := range subjType.Relationships { + for _, typeRel := range resType.Relationships { // If we find a relation with a name and type that matches our relationship, // return if rel.Relation == typeRel.Relation { for _, typeName := range typeRel.Types { - if resType.Name == typeName { + if subjType.Name == typeName { return nil } } diff --git a/internal/query/relations_test.go b/internal/query/relations_test.go index b276a54d..66ef3ca8 100644 --- a/internal/query/relations_test.go +++ b/internal/query/relations_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.infratographer.com/permissions-api/internal/iapl" "go.infratographer.com/permissions-api/internal/spicedbx" "go.infratographer.com/permissions-api/internal/testingx" "go.infratographer.com/permissions-api/internal/types" @@ -25,7 +26,12 @@ func testEngine(ctx context.Context, t *testing.T, namespace string) Engine { client, err := spicedbx.NewClient(config, false) require.NoError(t, err) - request := &pb.WriteSchemaRequest{Schema: spicedbx.GeneratedSchema(namespace)} + policy := testPolicy() + + schema, err := spicedbx.GenerateSchema(namespace, policy.Schema()) + require.NoError(t, err) + + request := &pb.WriteSchemaRequest{Schema: schema} _, err = client.WriteSchema(ctx, request) require.NoError(t, err) @@ -33,11 +39,37 @@ func testEngine(ctx context.Context, t *testing.T, namespace string) Engine { cleanDB(ctx, t, client, namespace) }) - out := NewEngine(namespace, client) + out := NewEngine(namespace, client, WithPolicy(policy)) return out } +func testPolicy() iapl.Policy { + policyDocument := iapl.DefaultPolicyDocument() + + policyDocument.ResourceTypes = append(policyDocument.ResourceTypes, + iapl.ResourceType{ + Name: "child", + IDPrefix: "chldten", + Relationships: []iapl.Relationship{ + { + Relation: "parent", + TargetTypeNames: []string{ + "tenant", + }, + }, + }, + }, + ) + + policy := iapl.NewPolicy(policyDocument) + if err := policy.Validate(); err != nil { + panic(err) + } + + return policy +} + func cleanDB(ctx context.Context, t *testing.T, client *authzed.Client, namespace string) { for _, dbType := range []string{"user", "client", "role", "tenant"} { namespacedType := namespace + "/" + dbType @@ -178,16 +210,18 @@ func TestRelationships(t *testing.T) { require.NoError(t, err) childRes, err := e.NewResourceFromID(childID) require.NoError(t, err) + child2ID, err := gidx.NewID("chldten") + require.NoError(t, err) + child2Res, err := e.NewResourceFromID(child2ID) + require.NoError(t, err) - testCases := []testingx.TestCase[[]types.Relationship, []types.Relationship]{ + testCases := []testingx.TestCase[types.Relationship, []types.Relationship]{ { Name: "InvalidRelationship", - Input: []types.Relationship{ - { - Resource: childRes, - Relation: "foo", - Subject: parentRes, - }, + Input: types.Relationship{ + Resource: childRes, + Relation: "foo", + Subject: parentRes, }, CheckFn: func(ctx context.Context, t *testing.T, res testingx.TestResult[[]types.Relationship]) { assert.ErrorIs(t, res.Err, errorInvalidRelationship) @@ -195,12 +229,10 @@ func TestRelationships(t *testing.T) { }, { Name: "Success", - Input: []types.Relationship{ - { - Resource: childRes, - Relation: "parent", - Subject: parentRes, - }, + Input: types.Relationship{ + Resource: childRes, + Relation: "parent", + Subject: parentRes, }, CheckFn: func(ctx context.Context, t *testing.T, res testingx.TestResult[[]types.Relationship]) { expRels := []types.Relationship{ @@ -211,21 +243,41 @@ func TestRelationships(t *testing.T) { }, } + require.NoError(t, res.Err) + assert.Equal(t, expRels, res.Success) + }, + }, + { + Name: "Different Success", + Input: types.Relationship{ + Resource: child2Res, + Relation: "parent", + Subject: parentRes, + }, + CheckFn: func(ctx context.Context, t *testing.T, res testingx.TestResult[[]types.Relationship]) { + expRels := []types.Relationship{ + { + Resource: child2Res, + Relation: "parent", + Subject: parentRes, + }, + } + require.NoError(t, res.Err) assert.Equal(t, expRels, res.Success) }, }, } - testFn := func(ctx context.Context, input []types.Relationship) testingx.TestResult[[]types.Relationship] { - queryToken, err := e.CreateRelationships(ctx, input) + testFn := func(ctx context.Context, input types.Relationship) testingx.TestResult[[]types.Relationship] { + queryToken, err := e.CreateRelationships(ctx, []types.Relationship{input}) if err != nil { return testingx.TestResult[[]types.Relationship]{ Err: err, } } - rels, err := e.ListRelationships(ctx, childRes, queryToken) + rels, err := e.ListRelationships(ctx, input.Resource, queryToken) return testingx.TestResult[[]types.Relationship]{ Success: rels,