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
|
SITE_URL=https://modrinth.com
|
||||||
CDN_URL=https://cdn.modrinth.com
|
CDN_URL=https://cdn.modrinth.com
|
||||||
LABRINTH_ADMIN_KEY=feedbeef
|
LABRINTH_ADMIN_KEY=feedbeef
|
||||||
|
RATE_LIMIT_IGNORE_KEY=feedbeef
|
||||||
|
|
||||||
MODERATION_DISCORD_WEBHOOK=
|
MODERATION_DISCORD_WEBHOOK=
|
||||||
CLOUDFLARE_INTEGRATION=false
|
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_interval(std::time::Duration::from_secs(60))
|
||||||
.with_max_requests(300)
|
.with_max_requests(300)
|
||||||
.with_ignore_ips(
|
.with_ignore_key(
|
||||||
parse_strings_from_var("RATE_LIMIT_IGNORE_IPS")
|
dotenv::var("RATE_LIMIT_IGNORE_KEY").ok(),
|
||||||
.unwrap_or_default(),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.app_data(web::Data::new(pool.clone()))
|
.app_data(web::Data::new(pool.clone()))
|
||||||
@@ -292,11 +291,6 @@ fn check_env_vars() -> bool {
|
|||||||
check
|
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() {
|
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");
|
warn!("Variable `WHITELISTED_MODPACK_DOMAINS` missing in dotenv or not a json array of strings");
|
||||||
failed |= true;
|
failed |= true;
|
||||||
@@ -305,6 +299,7 @@ fn check_env_vars() -> bool {
|
|||||||
failed |= check_var::<String>("SITE_URL");
|
failed |= check_var::<String>("SITE_URL");
|
||||||
failed |= check_var::<String>("CDN_URL");
|
failed |= check_var::<String>("CDN_URL");
|
||||||
failed |= check_var::<String>("LABRINTH_ADMIN_KEY");
|
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>("DATABASE_URL");
|
||||||
failed |= check_var::<String>("MEILISEARCH_ADDR");
|
failed |= check_var::<String>("MEILISEARCH_ADDR");
|
||||||
failed |= check_var::<String>("MEILISEARCH_KEY");
|
failed |= check_var::<String>("MEILISEARCH_KEY");
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ where
|
|||||||
max_requests: usize,
|
max_requests: usize,
|
||||||
store: Addr<T>,
|
store: Addr<T>,
|
||||||
identifier: RateLimiterIdentifier,
|
identifier: RateLimiterIdentifier,
|
||||||
ignore_ips: Vec<String>,
|
ignore_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RateLimiter<T>
|
impl<T> RateLimiter<T>
|
||||||
@@ -51,7 +51,7 @@ where
|
|||||||
max_requests: 0,
|
max_requests: 0,
|
||||||
store,
|
store,
|
||||||
identifier: Rc::new(Box::new(identifier)),
|
identifier: Rc::new(Box::new(identifier)),
|
||||||
ignore_ips: Vec::new(),
|
ignore_key: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +67,9 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets IPs that should be ignored by the ratelimiter
|
/// Sets key which can be used to bypass rate-limiter
|
||||||
pub fn with_ignore_ips(mut self, ignore_ips: Vec<String>) -> Self {
|
pub fn with_ignore_key(mut self, ignore_key: Option<String>) -> Self {
|
||||||
self.ignore_ips = ignore_ips;
|
self.ignore_key = ignore_key;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ where
|
|||||||
max_requests: self.max_requests,
|
max_requests: self.max_requests,
|
||||||
interval: self.interval.as_secs(),
|
interval: self.interval.as_secs(),
|
||||||
identifier: self.identifier.clone(),
|
identifier: self.identifier.clone(),
|
||||||
ignore_ips: self.ignore_ips.clone(),
|
ignore_key: self.ignore_key.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ where
|
|||||||
max_requests: usize,
|
max_requests: usize,
|
||||||
interval: u64,
|
interval: u64,
|
||||||
identifier: RateLimiterIdentifier,
|
identifier: RateLimiterIdentifier,
|
||||||
ignore_ips: Vec<String>,
|
ignore_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, B> Service<ServiceRequest> for RateLimitMiddleware<S, T>
|
impl<T, S, B> Service<ServiceRequest> for RateLimitMiddleware<S, T>
|
||||||
@@ -154,14 +154,20 @@ where
|
|||||||
let max_requests = self.max_requests;
|
let max_requests = self.max_requests;
|
||||||
let interval = Duration::from_secs(self.interval);
|
let interval = Duration::from_secs(self.interval);
|
||||||
let identifier = self.identifier.clone();
|
let identifier = self.identifier.clone();
|
||||||
let ignore_ips = self.ignore_ips.clone();
|
let ignore_key = self.ignore_key.clone();
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let identifier: String = (identifier)(&req)?;
|
let identifier: String = (identifier)(&req)?;
|
||||||
if ignore_ips.contains(&identifier) {
|
|
||||||
let fut = srv.call(req);
|
if let Some(ignore_key) = ignore_key {
|
||||||
let res = fut.await?;
|
if let Some(key) = req.headers().get("x-ratelimit-key") {
|
||||||
return Ok(res);
|
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
|
let remaining: ActorResponse = store
|
||||||
.send(ActorMessage::Get(String::from(&identifier)))
|
.send(ActorMessage::Get(String::from(&identifier)))
|
||||||
.await
|
.await
|
||||||
|
|||||||
Reference in New Issue
Block a user