pub struct AllowlistAspect { /* private fields */ }Expand description
Identity-based allowlist aspect.
Admits a call when the supplied identity string is present in a
configured allowlist, optionally honoring a wildcard entry ("*") and an
optional normalization hook for identity comparison.
This shape recurs across messaging-channel integrations in real
codebases: each channel maintains its own list of who is permitted to
talk to the bot. The classical role-based AuthorizationAspect does
not fit because there are no roles — there is a set of literal identity
strings and a yes/no decision.
§Example
use aspect_std::AllowlistAspect;
let policy = AllowlistAspect::new(["user_a".to_string(), "user_b".to_string()]);
assert!(policy.is_allowed("user_a"));
assert!(!policy.is_allowed("intruder"));
// Wildcard.
let open = AllowlistAspect::new(["*".to_string()]);
assert!(open.is_allowed("anyone"));
// Empty list = deny everyone.
let closed = AllowlistAspect::new(Vec::<String>::new());
assert!(!closed.is_allowed("user_a"));§Normalization
Some identity spaces require canonicalization before comparison: phone
numbers (E.164), emails (case-insensitive), Telegram usernames
(@-stripped), Matrix MXIDs (case-insensitive). Pass a normalization
function via AllowlistAspect::with_normalizer.
§Mutability
The allowlist is stored behind an RwLock and can be amended at runtime
via AllowlistAspect::add / AllowlistAspect::set. This matches
runtime-pairing flows where new identities are added without restart.
Implementations§
Source§impl AllowlistAspect
impl AllowlistAspect
Sourcepub fn new<I, S>(entries: I) -> Self
pub fn new<I, S>(entries: I) -> Self
Build an allowlist aspect from an initial set of entries.
The wildcard entry "*" admits everyone. An empty list denies
everyone (fail-closed). Identity comparison is byte-equal by
default; see AllowlistAspect::with_normalizer for case-
insensitive or canonicalized comparison.
Sourcepub fn with_normalizer<F>(self, normalizer: F) -> Self
pub fn with_normalizer<F>(self, normalizer: F) -> Self
Attach a normalization function applied to both the allowlist entries and the queried identity before comparison.
Consumes and returns self. The normalizer must be deterministic and
referentially transparent: calling it twice on the same input must
produce identical output.
Mutually exclusive with AllowlistAspect::with_matcher: if a
matcher is installed, the normalizer is bypassed because the
matcher owns the entry-vs-identity comparison end-to-end.
Sourcepub fn with_matcher<F>(self, matcher: F) -> Self
pub fn with_matcher<F>(self, matcher: F) -> Self
Attach a custom match predicate (entry, identity) -> bool that
replaces the default byte-equal (or normalized-equal) comparison.
Consumes and returns self. The wildcard "*" and empty-list
short-circuits still apply before the matcher runs — the matcher
is only consulted for non-"*" entries against a non-empty list.
The matcher must be referentially transparent.
Use this when entries and identities are not directly comparable
— e.g. allowlist entries that describe a class of identity
("@example.com" matches any user at that domain) rather than a
single literal one. When a matcher is set the normalizer is
bypassed; the matcher owns the comparison.
Sourcepub fn is_allowed(&self, identity: &str) -> bool
pub fn is_allowed(&self, identity: &str) -> bool
Returns true if identity is admitted by the allowlist.
Semantics: empty list ⇒ deny; "*" present ⇒ admit; otherwise
admit iff the (possibly normalized) identity equals some
(possibly normalized) entry.
Sourcepub fn add(&self, identity: impl Into<String>)
pub fn add(&self, identity: impl Into<String>)
Append identity to the allowlist if absent. No-op when identity
is already present (byte-equal, not normalized).
Sourcepub fn snapshot(&self) -> Vec<String>
pub fn snapshot(&self) -> Vec<String>
Snapshot the current allowlist as an owned Vec. Order-preserving
relative to insertion / construction.
Trait Implementations§
Source§impl Aspect for AllowlistAspect
impl Aspect for AllowlistAspect
Source§fn around(
&self,
pjp: ProceedingJoinPoint<'_>,
) -> Result<Box<dyn Any>, AspectError>
fn around( &self, pjp: ProceedingJoinPoint<'_>, ) -> Result<Box<dyn Any>, AspectError>
Source§fn after(&self, _ctx: &JoinPoint, _result: &(dyn Any + 'static))
fn after(&self, _ctx: &JoinPoint, _result: &(dyn Any + 'static))
Source§fn after_error(&self, _ctx: &JoinPoint, _error: &AspectError)
fn after_error(&self, _ctx: &JoinPoint, _error: &AspectError)
Source§impl Clone for AllowlistAspect
impl Clone for AllowlistAspect
Source§fn clone(&self) -> AllowlistAspect
fn clone(&self) -> AllowlistAspect
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more