Skip to main content

expand_roles

Function expand_roles 

Source
pub async fn expand_roles<S: StorageAdapter>(
    storage: &S,
    principal: RolePrincipal<'_>,
) -> Result<Vec<RoleName>, ParseError>
Expand description

Every role a principal holds, direct and transitive, deduplicated.

The order is upstream’s: direct role names first, in the order the _Role rows came back, then each level of ancestors in turn. Duplicates are dropped on first sight, which is what [...new Set(names)] does (Auth.js:402).

The traversal cuts cycles, it does not reject them. Upstream marks each role objectId into queriedRoles as it builds the next frontier and filters the frontier against it (Auth.js:393-398), so A -> B -> A terminates with both names and no error. A cycle check that raised would be a behavior change, and no cycle check at all is an infinite loop. The marking is the whole mechanism; see a_cycle_terminates_and_returns_both_names.

Depth is unbounded and the cost is per level, not per role. Each level is one read of the join collection followed by one read of _Role, regardless of how wide the frontier is. A per-role query would turn a wide role graph into a query storm.