Visibility phase 2: privacy-engine branches on viewer auth state
can_view_tree() now distinguishes anonymous vs authenticated non-members so the
four-level model is enforceable:
- public / unlisted → anyone, including anonymous (unlisted gated only by the
link, so the API must never *list* it)
- site_members → any authenticated account (denies anonymous)
- private → members only
Members (any role) always view; soft-deleted trees stay hidden from everyone.
person_visibility (living-person redaction) is unchanged.
Tests: a full can_view_tree matrix across {anonymous, logged-in non-member,
member} × {public, unlisted, site_members, private}, plus deleted-tree-hidden
and the site_members anon-vs-logged-in case. Adds `engine`/`db_session` fixtures
(refactored out of `client`) so the engine can be unit-tested directly,
including the anonymous path that has no HTTP endpoint yet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Justin Paul <justin@jpaul.me>
This commit is contained in:
@@ -45,8 +45,17 @@ async def can_view_tree(session: AsyncSession, *, user_id: uuid.UUID | None, tre
|
||||
if tree.deleted_at is not None:
|
||||
return False
|
||||
if await get_membership_role(session, user_id, tree.id) is not None:
|
||||
return True # members always (any role)
|
||||
# Non-members. Branch on the viewer's auth state:
|
||||
# public / unlisted → anyone, including anonymous (unlisted is gated only
|
||||
# by knowing the link, so the API must never *list* it).
|
||||
# site_members → any authenticated account on this instance.
|
||||
# private → no one.
|
||||
if tree.visibility in (TreeVisibility.public, TreeVisibility.unlisted):
|
||||
return True
|
||||
return tree.visibility in (TreeVisibility.public, TreeVisibility.unlisted)
|
||||
if tree.visibility == TreeVisibility.site_members:
|
||||
return user_id is not None
|
||||
return False
|
||||
|
||||
|
||||
async def can_edit_tree(session: AsyncSession, *, user_id: uuid.UUID | None, tree: Tree) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user