Skip to content

Commit

Permalink
Merge pull request #1925 from Permify/entity-filter-refactor
Browse files Browse the repository at this point in the history
test(internal): add test case for linked schema entrance validation
  • Loading branch information
tolgaOzen authored Jan 17, 2025
2 parents c910e05 + f616e1a commit aad5f48
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/api-reference/apidocs.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Permify API",
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
"version": "v1.2.6",
"version": "v1.2.7",
"contact": {
"name": "API Support",
"url": "https://github.com/Permify/permify/issues",
Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference/openapiv2/apidocs.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Permify API",
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
"version": "v1.2.6",
"version": "v1.2.7",
"contact": {
"name": "API Support",
"url": "https://github.com/Permify/permify/issues",
Expand Down
9 changes: 1 addition & 8 deletions internal/engines/entityFilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,7 @@ func (engine *EntityFilter) attributeEntrance(
pagination database.CursorPagination
)

// Determine the pagination settings based on the entity type in the request.
// If the entity type matches the target entrance, use cursor pagination with sorting by "entity_id".
// Otherwise, use the default pagination settings.
if request.GetEntrance().GetType() == entrance.TargetEntrance.GetType() {
pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id"))
} else {
pagination = database.NewCursorPagination()
}
pagination = database.NewCursorPagination(database.Cursor(request.GetCursor()), database.Sort("entity_id"))

// Query the relationships using the specified pagination settings.
// The context tuples are filtered based on the provided filter.
Expand Down
143 changes: 143 additions & 0 deletions internal/engines/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3060,6 +3060,149 @@ var _ = Describe("lookup-entity-engine", func() {
})
})

PropagationAcrossEntitiesEntityFilter := `
entity user {}
entity aaa {
relation role__admin @user
permission ccc__read = role__admin
}
entity bbb {
relation resource__aaa @aaa
relation role__admin @user
attribute attr__is_public boolean
permission ccc__read = role__admin or attr__is_public
}
entity ccc {
relation resource__aaa @aaa
relation resource__bbb @bbb
permission ccc__read = resource__aaa.ccc__read or resource__bbb.ccc__read
}`

Context("Propagation Across Entities: Entity Filter", func() {
It("Drive Sample: Case 1", func() {
db, err := factories.DatabaseFactory(
config.Database{
Engine: "memory",
},
)

Expect(err).ShouldNot(HaveOccurred())

conf, err := newSchema(PropagationAcrossEntitiesEntityFilter)
Expect(err).ShouldNot(HaveOccurred())

schemaWriter := factories.SchemaWriterFactory(db)
err = schemaWriter.WriteSchema(context.Background(), conf)

Expect(err).ShouldNot(HaveOccurred())

type filter struct {
entityType string
subject string
assertions map[string][]string
}

tests := struct {
relationships []string
attributes []string
filters []filter
}{
relationships: []string{
"aaa:a1#role__admin@user:u1",
"bbb:b1#resource__aaa@aaa:a1",
"ccc:c1#resource__aaa@aaa:a1",
"ccc:c1#resource__bbb@bbb:b1",
},
attributes: []string{
"bbb:b1$attr__is_public|boolean:true",
},
filters: []filter{
{
entityType: "ccc",
subject: "user:u1",
assertions: map[string][]string{
"ccc__read": {"c1"},
},
},
},
}

schemaReader := factories.SchemaReaderFactory(db)
dataReader := factories.DataReaderFactory(db)
dataWriter := factories.DataWriterFactory(db)

checkEngine := NewCheckEngine(schemaReader, dataReader)

lookupEngine := NewLookupEngine(
checkEngine,
schemaReader,
dataReader,
)

invoker := invoke.NewDirectInvoker(
schemaReader,
dataReader,
checkEngine,
nil,
lookupEngine,
nil,
)

checkEngine.SetInvoker(invoker)

var tuples []*base.Tuple

for _, relationship := range tests.relationships {
t, err := tuple.Tuple(relationship)
Expect(err).ShouldNot(HaveOccurred())
tuples = append(tuples, t)
}

var attributes []*base.Attribute

for _, attr := range tests.attributes {
a, err := attribute.Attribute(attr)
Expect(err).ShouldNot(HaveOccurred())
attributes = append(attributes, a)
}

_, err = dataWriter.Write(context.Background(), "t1", database.NewTupleCollection(tuples...), database.NewAttributeCollection(attributes...))
Expect(err).ShouldNot(HaveOccurred())

for _, filter := range tests.filters {
ear, err := tuple.EAR(filter.subject)
Expect(err).ShouldNot(HaveOccurred())

subject := &base.Subject{
Type: ear.GetEntity().GetType(),
Id: ear.GetEntity().GetId(),
Relation: ear.GetRelation(),
}

for permission, res := range filter.assertions {
response, err := invoker.LookupEntity(context.Background(), &base.PermissionLookupEntityRequest{
TenantId: "t1",
EntityType: filter.entityType,
Subject: subject,
Permission: permission,
Metadata: &base.PermissionLookupEntityRequestMetadata{
SnapToken: token.NewNoopToken().Encode().String(),
SchemaVersion: "",
Depth: 100,
},
})

Expect(err).ShouldNot(HaveOccurred())
Expect(response.GetEntityIds()).Should(Equal(res))
}
}
})
})

