You've already forked AstralRinth
forked from didirus/AstralRinth
Replace ignore IP system with keys (#368)
This commit is contained in:
1
.env
1
.env
@@ -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
|
||||
|
||||
11
src/main.rs
11
src/main.rs
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user