52 lines
1.9 KiB
Rust
52 lines
1.9 KiB
Rust
//! Generic sliding-window rate limiter.
|
||
//!
|
||
//! Key pattern: `rate:{namespace}:{identifier}`
|
||
//! Returns `Ok(true)` if the request is allowed, `Ok(false)` if rate-limited.
|
||
|
||
use redis::AsyncCommands;
|
||
use crate::RedisPool;
|
||
|
||
/// Check + increment a rate-limit counter.
|
||
///
|
||
/// * `namespace` – e.g. `"login"`, `"register"`, `"lead"`
|
||
/// * `identifier` – e.g. email, IP, user_id
|
||
/// * `max` – maximum requests allowed in `window_secs`
|
||
/// * `window_secs` – sliding window length in seconds
|
||
///
|
||
/// Returns `Ok(true)` = allowed, `Ok(false)` = blocked.
|
||
pub async fn check(
|
||
redis: &mut RedisPool,
|
||
namespace: &str,
|
||
identifier: &str,
|
||
max: i64,
|
||
window_secs: i64,
|
||
) -> Result<bool, redis::RedisError> {
|
||
let key = format!("rate:{namespace}:{identifier}");
|
||
let count: i64 = redis.incr(&key, 1i64).await?;
|
||
if count == 1 {
|
||
redis.expire::<_, ()>(&key, window_secs).await?;
|
||
}
|
||
Ok(count <= max)
|
||
}
|
||
|
||
/// Convenience wrappers ───────────────────────────────────────────────────────
|
||
|
||
/// Register: max 10 per hour per email
|
||
pub async fn check_register(redis: &mut RedisPool, email: &str) -> Result<bool, redis::RedisError> {
|
||
check(redis, "register", email, 10, 3_600).await
|
||
}
|
||
|
||
/// Login: max 10 attempts per 15 min per email
|
||
pub async fn check_login(redis: &mut RedisPool, email: &str) -> Result<bool, redis::RedisError> {
|
||
check(redis, "login", email, 10, 900).await
|
||
}
|
||
|
||
/// Lead request: max 5 per hour per professional
|
||
pub async fn check_lead(redis: &mut RedisPool, professional_id: &str) -> Result<bool, redis::RedisError> {
|
||
check(redis, "lead", professional_id, 5, 3_600).await
|
||
}
|
||
|
||
/// Job post: max 20 per hour per company
|
||
pub async fn check_job_post(redis: &mut RedisPool, company_id: &str) -> Result<bool, redis::RedisError> {
|
||
check(redis, "job_post", company_id, 20, 3_600).await
|
||
}
|