driveSchemaSubjectFilter := `
entity user {}
Expand Down
2 changes: 1 addition & 1 deletion internal/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var Identifier = ""
*/
const (
// Version is the last release of the Permify (e.g. v0.1.0)
Version = "v1.2.6"
Version = "v1.2.7"
)

// Function to create a single line of the ASCII art with centered content and color
Expand Down
68 changes: 68 additions & 0 deletions internal/schema/linkedSchema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,5 +1181,73 @@ var _ = Describe("linked schema", func() {
},
}))
})

It("Case 23", func() {
sch, err := parser.NewParser(`
entity user {}
entity aaa {
relation role__admin @user
permission ccc__read = role__admin
}
entity bbb {
relation resource__aaa @aaa
relation role__admin @user
attribute attr__is_public boolean
permission ccc__read = role__admin or attr__is_public
}
entity ccc {
relation resource__aaa @aaa
relation resource__bbb @bbb
permission ccc__read = resource__aaa.ccc__read or resource__bbb.ccc__read
}
`).Parse()

Expect(err).ShouldNot(HaveOccurred())

c := compiler.NewCompiler(true, sch)
a, _, _ := c.Compile()

g := NewLinkedGraph(NewSchemaFromEntityAndRuleDefinitions(a, nil))

ent, err := g.LinkedEntrances(&base.Entrance{
Type: "ccc",
Value: "ccc__read",
}, &base.Entrance{
Type: "user",
Value: "",
})

Expect(err).ShouldNot(HaveOccurred())
Expect(ent).Should(Equal([]*LinkedEntrance{
{
Kind: RelationLinkedEntrance,
TargetEntrance: &base.Entrance{
Type: "aaa",
Value: "role__admin",
},
TupleSetRelation: "",
},
{
Kind: RelationLinkedEntrance,
TargetEntrance: &base.Entrance{
Type: "bbb",
Value: "role__admin",
},
TupleSetRelation: "",
},
{
Kind: AttributeLinkedEntrance,
TargetEntrance: &base.Entrance{
Type: "bbb",
Value: "attr__is_public",
},
TupleSetRelation: "",
},
}))
})
})
})
2 changes: 1 addition & 1 deletion pkg/pb/base/v1/openapi.pb.go

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

2 changes: 1 addition & 1 deletion proto/base/v1/openapi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
title: "Permify API";
description: "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.";
version: "v1.2.6";
version: "v1.2.7";
contact: {
name: "API Support";
url: "https://github.com/Permify/permify/issues";
Expand Down

0 comments on commit aad5f48

Please sign in to comment.