← Questions

Page permissions inherited down a workspace tree

0
NotionCodingLast asked Mar 2026

Pages in a workspace form a tree: every page except the top-level ones has a parent. Build the permission layer: give a user a role on a page, remove it, and answer whether a user can view or edit a page. A role on a page also applies to every page below it, unless a page closer down sets a role of its own for that user.

Interface

Unless you agree on a different interface with the interviewer, assume:

  • create_page(page_id: str, parent_id: str | None) -> None
  • set_role(user_id: str, page_id: str, role: str) -> None — role is "view", "edit" or "none". "edit" includes viewing. "none" blocks access inherited from above.
  • revoke(user_id: str, page_id: str) -> None — removes the user's role set on exactly this page, so the page inherits again.
  • can_view(user_id, page_id) -> bool and can_edit(user_id, page_id) -> bool — use the role set on the closest page, starting at page_id and walking up to the root. No role anywhere means no access.

Example

create_page("eng", None); create_page("plans", "eng"); create_page("q3", "plans")
set_role("ana", "eng", "view")
set_role("ana", "plans", "edit")
can_edit("ana", "q3")   -> True     # inherits edit from plans
can_edit("ana", "eng")  -> False
set_role("ana", "q3", "none")
can_view("ana", "q3")   -> False    # the closest role wins
can_view("ana", "plans") -> True
revoke("ana", "q3")
can_edit("ana", "q3")   -> True
revoke("ana", "plans")
can_edit("ana", "q3")   -> False
can_view("ana", "q3")   -> True     # back to view from eng

Constraints

  • Up to 10^5 pages and 10^5 users; trees can be deep. Checks are far more frequent than changes.

Clarifying questions

  • Does the closest role always win, or does the most permissive role on the path win?
  • Are there groups or workspace-wide roles, and how do they combine with a user's own role?
  • Can pages be moved to a new parent, and should permissions follow?
  • Is the page owner a special case?

What a strong answer covers

  • A parent map for pages and a map from (user, page) to role; a check walks up from the page and stops at the first role found: O(depth).
  • Why "closest wins" lets a child page take access away, and how a "most permissive wins" rule would behave instead.
  • Clear errors for unknown pages and invalid roles.
  • Tests for inheritance, override, revoke and pages with no roles at all.

Follow-ups

  • Make checks O(1) on deep trees: cache each user's effective role per page, and say what a set_role near the root must invalidate.
  • Add groups: a user's own role, then their groups' roles. What wins when they disagree?
  • Support move_page(page_id, new_parent_id), and list every page a user can view.
Write and test your solution herePython in your browser, the question's tests level by level, every submission kept for you.Sign in to start coding