Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 117 in 50 files Dangling module declarations removed: 5 Cargo edits turning enterprise off: 14 Verification: clean Enterprise feature gates left for rebuilt features: 19 in 18 files Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
108 lines
3.7 KiB
Rust
108 lines
3.7 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use crate::auth::AccessToken;
|
|
use crate::network::ip_to_bytes;
|
|
use crate::network::limiter::{InFlight, LimiterResult};
|
|
use crate::{KV_RATE_LIMIT_HTTP_ANONYMOUS, KV_RATE_LIMIT_HTTP_AUTHENTICATED, Server};
|
|
use registry::schema::enums::Permission;
|
|
use std::net::IpAddr;
|
|
use trc::AddContext;
|
|
|
|
impl Server {
|
|
pub async fn is_http_authenticated_request_allowed(
|
|
&self,
|
|
access_token: &AccessToken,
|
|
addr: IpAddr,
|
|
) -> trc::Result<Option<InFlight>> {
|
|
let rate_reset = if let Some(rate) = &self.core.network.http.rate_authenticated {
|
|
if self.is_ip_allowed(addr) {
|
|
None
|
|
} else {
|
|
self.core
|
|
.storage
|
|
.memory
|
|
.is_rate_allowed(
|
|
KV_RATE_LIMIT_HTTP_AUTHENTICATED,
|
|
&access_token.account_id().to_be_bytes(),
|
|
rate,
|
|
false,
|
|
)
|
|
.await
|
|
.caused_by(trc::location!())?
|
|
.map(|reset| (reset, rate.count))
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
|
|
if let Some((reset, count)) = rate_reset {
|
|
if access_token.has_permission(Permission::UnlimitedRequests) {
|
|
Ok(None)
|
|
} else {
|
|
Err(trc::LimitEvent::TooManyRequests
|
|
.into_err()
|
|
.ctx(trc::Key::Expires, reset)
|
|
.ctx(trc::Key::Limit, count))
|
|
}
|
|
} else {
|
|
match access_token.is_http_request_allowed() {
|
|
LimiterResult::Allowed(in_flight) => Ok(Some(in_flight)),
|
|
LimiterResult::Forbidden => {
|
|
if access_token.has_permission(Permission::UnlimitedRequests) {
|
|
Ok(None)
|
|
} else {
|
|
Err(trc::LimitEvent::ConcurrentRequest
|
|
.into_err()
|
|
.ctx(trc::Key::Limit, access_token.concurrent_http_requests()))
|
|
}
|
|
}
|
|
LimiterResult::Disabled => Ok(None),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn is_http_anonymous_request_allowed(&self, addr: IpAddr) -> trc::Result<()> {
|
|
if let Some(rate) = &self.core.network.http.rate_anonymous
|
|
&& !self.is_ip_allowed(addr)
|
|
&& let Some(reset) = self
|
|
.core
|
|
.storage
|
|
.memory
|
|
.is_rate_allowed(
|
|
KV_RATE_LIMIT_HTTP_ANONYMOUS,
|
|
&ip_to_bytes(&addr),
|
|
rate,
|
|
false,
|
|
)
|
|
.await
|
|
.caused_by(trc::location!())?
|
|
{
|
|
return Err(trc::LimitEvent::TooManyRequests
|
|
.into_err()
|
|
.ctx(trc::Key::Expires, reset)
|
|
.ctx(trc::Key::Limit, rate.count));
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn is_upload_allowed(&self, access_token: &AccessToken) -> trc::Result<Option<InFlight>> {
|
|
match access_token.is_upload_allowed() {
|
|
LimiterResult::Allowed(in_flight) => Ok(Some(in_flight)),
|
|
LimiterResult::Forbidden => {
|
|
if access_token.has_permission(Permission::UnlimitedRequests) {
|
|
Ok(None)
|
|
} else {
|
|
Err(trc::LimitEvent::ConcurrentUpload
|
|
.into_err()
|
|
.ctx(trc::Key::Limit, access_token.concurrent_uploads()))
|
|
}
|
|
}
|
|
LimiterResult::Disabled => Ok(None),
|
|
}
|
|
}
|
|
}
|