Skip to content

Commit 9956044

Browse files
authored
Merge pull request #1711 from Permify/subject-filter
feat: subject filter cursor pagination
2 parents e5b4f5f + fe427d0 commit 9956044

File tree

7 files changed

+16
-52
lines changed

7 files changed

+16
-52
lines changed

docs/api-reference/apidocs.swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "Permify API",
55
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
6-
"version": "v1.1.6",
6+
"version": "v1.1.7",
77
"contact": {
88
"name": "API Support",
99
"url": "https://github.com/Permify/permify/issues",

docs/api-reference/openapiv2/apidocs.swagger.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "Permify API",
55
"description": "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.",
6-
"version": "v1.1.6",
6+
"version": "v1.1.7",
77
"contact": {
88
"name": "API Support",
99
"url": "https://github.com/Permify/permify/issues",

internal/engines/lookup.go

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -240,44 +240,14 @@ func (engine *LookupEngine) LookupSubject(ctx context.Context, request *base.Per
240240
}, nil
241241
}
242242

243-
start := ""
244-
245243
// Sort the IDs
246244
sort.Strings(ids)
247245

248-
// Handle continuous token if present
249-
if request.GetContinuousToken() != "" {
250-
var t database.ContinuousToken
251-
t, err := utils.EncodedContinuousToken{Value: request.GetContinuousToken()}.Decode()
252-
if err != nil {
253-
return nil, err
254-
}
255-
start = t.(utils.ContinuousToken).Value
256-
}
257-
258-
// Since the incoming 'ids' are already filtered based on the continuous token,
259-
// there is no need to decode or handle the continuous token manually.
260-
// The startIndex is initialized to 0.
261-
startIndex := 0
262-
263-
if start != "" {
264-
// Locate the position in the sorted list where the ID equals or exceeds the token value
265-
for i, id := range ids {
266-
if id >= start {
267-
startIndex = i
268-
break
269-
}
270-
}
271-
}
272-
273-
// Convert size to int for compatibility with startIndex
246+
// Convert page size to int for compatibility with startIndex
274247
pageSize := int(size)
275248

276-
// Calculate the end index based on the page size
277-
end := startIndex + pageSize
278-
if end > len(ids) {
279-
end = len(ids)
280-
}
249+
// Determine the end index based on the page size and total number of IDs
250+
end := min(pageSize, len(ids))
281251

282252
// Generate the next continuous token if there are more results
283253
if end < len(ids) {
@@ -288,8 +258,8 @@ func (engine *LookupEngine) LookupSubject(ctx context.Context, request *base.Per
288258

289259
// Return the paginated list of IDs
290260
return &base.PermissionLookupSubjectResponse{
291-
SubjectIds: ids[startIndex:end], // Slice the IDs based on pagination
292-
ContinuousToken: ct, // Return the next continuous token
261+
SubjectIds: ids[:end], // Slice the IDs based on pagination
262+
ContinuousToken: ct, // Return the next continuous token
293263
}, nil
294264
}
295265

internal/engines/subjectFilter.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -429,15 +429,15 @@ func (engine *SubjectFilter) subjectFilterDirectRelation(
429429
// NewContextualRelationships() creates a ContextualRelationships instance from tuples in the request.
430430
// QueryRelationships() then uses the filter to find and return matching relationships.
431431
var cti *database.TupleIterator
432-
cti, err = storageContext.NewContextualTuples(request.GetContext().GetTuples()...).QueryRelationships(filter, database.NewCursorPagination())
432+
cti, err = storageContext.NewContextualTuples(request.GetContext().GetTuples()...).QueryRelationships(filter, database.NewCursorPagination(database.Cursor(request.GetContinuousToken()), database.Sort("subject_id")))
433433
if err != nil {
434434
return subjectFilterEmpty(), err
435435
}
436436

437437
// Query the relationships for the entity in the request.
438438
// TupleFilter helps in filtering out the relationships for a specific entity and a permission.
439439
var rit *database.TupleIterator
440-
rit, err = engine.dataReader.QueryRelationships(ctx, request.GetTenantId(), filter, request.GetMetadata().GetSnapToken(), database.NewCursorPagination())
440+
rit, err = engine.dataReader.QueryRelationships(ctx, request.GetTenantId(), filter, request.GetMetadata().GetSnapToken(), database.NewCursorPagination(database.Cursor(request.GetContinuousToken()), database.Sort("subject_id")))
441441
if err != nil {
442442
return subjectFilterEmpty(), err
443443
}
@@ -517,10 +517,10 @@ func (engine *SubjectFilter) subjectFilterDirectRelation(
517517
// setChild generates a SubjectFilterFunction by applying a SubjectFilterCombiner
518518
// to a set of child permission lookups, given a request and a list of Child objects.
519519
func (engine *SubjectFilter) setChild(
520-
ctx context.Context, // The context for carrying out the operation
520+
ctx context.Context, // The context for carrying out the operation
521521
request *base.PermissionLookupSubjectRequest, // The request containing parameters for lookup
522-
children []*base.Child, // The children of a particular node in the permission schema
523-
combiner SubjectFilterCombiner, // A function to combine the results from multiple lookup functions
522+
children []*base.Child, // The children of a particular node in the permission schema
523+
combiner SubjectFilterCombiner, // A function to combine the results from multiple lookup functions
524524
) SubjectFilterFunction {
525525
var functions []SubjectFilterFunction // Array of functions to store lookup functions for each child
526526

@@ -795,13 +795,7 @@ func subjectFilterIntersection(ctx context.Context, functions []SubjectFilterFun
795795
// If wildcard was encountered, we exclude the IDs in `excludedIds`
796796
if encounteredWildcard {
797797
if len(commonIds) == 0 {
798-
// No specific common IDs were found, so all are included except exclusions
799-
finalRes := []string{ALL}
800-
if len(excludedIds) > 0 {
801-
exclusions := "-" + strings.Join(excludedIds, ",")
802-
return []string{finalRes[0] + exclusions}, nil
803-
}
804-
return []string{ALL}, nil
798+
return []string{}, nil
805799
}
806800

807801
// Exclude IDs from commonIds that are in excludedIds

internal/info.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var Identifier = ""
2323
*/
2424
const (
2525
// Version is the last release of the Permify (e.g. v0.1.0)
26-
Version = "v1.1.6"
26+
Version = "v1.1.7"
2727
)
2828

2929
// Function to create a single line of the ASCII art with centered content and color

pkg/pb/base/v1/openapi.pb.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/base/v1/openapi.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
99
info: {
1010
title: "Permify API";
1111
description: "Permify is an open source authorization service for creating fine-grained and scalable authorization systems.";
12-
version: "v1.1.6";
12+
version: "v1.1.7";
1313
contact: {
1414
name: "API Support";
1515
url: "https://github.com/Permify/permify/issues";

0 commit comments

Comments
 (0)