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§
- Role
Name - A role name, without the
role:prefix.
Enums§
- Role
Principal - Who is asking.
Functions§
- expand_
roles - Every role a principal holds, direct and transitive, deduplicated.