Import upstream v0.16.22, stripped
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.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user