Add a folder-scoped Google Drive resource - #440
Open
ndisidore wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Devin Review found 1 potential issue.
3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
| let folder = await readFolderRoot(scope.folderId, id => api.getFile(id)); | ||
| return { | ||
| // The natural browser URL, not the internal `_resource` selector the grant is keyed on. | ||
| url: `https://drive.google.com/drive/folders/${encodeURIComponent(scope.folderId)}`, |
There was a problem hiding this comment.
🟡 Folder sharing requests wrong grant
describe() labels folder bindings with the shared-drive URL grammar. Collaborator setup then requests the wrong resource grant and broader permissions.
Prompt for agents
Folder bindings use an internal _resource URL as their grant identity, but GoogleDriveGatekeeperImpl.describe returns the natural /drive/folders/:id URL. The Workshop persists ResourceDescription.url and ObserverConfigModal resolves that URL against supported resource patterns when deciding which grant a collaborator needs. Because /drive/folders/:id is the shared-drive pattern, folder bindings are classified as shared drives and request drive.readonly. Preserve the natural browser URL for display while giving observer grant resolution an unambiguous folder resource identity. This likely requires carrying or using the original typeUrlPattern or creation resource URL rather than inferring the grant type from ResourceDescription.url.
Was this helpful? React with 👍 or 👎 to provide feedback.
Confines the existing read-only GoogleDriveSession API to one selected folder's current descendant subtree, for both My Drive folders and ordinary subfolders inside a shared drive. A shared drive's own root stays with the Shared Drive resource. Drive v3 offers no folder corpus, no folder-scoped token, and no recursive ancestor predicate -- `'<id>' in parents` means direct children only -- so membership is proved in the gatekeeper. drive-folder-scope.ts walks each candidate's parent chain upward through freshly batched files.get metadata, level by level, admitting only acyclic same-domain chains of live folders that reach the root within Drive's 101-hop nesting limit, then re-reads every node on the surviving paths immediately before disclosure. Nothing is cached across the operation that proved it: a hierarchy change rotates no credential and bumps no cache generation. The grant identity is an internal `/_resource/folder/:folderId` path rather than the natural browser URL, because `/drive/folders/:driveId` is already the shared drive's permanent identity and its pattern leaves the query component wildcard -- a query-qualified variant would match both resources and make resource selection order-dependent. describe() still reports the natural URL for the UI. Folder-derived Doc and Sheet children now revalidate: DriveSessionCore .nativeRead() re-proves ancestry and the exact native MIME type before the provider is contacted, re-checks the proved chain before any approval, and discards the fetched value if either fails. Drive has no ancestry-plus-content transaction, so a move landing after that final check still returns; the next read denies, and the method says so. CursorPager's authorize() now takes `exhausted` and its page budget is maxProviderPagesPerCall: reaching the bound authorizes the empty nonterminal page and returns [] rather than throwing, so a folder cursor can filter a whole page without claiming there are no results. Only an exhausted cursor reaches the empty-search path, which now fences observer admission through ObserverTracker.prepareWithheld() -- a withheld read registers no tracked set, so addObserver would otherwise verify a candidate against nothing. The Drive observer denial no longer names a file ID.
ndisidore
force-pushed
the
feat/gk-google-drive-folder
branch
from
September 3, 2026 22:56
24a03b3 to
7256fd6
Compare
Preview:
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a fourth Google Drive resource, scoped to one folder and everything currently
beneath it, read-only. It covers a folder in My Drive, including one someone else
shared with you, and an ordinary subfolder inside a shared drive; a shared drive's
own root stays with the existing Shared Drive resource. It requests the same three
read-only scopes as the account and exact-file resources rather than the wider
drive.readonlythat Shared Drive needs.Folder-derived Doc and Sheet sessions re-prove ancestry on every method call, not only
at open, so a file moved out of the subtree stops answering through a session that is
already open. Drive has no ancestry-plus-content transaction, so a move landing after
the final check still returns and the next read denies.