-
Notifications
You must be signed in to change notification settings - Fork 21
feat: add continuation_token to ListObjects request and response #238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1019,6 +1019,15 @@ message ListObjectsRequest { | |||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // Controls the consistency preference for this request. Default value is UNSPECIFIED, which will have the same behavior as MINIMIZE_LATENCY. | ||||||||||||||||||||||||||||||||||||||||||||||
| ConsistencyPreference consistency = 8 [(validate.rules).enum.defined_only = true]; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // An opaque token used to continue paginated results. If provided, the server will | ||||||||||||||||||||||||||||||||||||||||||||||
| // resume returning objects from where the previous request left off. This allows | ||||||||||||||||||||||||||||||||||||||||||||||
| // clients to retrieve all accessible objects even when the result set is large or | ||||||||||||||||||||||||||||||||||||||||||||||
| // when the server deadline is reached before returning all results. | ||||||||||||||||||||||||||||||||||||||||||||||
| string continuation_token = 9 [ | ||||||||||||||||||||||||||||||||||||||||||||||
| json_name = "continuation_token", | ||||||||||||||||||||||||||||||||||||||||||||||
| (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "An opaque token used to continue paginated results from a previous ListObjects call."} | ||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1022
to
+1030
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Add input validation for request continuation_token. Match existing token constraints (size + base64url) to harden input and align APIs. Apply: string continuation_token = 9 [
json_name = "continuation_token",
- (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "An opaque token used to continue paginated results from a previous ListObjects call."}
+ (validate.rules).string.max_bytes = 5120,
+ (validate.rules).string.pattern = "^$|^[A-Za-z0-9-_]+={0,2}$",
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+ description: "An opaque token used to continue paginated results from a previous ListObjects call."
+ example: "\"eyJwayI6Ik...==\""
+ }
];📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| message ListObjectsResponse { | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1027,6 +1036,14 @@ message ListObjectsResponse { | |||||||||||||||||||||||||||||||||||||||||||||
| (google.api.field_behavior) = REQUIRED, | ||||||||||||||||||||||||||||||||||||||||||||||
| (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {example: "[\"document:roadmap\",\"document:planning\"]"} | ||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // An opaque token that can be passed to a subsequent ListObjects call to continue | ||||||||||||||||||||||||||||||||||||||||||||||
| // retrieving results. If empty, all accessible objects have been returned. | ||||||||||||||||||||||||||||||||||||||||||||||
| // A non-empty token indicates that more results may be available. | ||||||||||||||||||||||||||||||||||||||||||||||
| string continuation_token = 2 [ | ||||||||||||||||||||||||||||||||||||||||||||||
| json_name = "continuation_token", | ||||||||||||||||||||||||||||||||||||||||||||||
| (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "An opaque token to continue paginated results. Empty if all results have been returned."} | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "An opaque token to continue paginated results. Empty if all results have been returned."} | |
| (validate.rules).string = { | |
| max_bytes: 5120 | |
| pattern: "^$|^[A-Za-z0-9-_]+={0,2}$" | |
| }, | |
| (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { | |
| description: "An opaque token to continue paginated results. Empty if all results have been returned." | |
| example: "\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"" | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Make response continuation_token required + validated.
Keep it always present (empty when complete) and validate like other paginated responses.
Apply:
string continuation_token = 2 [
json_name = "continuation_token",
- (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "An opaque token to continue paginated results. Empty if all results have been returned."}
+ (google.api.field_behavior) = REQUIRED,
+ (validate.rules).string.max_bytes = 5120,
+ (validate.rules).string.pattern = "^$|^[A-Za-z0-9-_]+={0,2}$",
+ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
+ description: "An opaque token to continue paginated results. Empty if all results have been returned."
+ example: "\"eyJwayI6Ik...==\""
+ }
];🤖 Prompt for AI Agents
In openfga/v1/openfga_service.proto around lines 1039–1046, the
continuation_token field must be made required-and-validated: change the
declaration to use presence-aware proto3 (make it "optional string
continuation_token = 2" with the same json_name) and add the same pgv validation
options used by other paginated responses (the validate.rules string block used
elsewhere) so the field is always present (empty string when no more results)
and rejected if omitted; also update any server-side request handling/validation
to enforce presence consistent with other list responses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
continuation_tokenfield inListObjectsRequestis missing validation rules that are consistently applied to continuation tokens across the codebase. Other request types (e.g.,ReadRequest,ReadAuthorizationModelsRequest,ReadChangesRequest) include:(validate.rules).string.max_bytes = 5120- to limit token size(validate.rules).string.pattern = "^$|^[A-Za-z0-9-_]+={0,2}$"- to validate base64url encoding formatAdditionally, the OpenAPI annotation should include an example field with a sample token value (e.g.,
"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==").Example:
string continuation_token = 9 [ json_name = "continuation_token", (validate.rules).string.max_bytes = 5120, (validate.rules).string.pattern = "^$|^[A-Za-z0-9-_]+={0,2}$", (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { description: "An opaque token used to continue paginated results from a previous ListObjects call." example: "\"eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==\"" } ];