pub struct GroupGraph { /* private fields */ }Expand description
A loaded, in-memory snapshot of the groups/group_members tables, and the closure resolver
over it. Sync and infallible once built: every method here is a walk over an already-loaded
snapshot, never a query.
Implementations§
Source§impl GroupGraph
impl GroupGraph
Sourcepub fn from_rows(
groups: impl IntoIterator<Item = String>,
members: impl IntoIterator<Item = (String, String)>,
) -> Result<GroupGraph, Error>
pub fn from_rows( groups: impl IntoIterator<Item = String>, members: impl IntoIterator<Item = (String, String)>, ) -> Result<GroupGraph, Error>
Builds a graph from (name) rows out of groups and (group_name, member) rows out of
group_members. Re-runs the name charset and valid_selector checks the way
AudienceGrants::from_rows does, so a row that slipped past the tables’ own CHECK
constraints (e.g. via a direct psql session) fails the snapshot load rather than
reaching a decision.
Sourcepub fn group_names(&self) -> impl Iterator<Item = &String>
pub fn group_names(&self) -> impl Iterator<Item = &String>
Every known group name, sorted.
Sourcepub fn contains_group(&self, name: &str) -> bool
pub fn contains_group(&self, name: &str) -> bool
Whether name is a known group.
Sourcepub fn closure(&self, email: Option<&str>) -> Vec<String>
pub fn closure(&self, email: Option<&str>) -> Vec<String>
The caller’s resolved, transitive group membership: a breadth-first walk upward from
the caller, seeded at the groups listed under the selectors * and user:<email> (when
email is Some). Returned sorted, deduplicated. Sync and infallible: the graph is an
already-loaded snapshot.
Sourcepub fn has_wildcard_admin(&self) -> bool
pub fn has_wildcard_admin(&self) -> bool
true when the wildcard selector * reaches ADMINS_GROUP – directly (('admins', '*')) or through nesting. Reuses the same upward walk as Self::closure, seeded at *
alone (no caller email).
Sourcepub fn any_principal_reaches(&self, target: &str) -> bool
pub fn any_principal_reaches(&self, target: &str) -> bool
true when target is reachable from some principal – the wildcard * selector or
any user:<email> selector present in the snapshot – directly or through nesting.
Generalizes Self::has_wildcard_admin (which seeds the walk from * alone) to seed
from every base selector on record, so a caller can check “would target still be
reachable by anyone” rather than “by * specifically” – e.g. before removing a
membership that would strand ADMINS_GROUP behind a user-only or nested-only path.
Sourcepub fn nesting_would_cycle(&self, group: &str, nested: &str) -> bool
pub fn nesting_would_cycle(&self, group: &str, nested: &str) -> bool
Whether adding group:nested as a member of group would create a cycle: nested == group, or nested is already reachable upward from group (a walk seeded at group
reaches it – i.e. group is already, directly or transitively, nested into nested).
Trait Implementations§
Source§impl Clone for GroupGraph
impl Clone for GroupGraph
Source§fn clone(&self) -> GroupGraph
fn clone(&self) -> GroupGraph
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for GroupGraph
impl Debug for GroupGraph
Source§impl Default for GroupGraph
impl Default for GroupGraph
Source§fn default() -> GroupGraph
fn default() -> GroupGraph
Auto Trait Implementations§
impl Freeze for GroupGraph
impl RefUnwindSafe for GroupGraph
impl Send for GroupGraph
impl Sync for GroupGraph
impl Unpin for GroupGraph
impl UnsafeUnpin for GroupGraph
impl UnwindSafe for GroupGraph
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].