feat(#571): the grant API, its own policy switch, and /shared goes live #575
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix-571"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Backend half of #571.
/sharedstops being inert: grants can now be created, listed and revoked, and the overlay is wired to the share store.The endpoints
Registered alongside the link routes, because a grant is a share record with the other half filled in. Paths are stored resolved to the backend path, exactly like links, since that is what
RoleForPathand the overlay look up.Recipients cannot re-share — enforced, not intended
This is the one that would have been a real hole. The overlay resolves
/shared/alice/q3.pdfto Alice's real backend path, which is correct for reading and is exactly what would let BobPOSTa grant on Alice's file and become a second grantor of it.scope.Driver.Delegatedreports whether a path was reached through someone else's grant, andresolveOwnedrefuses before anything is written.TestGrantCreateRefusesToReShareasserts both the 403 and that the store stayed empty.Two switches, because two risks
ShareLinksDisabledsays public share links are turned off on this server — a statement about the public internet. It does not govern grants, andTestPublicLinkPolicyDoesNotGovernGrantspins that: with links disabled, password required and uploads forbidden, sharing a file with a colleague still works. Internal sharing getsShareInternalDisabled, stored negative like its neighbour so an instance upgrading into the field keeps sharing on.A link is not a grant
GrantKeygives grants their own key space (g:<id>), so a link's token cannot be revoked through the grant route and a link never appears in a grant listing. Both fenced.Wiring
share.GrantsForfans in everything addressed to a principal — named directly, or through any of their groups — and deduplicates by id, because being both is the ordinary case for anyone on a team and the overlay would otherwise show the same file twice under the same owner. That logic lives ininternal/sharewhere it is tested;main.gokeeps only the mapping intoscope.Grant, via a newscope.GrantsFuncso the composition root declares no type of its own.The audit callback uses literal verbs in a switch rather than passing the verb through. That keeps the #433 registry scanner able to see them, and it means an unregistered verb cannot be emitted from
main.goat all.share-grantandshare-grant-revokeare registered now that they have call sites.One deliberate omission: the audit event carries no owner field, because
vpathis/shared/<owner>/...— the record already names the owner.Not in this PR
The panel itself, and the non-admin recipient picker.
GET /api/v1/admin/groups/candidatesisrequireAdmin, so it cannot back a picker every user needs; that becomes a search-only/api/v1/recipients(min 2 characters, capped, no blank-query enumeration) in the next slice, together with the admin toggle for the new switch.Red witnessed on the runner for every test here before any of it existed.