Sharing like Google Docs: private, shared with people, anyone with the link, public
A document starts private. Its owner shares it with people, hands out a link, or makes it public.
authz
type document = app.documents
owner : user = owner_id
viewer : user, link shared by share
editor : user shared by share
can share = owner
can edit = share or editor
can view = edit or viewer or {visibility = 'public'}
rules app.documents
select : view
insert : owner
update : edit
update owner_id, visibility : share
delete : share- Private is the absence of everything else: only
ownerholds. - Shared with people:
authz.share('document', 7, 'viewer', 'user', 4), or'editor'. - Anyone with the link:
viewermay be given tolink.authz.create_link('document', 7, 'viewer')returns a token, and a request that carries it setsauthz_ctx.linksto it for its transaction.authz.list_linksshows a document's links andauthz.revoke_linkturns one off. - Public:
{visibility = 'public'}is a condition on the row, true for everyone, signed in or not. update owner_id, visibility : share: an editor changes the text, and only the owner changes who sees it.
Tested
anyone in a test asks as nobody signed in:
authz
test "private, shared with a person, public"
user $bo cannot view document $diary
anyone cannot view document $diary
anyone can view document $blog
user $bo cannot edit document $blog
as user $ann allowed {SELECT authz.share('document', $diary, 'editor', 'user', $bo)}
user $bo can edit document $diary
as user $bo refused {UPDATE app.documents SET visibility = 'public' WHERE id = $diary}
as user $ann allowed {UPDATE app.documents SET visibility = 'public' WHERE id = $diary}
anyone can view document $diaryauthz
test "anyone with the link"
as user $bo refused {SELECT authz.create_link('document', $d, 'viewer')}
as user $ann allowed {SELECT authz.create_link('document', $d, 'viewer')}
as user $ann sees 1 {SELECT FROM authz.list_links('document', $d)}Try it
Open it in the playground: the tables, the policy and the tests, in your browser, with nothing to install. Or take the files of docs/cookbook/google-docs-sharing/ (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: sharing with teams, and shares that end, links from app code, the other recipes.