Replace ignore IP system with keys (#368)

This commit is contained in:
Geometrically
2022-06-09 15:28:40 -07:00
committed by GitHub
parent 75614fb13c
commit 355689ed19
3 changed files with 22 additions and 20 deletions

1
.env
View File

@@ -4,6 +4,7 @@ RUST_LOG=info,sqlx::query=warn
SITE_URL=https://modrinth.com
CDN_URL=https://cdn.modrinth.com
LABRINTH_ADMIN_KEY=feedbeef
RATE_LIMIT_IGNORE_KEY=feedbeef
MODERATION_DISCORD_WEBHOOK=
CLOUDFLARE_INTEGRATION=false

View File

@@ -253,9 +253,8 @@ async fn main() -> std::io::Result<()> {
})
.with_interval(std::time::Duration::from_secs(60))
.with_max_requests(300)
.with_ignore_ips(
parse_strings_from_var("RATE_LIMIT_IGNORE_IPS")
.unwrap_or_default(),
.with_ignore_key(
dotenv::var("RATE_LIMIT_IGNORE_KEY").ok(),
),
)
.app_data(web::Data::new(pool.clone()))
@@ -292,11 +291,6 @@ fn check_env_vars() -> bool {
check
}
if parse_strings_from_var("RATE_LIMIT_IGNORE_IPS").is_none() {
warn!("Variable `RATE_LIMIT_IGNORE_IPS` missing in dotenv or not a json array of strings");
failed |= true;
}
if parse_strings_from_var("WHITELISTED_MODPACK_DOMAINS").is_none() {
warn!("Variable `WHITELISTED_MODPACK_DOMAINS` missing in dotenv or not a json array of strings");
failed |= true;
@@ -305,6 +299,7 @@ fn check_env_vars() -> bool {
failed |= check_var::<String>("SITE_URL");
failed |= check_var::<String>("CDN_URL");
failed |= check_var::<String>("LABRINTH_ADMIN_KEY");
failed |= check_var::<String>("RATE_LIMIT_IGNORE_KEY");
failed |= check_var::<String>("DATABASE_URL");
failed |= check_var::<String>("MEILISEARCH_ADDR");
failed |= check_var::<String>("MEILISEARCH_KEY");

View File

@@ -30,7 +30,7 @@ where
max_requests: usize,
store: Addr<T>,
identifier: RateLimiterIdentifier,
ignore_ips: Vec<String>,
ignore_key: Option<String>,
}
impl<T> RateLimiter<T>
@@ -51,7 +51,7 @@ where
max_requests: 0,
store,
identifier: Rc::new(Box::new(identifier)),
ignore_ips: Vec::new(),
ignore_key: None
}
}
@@ -67,9 +67,9 @@ where
self
}
/// Sets IPs that should be ignored by the ratelimiter
pub fn with_ignore_ips(mut self, ignore_ips: Vec<String>) -> Self {
self.ignore_ips = ignore_ips;
/// Sets key which can be used to bypass rate-limiter
pub fn with_ignore_key(mut self, ignore_key: Option<String>) -> Self {
self.ignore_key = ignore_key;
self
}
@@ -107,7 +107,7 @@ where
max_requests: self.max_requests,
interval: self.interval.as_secs(),
identifier: self.identifier.clone(),
ignore_ips: self.ignore_ips.clone(),
ignore_key: self.ignore_key.clone(),
})
}
}
@@ -124,7 +124,7 @@ where
max_requests: usize,
interval: u64,
identifier: RateLimiterIdentifier,
ignore_ips: Vec<String>,
ignore_key: Option<String>,
}
impl<T, S, B> Service<ServiceRequest> for RateLimitMiddleware<S, T>
@@ -154,14 +154,20 @@ where
let max_requests = self.max_requests;
let interval = Duration::from_secs(self.interval);
let identifier = self.identifier.clone();
let ignore_ips = self.ignore_ips.clone();
let ignore_key = self.ignore_key.clone();
Box::pin(async move {
let identifier: String = (identifier)(&req)?;
if ignore_ips.contains(&identifier) {
let fut = srv.call(req);
let res = fut.await?;
return Ok(res);
if let Some(ignore_key) = ignore_key {
if let Some(key) = req.headers().get("x-ratelimit-key") {
if key.to_str().ok().unwrap_or_default() == &*ignore_key {
let fut = srv.call(req);
let res = fut.await?;
return Ok(res);
}
}
}
let remaining: ActorResponse = store
.send(ActorMessage::Get(String::from(&identifier)))
.await