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,210 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
core::{Session, SessionData},
|
||||
op::ImapContext,
|
||||
spawn_op,
|
||||
};
|
||||
use common::network::SessionStream;
|
||||
use imap_proto::{
|
||||
Command, ResponseCode, StatusResponse,
|
||||
protocol::{
|
||||
ImapResponse,
|
||||
capability::QuotaResourceName,
|
||||
quota::{Arguments, QuotaItem, QuotaResource, Response},
|
||||
},
|
||||
receiver::Request,
|
||||
};
|
||||
use registry::schema::enums::Permission;
|
||||
use std::time::Instant;
|
||||
|
||||
impl<T: SessionStream> Session<T> {
|
||||
pub async fn handle_get_quota(&mut self, request: Request<Command>) -> trc::Result<()> {
|
||||
// Validate access
|
||||
self.assert_has_permission(Permission::ImapStatus)?;
|
||||
|
||||
let data = self.state.session_data();
|
||||
|
||||
spawn_op!(data, {
|
||||
match request.parse_get_quota() {
|
||||
Ok(argument) => match data.get_quota(argument).await {
|
||||
Ok(response) => {
|
||||
data.write_bytes(response).await?;
|
||||
}
|
||||
Err(error) => {
|
||||
data.write_error(error).await?;
|
||||
}
|
||||
},
|
||||
Err(err) => data.write_error(err).await?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn handle_get_quota_root(&mut self, request: Request<Command>) -> trc::Result<()> {
|
||||
// Validate access
|
||||
self.assert_has_permission(Permission::ImapStatus)?;
|
||||
|
||||
let data = self.state.session_data();
|
||||
let is_utf8 = self.is_utf8;
|
||||
|
||||
spawn_op!(data, {
|
||||
match request.parse_get_quota_root(is_utf8) {
|
||||
Ok(argument) => match data.get_quota_root(argument).await {
|
||||
Ok(response) => {
|
||||
data.write_bytes(response).await?;
|
||||
}
|
||||
Err(error) => {
|
||||
data.write_error(error).await?;
|
||||
}
|
||||
},
|
||||
Err(err) => data.write_error(err).await?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SessionStream> SessionData<T> {
|
||||
pub async fn get_quota(&self, arguments: Arguments) -> trc::Result<Vec<u8>> {
|
||||
let op_start = Instant::now();
|
||||
|
||||
// Refresh mailboxes
|
||||
self.synchronize_mailboxes(false)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
|
||||
// Validate quota root
|
||||
let account_id: u32 = arguments
|
||||
.name
|
||||
.strip_prefix("#")
|
||||
.and_then(|id| id.parse().ok())
|
||||
.filter(|id| self.access_token.is_member(*id))
|
||||
.ok_or_else(|| {
|
||||
trc::ImapEvent::Error
|
||||
.into_err()
|
||||
.details("Invalid quota root parameter.")
|
||||
.id(arguments.tag.to_string())
|
||||
})?;
|
||||
|
||||
// Obtain access token for mailbox
|
||||
let account = self
|
||||
.server
|
||||
.account(account_id)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
let used_quota = self
|
||||
.server
|
||||
.get_used_quota_account(account_id)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
|
||||
trc::event!(
|
||||
Imap(trc::ImapEvent::GetQuota),
|
||||
SpanId = self.session_id,
|
||||
Id = arguments.name.clone(),
|
||||
Details = vec![
|
||||
trc::Value::from(used_quota),
|
||||
trc::Value::from(account.disk_quota())
|
||||
],
|
||||
Elapsed = op_start.elapsed()
|
||||
);
|
||||
|
||||
// Build response
|
||||
let response = Response {
|
||||
quota_root_items: vec![],
|
||||
quota_items: vec![QuotaItem {
|
||||
name: arguments.name,
|
||||
resources: if account.disk_quota() > 0 {
|
||||
vec![QuotaResource {
|
||||
resource: QuotaResourceName::Storage,
|
||||
total: account.disk_quota(),
|
||||
used: used_quota as u64,
|
||||
}]
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
Ok(StatusResponse::ok("GETQUOTA successful.")
|
||||
.with_tag(arguments.tag)
|
||||
.serialize(response.serialize()))
|
||||
}
|
||||
|
||||
pub async fn get_quota_root(&self, arguments: Arguments) -> trc::Result<Vec<u8>> {
|
||||
let op_start = Instant::now();
|
||||
|
||||
// Refresh mailboxes
|
||||
self.synchronize_mailboxes(false)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
|
||||
// Validate mailbox
|
||||
let account_id = if let Some(mailbox) = self.get_mailbox_by_name(&arguments.name) {
|
||||
mailbox.account_id
|
||||
} else {
|
||||
return Err(trc::ImapEvent::Error
|
||||
.into_err()
|
||||
.details("Mailbox does not exist.")
|
||||
.code(ResponseCode::TryCreate)
|
||||
.id(arguments.tag));
|
||||
};
|
||||
|
||||
// Obtain access token for mailbox
|
||||
let account = self
|
||||
.server
|
||||
.account(account_id)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
let used_quota = self
|
||||
.server
|
||||
.get_used_quota_account(account_id)
|
||||
.await
|
||||
.imap_ctx(&arguments.tag, trc::location!())?;
|
||||
|
||||
trc::event!(
|
||||
Imap(trc::ImapEvent::GetQuota),
|
||||
SpanId = self.session_id,
|
||||
MailboxName = arguments.name.clone(),
|
||||
Details = vec![
|
||||
trc::Value::from(used_quota),
|
||||
trc::Value::from(account.disk_quota())
|
||||
],
|
||||
Elapsed = op_start.elapsed()
|
||||
);
|
||||
|
||||
// Build response
|
||||
let response = Response {
|
||||
quota_root_items: vec![arguments.name, format!("#{account_id}")],
|
||||
quota_items: vec![QuotaItem {
|
||||
name: format!("#{account_id}"),
|
||||
resources: if account.disk_quota() > 0 {
|
||||
vec![QuotaResource {
|
||||
resource: QuotaResourceName::Storage,
|
||||
total: account.disk_quota(),
|
||||
used: used_quota as u64,
|
||||
}]
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
Ok(StatusResponse::ok("GETQUOTAROOT successful.")
|
||||
.with_tag(arguments.tag)
|
||||
.serialize(response.serialize()))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user