mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-11-07 11:27:04 +08:00
Hide the current server version (closes #1435)
This commit is contained in:
parent
ee7c953279
commit
e10e94325f
12 changed files with 97 additions and 59 deletions
|
|
@ -11,9 +11,12 @@ use sieve::{Compiler, Runtime, Sieve, compiler::grammar::Capability};
|
||||||
use store::Stores;
|
use store::Stores;
|
||||||
use utils::config::Config;
|
use utils::config::Config;
|
||||||
|
|
||||||
use crate::scripts::{
|
use crate::{
|
||||||
functions::{register_functions_trusted, register_functions_untrusted},
|
VERSION_PUBLIC,
|
||||||
plugins::RegisterSievePlugins,
|
scripts::{
|
||||||
|
functions::{register_functions_trusted, register_functions_untrusted},
|
||||||
|
plugins::RegisterSievePlugins,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{if_block::IfBlock, smtp::SMTP_RCPT_TO_VARS, tokenizer::TokenMap};
|
use super::{if_block::IfBlock, smtp::SMTP_RCPT_TO_VARS, tokenizer::TokenMap};
|
||||||
|
|
@ -182,8 +185,8 @@ impl Scripting {
|
||||||
.unwrap_or("Auto: ")
|
.unwrap_or("Auto: ")
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
.with_env_variable("name", "Stalwart Mail Server")
|
.with_env_variable("name", "Stalwart Server")
|
||||||
.with_env_variable("version", env!("CARGO_PKG_VERSION"))
|
.with_env_variable("version", VERSION_PUBLIC)
|
||||||
.with_env_variable("location", "MS")
|
.with_env_variable("location", "MS")
|
||||||
.with_env_variable("phase", "during");
|
.with_env_variable("phase", "during");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,12 @@ pub mod telemetry;
|
||||||
|
|
||||||
pub use psl;
|
pub use psl;
|
||||||
|
|
||||||
pub static USER_AGENT: &str = concat!("Stalwart/", env!("CARGO_PKG_VERSION"),);
|
pub static VERSION_PRIVATE: &str = env!("CARGO_PKG_VERSION");
|
||||||
pub static DAEMON_NAME: &str = concat!("Stalwart Mail Server v", env!("CARGO_PKG_VERSION"),);
|
pub static VERSION_PUBLIC: &str = "1.0.0";
|
||||||
|
|
||||||
|
pub static USER_AGENT: &str = "Stalwart/1.0.0";
|
||||||
|
pub static DAEMON_NAME: &str = concat!("Stalwart v", env!("CARGO_PKG_VERSION"),);
|
||||||
|
pub static PROD_ID: &str = "-//Stalwart Labs Ltd.//Stalwart Server//EN";
|
||||||
|
|
||||||
pub const LONG_1D_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24);
|
pub const LONG_1D_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24);
|
||||||
pub const LONG_1Y_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24 * 365);
|
pub const LONG_1Y_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24 * 365);
|
||||||
|
|
@ -253,9 +257,22 @@ pub struct DavResource {
|
||||||
pub document_id: u32,
|
pub document_id: u32,
|
||||||
pub parent_id: Option<u32>,
|
pub parent_id: Option<u32>,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub size: u32,
|
pub data: DavResourceMetadata,
|
||||||
pub hierarchy_sequence: u32,
|
}
|
||||||
pub is_container: bool,
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub enum DavResourceMetadata {
|
||||||
|
File {
|
||||||
|
size: u32,
|
||||||
|
hierarchy_sequence: u32,
|
||||||
|
is_container: bool,
|
||||||
|
},
|
||||||
|
Calendar {
|
||||||
|
start: i64,
|
||||||
|
duration: u32,
|
||||||
|
},
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
|
|
@ -506,7 +523,7 @@ impl DavResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_resource(&self, resource: &DavResource) -> String {
|
pub fn format_resource(&self, resource: &DavResource) -> String {
|
||||||
if resource.is_container {
|
if resource.is_container() {
|
||||||
format!("{}{}/", self.base_path, resource.name)
|
format!("{}{}/", self.base_path, resource.name)
|
||||||
} else {
|
} else {
|
||||||
format!("{}{}", self.base_path, resource.name)
|
format!("{}{}", self.base_path, resource.name)
|
||||||
|
|
@ -522,6 +539,46 @@ impl DavResources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DavResource {
|
||||||
|
pub fn event_time_range(&self) -> Option<(i64, i64)> {
|
||||||
|
match &self.data {
|
||||||
|
DavResourceMetadata::Calendar { start, duration } => {
|
||||||
|
Some((*start, *start + *duration as i64))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_container(&self) -> bool {
|
||||||
|
match &self.data {
|
||||||
|
DavResourceMetadata::File { is_container, .. } => *is_container,
|
||||||
|
_ => self.parent_id.is_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> u32 {
|
||||||
|
match &self.data {
|
||||||
|
DavResourceMetadata::File { size, .. } => *size,
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hierarchy_sequence(&self) -> u32 {
|
||||||
|
match &self.data {
|
||||||
|
DavResourceMetadata::File {
|
||||||
|
hierarchy_sequence, ..
|
||||||
|
} => *hierarchy_sequence,
|
||||||
|
_ => {
|
||||||
|
if self.parent_id.is_none() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IdBimapItem for DavResource {
|
impl IdBimapItem for DavResource {
|
||||||
fn id(&self) -> &u32 {
|
fn id(&self) -> &u32 {
|
||||||
&self.document_id
|
&self.document_id
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ pub struct IpcReceivers {
|
||||||
}
|
}
|
||||||
|
|
||||||
const HELP: &str = concat!(
|
const HELP: &str = concat!(
|
||||||
"Stalwart Mail Server v",
|
"Stalwart Server v",
|
||||||
env!("CARGO_PKG_VERSION"),
|
env!("CARGO_PKG_VERSION"),
|
||||||
r#"
|
r#"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use store::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const HELP: &str = concat!(
|
const HELP: &str = concat!(
|
||||||
"Stalwart Mail Server v",
|
"Stalwart Server v",
|
||||||
env!("CARGO_PKG_VERSION"),
|
env!("CARGO_PKG_VERSION"),
|
||||||
r#" Data Store CLI
|
r#" Data Store CLI
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ impl Server {
|
||||||
access_token: &AccessToken,
|
access_token: &AccessToken,
|
||||||
to_account_id: u32,
|
to_account_id: u32,
|
||||||
to_collection: Collection,
|
to_collection: Collection,
|
||||||
check_acls: impl Into<Bitmap<Acl>>,
|
check_acls: impl IntoIterator<Item = Acl>,
|
||||||
|
match_any: bool,
|
||||||
) -> trc::Result<RoaringBitmap> {
|
) -> trc::Result<RoaringBitmap> {
|
||||||
let check_acls = check_acls.into();
|
let check_acls = Bitmap::<Acl>::from_iter(check_acls);
|
||||||
let mut document_ids = RoaringBitmap::new();
|
let mut document_ids = RoaringBitmap::new();
|
||||||
let to_collection = u8::from(to_collection);
|
let to_collection = u8::from(to_collection);
|
||||||
for &grant_account_id in [access_token.primary_id]
|
for &grant_account_id in [access_token.primary_id]
|
||||||
|
|
@ -39,9 +40,8 @@ impl Server {
|
||||||
.caused_by(trc::location!())?
|
.caused_by(trc::location!())?
|
||||||
{
|
{
|
||||||
let mut acls = Bitmap::<Acl>::from(acl_item.permissions);
|
let mut acls = Bitmap::<Acl>::from(acl_item.permissions);
|
||||||
|
|
||||||
acls.intersection(&check_acls);
|
acls.intersection(&check_acls);
|
||||||
if !acls.is_empty() {
|
if acls == check_acls || (match_any && !acls.is_empty()) {
|
||||||
document_ids.insert(acl_item.to_document_id);
|
document_ids.insert(acl_item.to_document_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,26 +50,6 @@ impl Server {
|
||||||
Ok(document_ids)
|
Ok(document_ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn owned_or_shared_containers(
|
|
||||||
&self,
|
|
||||||
access_token: &AccessToken,
|
|
||||||
account_id: u32,
|
|
||||||
collection: Collection,
|
|
||||||
check_acls: impl Into<Bitmap<Acl>>,
|
|
||||||
) -> trc::Result<RoaringBitmap> {
|
|
||||||
let check_acls = check_acls.into();
|
|
||||||
let mut document_ids = self
|
|
||||||
.get_document_ids(account_id, collection)
|
|
||||||
.await?
|
|
||||||
.unwrap_or_default();
|
|
||||||
if !document_ids.is_empty() && !access_token.is_member(account_id) {
|
|
||||||
document_ids &= self
|
|
||||||
.shared_containers(access_token, account_id, collection, check_acls)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
Ok(document_ids)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn has_access_to_document(
|
pub async fn has_access_to_document(
|
||||||
&self,
|
&self,
|
||||||
access_token: &AccessToken,
|
access_token: &AccessToken,
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,12 @@ impl From<u64> for IndexItem<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<i64> for IndexItem<'_> {
|
||||||
|
fn from(value: i64) -> Self {
|
||||||
|
IndexItem::LongInt(value.to_be_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'x> From<&'x [u8]> for IndexItem<'x> {
|
impl<'x> From<&'x [u8]> for IndexItem<'x> {
|
||||||
fn from(value: &'x [u8]) -> Self {
|
fn from(value: &'x [u8]) -> Self {
|
||||||
IndexItem::Slice(value)
|
IndexItem::Slice(value)
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ impl<T: SessionStream> Session<T> {
|
||||||
.with_tag(request.tag)
|
.with_tag(request.tag)
|
||||||
.serialize(
|
.serialize(
|
||||||
concat!(
|
concat!(
|
||||||
"* ID (\"name\" \"Stalwart IMAP\" \"version\" \"",
|
"* ID (\"name\" \"Stalwart\" \"version\" \"1.0.0\" \"vendor\" \"Stalwart Labs Ltd.\" ",
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
"\" \"vendor\" \"Stalwart Labs Ltd.\" ",
|
|
||||||
"\"support-url\" \"https://stalw.art\")\r\n"
|
"\"support-url\" \"https://stalw.art\")\r\n"
|
||||||
)
|
)
|
||||||
.as_bytes()
|
.as_bytes()
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,8 @@ impl<T: SessionStream> Session<T> {
|
||||||
pub async fn handle_logout(&mut self, request: Request<Command>) -> trc::Result<()> {
|
pub async fn handle_logout(&mut self, request: Request<Command>) -> trc::Result<()> {
|
||||||
let op_start = Instant::now();
|
let op_start = Instant::now();
|
||||||
|
|
||||||
let mut response = StatusResponse::bye(
|
let mut response =
|
||||||
concat!(
|
StatusResponse::bye("Stalwart IMAP4rev2 bids you farewell.".to_string()).into_bytes();
|
||||||
"Stalwart IMAP4rev2 v",
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
" bids you farewell."
|
|
||||||
)
|
|
||||||
.to_string(),
|
|
||||||
)
|
|
||||||
.into_bytes();
|
|
||||||
|
|
||||||
trc::event!(
|
trc::event!(
|
||||||
Imap(trc::ImapEvent::Logout),
|
Imap(trc::ImapEvent::Logout),
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ impl Account {
|
||||||
impl Default for SieveSessionCapabilities {
|
impl Default for SieveSessionCapabilities {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
implementation: concat!("Stalwart JMAP v", env!("CARGO_PKG_VERSION"),),
|
implementation: "Stalwart v1.0.0",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,13 @@ impl SessionHandler for Server {
|
||||||
let is_personal = !access_token.is_member(*id);
|
let is_personal = !access_token.is_member(*id);
|
||||||
let is_readonly = is_personal
|
let is_readonly = is_personal
|
||||||
&& self
|
&& self
|
||||||
.shared_containers(&access_token, *id, Collection::Mailbox, Acl::AddItems)
|
.shared_containers(
|
||||||
|
&access_token,
|
||||||
|
*id,
|
||||||
|
Collection::Mailbox,
|
||||||
|
[Acl::AddItems],
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.caused_by(trc::location!())?
|
.caused_by(trc::location!())?
|
||||||
.is_empty();
|
.is_empty();
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,6 @@ impl<T: AsyncRead + AsyncWrite> Session<T> {
|
||||||
Elapsed = trc::Value::Duration(0)
|
Elapsed = trc::Value::Duration(0)
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(StatusResponse::ok(concat!(
|
Ok(StatusResponse::ok("Stalwart ManageSieve bids you farewell.").into_bytes())
|
||||||
"Stalwart ManageSieve v",
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
" bids you farewell."
|
|
||||||
))
|
|
||||||
.into_bytes())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ impl<T: Display> Response<T> {
|
||||||
"EXPIRE NEVER",
|
"EXPIRE NEVER",
|
||||||
"UIDL",
|
"UIDL",
|
||||||
"UTF8",
|
"UTF8",
|
||||||
"IMPLEMENTATION Stalwart Mail Server",
|
"IMPLEMENTATION Stalwart Server",
|
||||||
] {
|
] {
|
||||||
buf.extend_from_slice(capa.as_bytes());
|
buf.extend_from_slice(capa.as_bytes());
|
||||||
buf.extend_from_slice(b"\r\n");
|
buf.extend_from_slice(b"\r\n");
|
||||||
|
|
@ -201,7 +201,7 @@ mod tests {
|
||||||
"EXPIRE NEVER\r\n",
|
"EXPIRE NEVER\r\n",
|
||||||
"UIDL\r\n",
|
"UIDL\r\n",
|
||||||
"UTF8\r\n",
|
"UTF8\r\n",
|
||||||
"IMPLEMENTATION Stalwart Mail Server\r\n.\r\n"
|
"IMPLEMENTATION Stalwart Server\r\n.\r\n"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue