pub struct LoginRateLimiter { /* private fields */ }Expand description
In-memory counter of recent failed login attempts, keyed by email.
After LoginRateLimiter::MAX_FAILURES failures, further attempts
for the same key are rejected for LoginRateLimiter::LOCKOUT. A
single successful login clears the counter.
Scope: per-email, not per-IP. Stops targeted brute force against a single account. A distributed attack (many emails, many sources) is not defended; per-IP rate limiting requires the server pipeline to propagate the client address into the request context, which is deferred to a later pass.
Implementations§
Source§impl LoginRateLimiter
impl LoginRateLimiter
Sourcepub const MAX_FAILURES: u32 = 5
pub const MAX_FAILURES: u32 = 5
Lock an account’s login attempts for 60s after 5 failures in
the current lockout window. Conservative defaults; tune via
LoginRateLimiter::with_params in tests or forks.
pub const LOCKOUT: StdDuration
pub fn new() -> Self
Sourcepub fn with_params(max_failures: u32, lockout: StdDuration) -> Self
pub fn with_params(max_failures: u32, lockout: StdDuration) -> Self
Construct with custom thresholds. Used by tests to exercise lockout behaviour on a shorter clock.
Sourcepub fn global() -> &'static Self
pub fn global() -> &'static Self
Process-wide shared limiter used by the login handler. Lazily created on first access. In-process only — resets on restart, which is a deliberate trade-off for simplicity in 0.4.0.
Sourcepub fn check(&self, key: &str) -> Result<(), StdDuration>
pub fn check(&self, key: &str) -> Result<(), StdDuration>
Return Ok(()) if a login attempt is permitted for this key.
If the key is currently locked out, return the time remaining
until the lockout expires.
Sourcepub fn record_failure(&self, key: &str)
pub fn record_failure(&self, key: &str)
Record a failed login for key. On the transition to the
threshold, stamps locked_until to “now + LOCKOUT” so check
will reject further attempts until the clock advances.
Sourcepub fn record_success(&self, key: &str)
pub fn record_success(&self, key: &str)
Clear the counter for key. Called on every successful login
so a user who mistypes once then logs in isn’t held to the
strike count.
Sourcepub fn compose_key(email: &str, ip: Option<&str>) -> String
pub fn compose_key(email: &str, ip: Option<&str>) -> String
Compose a multi-axis rate-limit key from an email (required) and an optional IP.
The login handler calls this with whatever it has in hand —
peer_addr() is available when the server provided it,
otherwise we fall back to email-only. Including the IP means
one attacker hammering many emails is throttled by IP too,
and one email being hit from many IPs is still throttled by
email.
This is the documented extension point for future per-IP
limiting beyond the login path. Wrap the key any way a
caller sees fit (e.g. format!("api:{user_id}")); the
limiter itself only compares strings.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for LoginRateLimiter
impl RefUnwindSafe for LoginRateLimiter
impl Send for LoginRateLimiter
impl Sync for LoginRateLimiter
impl Unpin for LoginRateLimiter
impl UnsafeUnpin for LoginRateLimiter
impl UnwindSafe for LoginRateLimiter
Blanket Implementations§
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
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> 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