Skip to main content

Module roles

Module roles 

Source
Expand description

The role graph.

A user’s roles are the roles they belong to directly, plus every role that transitively contains one of those. Upstream computes it in Auth.prototype._loadRoles (Auth.js:297-336) and _getAllRolesNamesForRoleIds (Auth.js:393-428), and this is a port of that, not a reimplementation of the idea.

Unauthenticated against storage, deliberately. Upstream queries _Role under master(this.config) in both directions (Auth.js:283, :383). It has to: the role names are an input to every later ACL and CLP decision, so gating them on one would be circular. What keeps that narrow is that nothing here takes a client query. The inputs are a user objectId and a set of role objectIds this module produced itself, and the output is a list of role names.

No cache, on purpose. Upstream caches the expanded list per user with a 5 second TTL and clears the whole role cache on any _Role write (RestWrite.js:1565-1570). The invalidation is the load-bearing half: a cache that keeps the TTL and drops the invalidation serves stale authorization for up to five seconds after a role membership is revoked, which is worse than not caching at all. Adding one is 0.3.0 work and it lands with the invalidation or not at all. Until then a request with deep role nesting issues two queries per level of the graph.

Relation reads go straight to the join collections. _Role.users and _Role.roles are Relation fields, which have no column at all: membership lives in _Join:users:_Role and _Join:roles:_Role, whose documents are exactly {relatedId, owningId} (DatabaseController.js:418-420, :794-806) and which have no _SCHEMA row. That is why the schema comes from join_schema rather than from storage, and why nothing here ever writes one.

Structs§

RoleName
A role name, without the role: prefix.

Enums§

RolePrincipal
Who is asking.

Functions§

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