ory / keto

Open Source (Go) implementation of "Zanzibar: Google's Consistent, Global Authorization System". Ships gRPC, REST APIs, newSQL, and an easy and granular permission language. Supports ACL, RBAC, and other access models.

Home Page:https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=keto

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Subject expansion failed when depth exceeds 2

stonelgh opened this issue · comments

Preflight checklist

Describe the bug

Given the namespace definition

class Role implements Namespace {
	related: {
		perms: SubjectSet<Role, "perms">[]
	}
}

and the relation tuples:

"Role:a#perms@Role:b#perms",
"Role:b#perms@Role:c#perms",
"Role:c#perms@Role:d#perms",
"Role:d#perms@get",

The check "Role:a#perms@get" will fail.

Reproducing the bug

package check_test

import (
	"context"
	"testing"

	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/goleak"

	"github.com/ory/keto/internal/check"
	"github.com/ory/keto/internal/check/checkgroup"
	"github.com/ory/keto/internal/driver/config"
	"github.com/ory/keto/internal/namespace"
	"github.com/ory/keto/internal/schema"
)

func TestSubjectExpansion(t *testing.T) {
	var rawns = `
	import { Namespace, SubjectSet, Context } from '@ory/keto-namespace-types';
	
	class Role implements Namespace {
	  related: {
		perms: SubjectSet<Role, "perms">[]
	  }
	}`

	nss, err := schema.Parse(rawns)
	require.True(t, err == nil)
	namespaces := make([]*namespace.Namespace, len(nss))
	for i, ns := range nss {
		ns := ns
		namespaces[i] = &ns
	}

	reg := newDepsProvider(t, namespaces)
	reg.Logger().Logger.SetLevel(logrus.InfoLevel)

	insertFixtures(t, reg.RelationTupleManager(), []string{
		"Role:a#perms@Role:b#perms",
		"Role:b#perms@Role:c#perms",
		"Role:c#perms@Role:d#perms",
		"Role:d#perms@get",
	})

	testCases := []struct {
		query         string
		expected      checkgroup.Result
		expectedPaths []path
	}{{
		query:    "Role:d#perms@get",
		expected: checkgroup.ResultIsMember,
	}, {
		query:    "Role:c#perms@get",
		expected: checkgroup.ResultIsMember,
	}, {
		query:    "Role:b#perms@get",
		expected: checkgroup.ResultIsMember,
	}, { // This case will fail
		query:    "Role:a#perms@get",
		expected: checkgroup.ResultIsMember,
	}}

	t.Run("suite=testcases", func(t *testing.T) {
		ctx := context.Background()
		reg.Config(ctx).Set(config.KeyLimitMaxReadDepth, 10)
		e := check.NewEngine(reg)
		defer goleak.VerifyNone(t, goleak.IgnoreCurrent())

		for _, tc := range testCases {
			t.Run("case="+tc.query, func(t *testing.T) {
				rt := tupleFromString(t, tc.query)

				res := e.CheckRelationTuple(ctx, rt, 100)
				require.NoError(t, res.Err)
				t.Logf("tree:\n%s", res.Tree)
				assert.Equal(t, tc.expected.Membership, res.Membership)

				if len(tc.expectedPaths) > 0 {
					for _, path := range tc.expectedPaths {
						assertPath(t, path, res.Tree)
					}
				}
			})
		}
	})
}

Relevant log output

=== RUN   TestSubjectExpansion
time=2023-02-24T19:45:04+08:00 level=info msg=No tracer configured - skipping tracing setup audience=application service_name=Ory Keto service_version=testing
=== RUN   TestSubjectExpansion/suite=testcases
=== RUN   TestSubjectExpansion/suite=testcases/case=Role:d#perms@get
    /keto/internal/check/check_test.go:80: tree:
        ∋ Role:5d0ab373-34e6-5449-9217-196aa2ef5d76#perms@01338e40-ba98-5539-a9ee-856b0223c9b1️
=== RUN   TestSubjectExpansion/suite=testcases/case=Role:c#perms@get
    /keto/internal/check/check_test.go:80: tree:
=== RUN   TestSubjectExpansion/suite=testcases/case=Role:b#perms@get
    /keto/internal/check/check_test.go:80: tree:
=== RUN   TestSubjectExpansion/suite=testcases/case=Role:a#perms@get
    /keto/internal/check/check_test.go:80: tree:
    /keto/internal/check/check_test.go:81:
        	Error Trace:	/keto/internal/check/check_test.go:81
        	Error:      	Not equal:
        	            	expected: 1
        	            	actual  : 2
        	Test:       	TestSubjectExpansion/suite=testcases/case=Role:a#perms@get
--- FAIL: TestSubjectExpansion (0.02s)
    --- FAIL: TestSubjectExpansion/suite=testcases (0.00s)
        --- PASS: TestSubjectExpansion/suite=testcases/case=Role:d#perms@get (0.00s)
        --- PASS: TestSubjectExpansion/suite=testcases/case=Role:c#perms@get (0.00s)
        --- PASS: TestSubjectExpansion/suite=testcases/case=Role:b#perms@get (0.00s)
        --- FAIL: TestSubjectExpansion/suite=testcases/case=Role:a#perms@get (0.00s)
FAIL
FAIL	github.com/ory/keto/internal/check	0.811s

Relevant configuration

No response

Version

master

On which operating system are you observing this issue?

None

In which environment are you deploying?

None

Additional Context

No response