Sharing a row with a person or a team, for a while, and share links
shared by share makes a relation people give to each other at run time: whoever holds share on a document gives viewer or editor to a person, to a team's members, or to whoever holds a link.
authz
type document = app.documents
owner : user = owner_id
viewer : user, team#member, link shared by share
editor : user, team#member shared by share
can share = owner
can edit = share or editor
can view = edit or viewer- The words after the colon say who a relation may be given to:
user,team#member(a team's members),link(whoever holds a link). shared by sharenames the permission that giving it takes. Here only the owner shares; writecan share = owner or editorto let editors pass it on.- The app shares with
authz.share(), signed in as the person who shares, and the database checks them. A share can end, and start later:
authz
as user $ann allowed {SELECT authz.share('document', $d, 'viewer', 'user', $bo)}
as user $ann allowed {SELECT authz.share('document', $d, 'editor', 'team', $eng, 'member')}
as user $ann allowed {SELECT authz.share('document', $d, 'viewer', 'user', $bo, '', now() + interval '1 week', now() + interval '1 day')}authz.create_link('document', 7, 'viewer')returns a token. A request that carries it setsauthz_ctx.linksto it for its transaction, and holds what the link gives (using it from app code).
Tested
authz
test "sharing with a person and with a team"
user $bo cannot view document $d
as user $ann allowed {SELECT authz.share('document', $d, 'viewer', 'user', $bo)}
user $bo can view document $d
user $bo cannot edit document $d
as user $bo refused {SELECT authz.share('document', $d, 'editor', 'user', $bo)}
user $cy can edit document $d
as user $cy refused {DELETE FROM app.documents WHERE id = $d}authz
test "a share that starts later, and a link"
user $bo cannot view document $d
as user $ann allowed {SELECT authz.create_link('document', $d, 'viewer')}
as user $bo refused {SELECT authz.create_link('document', $d, 'viewer')}Try it
Open it in the playground: the tables, the policy and the test, in your browser, with nothing to install. Or take the files of docs/cookbook/sharing-and-links/ (schema.sql, policy.authz, tests.authz) and run rowstile dev. CI applies and tests them on every change (core/tests/cookbook.sh), and every line shown here is in those files.
More: shares, listing and taking back shares and links, the other recipes.