Expand description
Drive move visibility-diff algorithm — the security-critical core of
drive move’s safety gate (ADR-0070).
Deliberately pure: zero DriveClient/network dependency, and zero
dependency on crate::drive::file_move (or any other engine module) —
this module classifies an already-fetched set of permission snapshots,
so the whole file is unit-testable with no wiremock at all.
DrivePermission fetching lives in crate::drive::permissions_api;
orchestration (which files to fetch, calling classify, gating the
move) lives in crate::drive::file_move.
§The algorithm
Drive’s permissions.list(fileId) returns a file’s full effective
permission set (direct + inherited, merged) — but the
permissionDetails[].inherited flag that would let us split “direct”
from “inherited” is only populated for Shared Drive items, not My Drive
files. So instead of reading that split off the file directly, it’s
derived by subtraction, from three snapshots the caller fetches:
before = principal_set(permissions.list(file_id))
current_parent = principal_set(permissions.list(union of file's current parent(s))) // ∅ if none
dest = principal_set(permissions.list(dest_folder_id))
direct_on_file = before − current_parent // what's granted on the file, not inherited
after = direct_on_file ∪ dest
added = after − before // visibility increase: new principals gain access
removed = before − after // visibility decrease: principals lose accessMulti-parent legacy files: the caller unions permissions across every
current parent, not just the first, before calling diff_visibility.
An orphan/root file with no current parent passes an empty
current_parent_perms slice, which degenerates correctly to “everything
on the file counts as direct.”
§Known limitation: shadowed grants
If a principal has both a direct grant on the file and inherited
access via the current parent (a “shadowed” grant), the subtraction
can’t distinguish them: direct_on_file won’t include that principal
(it’s in current_parent too), so if dest also doesn’t grant it,
after won’t include it either — diff_visibility reports it as
losing access even though it actually keeps it via the shadowed direct
grant, invisible to this subtraction.
This is the safe failure direction: it can only produce a false
positive on removed (an unnecessary --allow-visibility-decrease
requirement), never a false negative on added — direct_on_file ⊆ before always holds, and dest enters after unfiltered, so a real
visibility increase is always caught. Accepted, not a bug to fix later.
Structs§
- Block
Reasons - Which safety gate(s) block a move.
- Move
Gate Flags - The three independent, per-move opt-ins
classifygates on. - Visibility
Diff - The result of diffing a file’s visibility before/after a hypothetical move — see the module doc for the algorithm and its known limitation.
Enums§
- Principal
- A Drive permission’s identity, independent of
role.
Functions§
- classify
- Classifies whether a move is clear to proceed.
- diff_
visibility - Computes the visibility diff a move from the file’s current parent(s) to a destination folder would produce, given three already-fetched permission snapshots (see the module doc’s algorithm).
- principal_
set - Builds the set of principals a permission list grants access to.