Skip to content

Commit

Permalink
Installation binary first part.
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Jul 9, 2023
1 parent 705762c commit 843e611
Show file tree
Hide file tree
Showing 27 changed files with 847 additions and 141 deletions.
44 changes: 44 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"crates/utils",
"crates/maybe-async",
"crates/cli",
"crates/install",
"tests",
]

Expand Down
10 changes: 7 additions & 3 deletions crates/directory/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl ConfigDirectory for Config {
};

// Add queries/filters as lookups
if ["sql", "ldap"].contains(&protocol) {
let is_directory = ["sql", "ldap"].contains(&protocol);
if is_directory {
let name = if protocol == "sql" { "query" } else { "filter" };
for lookup_id in self.sub_keys(("directory", id, name)) {
config.lookups.insert(
Expand All @@ -58,9 +59,8 @@ impl ConfigDirectory for Config {
}

// Parse lookups
let is_remote = protocol != "memory";
for lookup_id in self.sub_keys(("directory", id, "lookup")) {
let lookup = if is_remote {
let lookup = if is_directory {
Lookup::Directory {
directory: directory.clone(),
query: self
Expand Down Expand Up @@ -120,6 +120,10 @@ impl DirectoryOptions {
Ok(DirectoryOptions {
catch_all: config.property_or_static((&key, "options.catch-all"), "false")?,
subaddressing: config.property_or_static((&key, "options.subaddressing"), "true")?,
superuser_group: config
.value("options.superuser-group")
.unwrap_or("superusers")
.to_string(),
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/directory/src/imap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl ImapDirectory {
let address = config.value_require((&prefix, "address"))?;
let tls_implicit: bool = config.property_or_static((&prefix, "tls.implicit"), "false")?;
let port: u16 = config
.property_or_static((&prefix, "port"), if tls_implicit { "443" } else { "143" })?;
.property_or_static((&prefix, "port"), if tls_implicit { "993" } else { "143" })?;

let manager = ImapConnectionManager {
addr: format!("{address}:{port}"),
Expand Down
16 changes: 12 additions & 4 deletions crates/directory/src/ldap/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,25 @@ impl LdapDirectory {
for entry in rs {
'outer: for (attr, value) in SearchEntry::construct(entry).attrs {
if self.mappings.attr_name.contains(&attr) {
if let Some(name) = value.first() {
if !name.is_empty() {
names.push(name.to_string());
if let Some(group) = value.first() {
if !group.is_empty() {
if !group
.eq_ignore_ascii_case(&self.opt.superuser_group)
{
names.push(group.to_string());
} else {
principal.typ = Type::Superuser;
}
break 'outer;
}
}
}
}
}
} else {
} else if !group.eq_ignore_ascii_case(&self.opt.superuser_group) {
names.push(group);
} else {
principal.typ = Type::Superuser;
}
}
principal.member_of = names;
Expand Down
4 changes: 3 additions & 1 deletion crates/directory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum Type {
Location,
#[default]
Other,
Superuser,
}

#[derive(Debug)]
Expand Down Expand Up @@ -135,7 +136,7 @@ impl Debug for Lookup {
impl Type {
pub fn to_jmap(&self) -> &'static str {
match self {
Self::Individual => "individual",
Self::Individual | Self::Superuser => "individual",
Self::Group => "group",
Self::Resource => "resource",
Self::Location => "location",
Expand All @@ -148,6 +149,7 @@ impl Type {
struct DirectoryOptions {
catch_all: bool,
subaddressing: bool,
superuser_group: String,
}

#[derive(Default, Clone, Debug)]
Expand Down
24 changes: 17 additions & 7 deletions crates/directory/src/memory/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,26 @@ impl MemoryDirectory {
prefix: impl AsKey,
) -> utils::config::Result<Arc<dyn Directory>> {
let prefix = prefix.as_key();
let mut directory = MemoryDirectory::default();
let mut directory = MemoryDirectory {
opt: DirectoryOptions::from_config(config, prefix.clone())?,
..Default::default()
};

for lookup_id in config.sub_keys((prefix.as_str(), "users")) {
let name = config
.value_require((prefix.as_str(), "users", lookup_id, "name"))?
.to_string();
let mut typ = Type::Individual;
let mut member_of = Vec::new();

for (_, group) in config.values((prefix.as_str(), "users", lookup_id, "member-of")) {
if !group.eq_ignore_ascii_case(&directory.opt.superuser_group) {
member_of.push(group.to_string());
} else {
typ = Type::Superuser;
}
}

directory.principals.insert(
name.clone(),
Principal {
Expand All @@ -26,17 +40,14 @@ impl MemoryDirectory {
.values((prefix.as_str(), "users", lookup_id, "secret"))
.map(|(_, v)| v.to_string())
.collect(),
typ: Type::Individual,
typ,
description: config
.value((prefix.as_str(), "users", lookup_id, "description"))
.map(|v| v.to_string()),
quota: config
.property((prefix.as_str(), "users", lookup_id, "quota"))?
.unwrap_or(0),
member_of: config
.values((prefix.as_str(), "users", lookup_id, "member-of"))
.map(|(_, v)| v.to_string())
.collect(),
member_of,
},
);
let mut emails = Vec::new();
Expand Down Expand Up @@ -105,7 +116,6 @@ impl MemoryDirectory {
directory
.domains
.extend(config.parse_lookup_list((&prefix, "lookup.domains"))?);
directory.opt = DirectoryOptions::from_config(config, prefix)?;

Ok(Arc::new(directory))
}
Expand Down
10 changes: 10 additions & 0 deletions crates/directory/src/sql/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ impl Directory for SqlDirectory {
.fetch_all(&self.pool)
.await?;

// Check whether the user is a superuser
if let Some(idx) = principal
.member_of
.iter()
.position(|group| group.eq_ignore_ascii_case(&self.opt.superuser_group))
{
principal.member_of.swap_remove(idx);
principal.typ = Type::Superuser;
}

Ok(Some(principal))
} else {
Ok(None)
Expand Down
56 changes: 26 additions & 30 deletions crates/imap/src/core/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use imap_proto::{protocol::list::Attribute, StatusResponse};
use jmap::{
auth::{acl::EffectiveAcl, AccessToken},
mailbox::INBOX_ID,
SUPERUSER_ID,
};
use jmap_proto::{
object::Object,
Expand Down Expand Up @@ -43,31 +42,29 @@ impl SessionData {

// Fetch shared mailboxes
for &account_id in access_token.shared_accounts(Collection::Mailbox) {
if account_id != SUPERUSER_ID {
match session
.fetch_account_mailboxes(
account_id,
format!(
"{}/{}",
session.imap.name_shared,
session
.jmap
.get_account_name(account_id)
.await
.unwrap_or_default()
.unwrap_or_else(|| Id::from(account_id).to_string())
)
.into(),
access_token,
match session
.fetch_account_mailboxes(
account_id,
format!(
"{}/{}",
session.imap.name_shared,
session
.jmap
.get_account_name(account_id)
.await
.unwrap_or_default()
.unwrap_or_else(|| Id::from(account_id).to_string())
)
.await
{
Ok(account_mailboxes) => {
mailboxes.push(account_mailboxes);
}
Err(_) => {
tracing::warn!(parent: &session.span, account_id = account_id, event = "error", "Failed to retrieve mailboxes.");
}
.into(),
access_token,
)
.await
{
Ok(account_mailboxes) => {
mailboxes.push(account_mailboxes);
}
Err(_) => {
tracing::warn!(parent: &session.span, account_id = account_id, event = "error", "Failed to retrieve mailboxes.");
}
}
}
Expand Down Expand Up @@ -305,11 +302,10 @@ impl SessionData {

// Add new shared account ids
for account_id in has_access_to {
if account_id != SUPERUSER_ID
&& !new_accounts
.iter()
.skip(1)
.any(|m| m.account_id == account_id)
if !new_accounts
.iter()
.skip(1)
.any(|m| m.account_id == account_id)
{
tracing::debug!(parent: &self.span, "Adding shared account {}", account_id);
added_account_ids.push(account_id);
Expand Down
6 changes: 4 additions & 2 deletions crates/imap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ impl IMAP {
})
.into_bytes(),
rate_limiter: DashMap::with_capacity_and_hasher_and_shard_amount(
config.property("imap.rate-limit.size")?.unwrap_or(2048),
config
.property("imap.rate-limit.cache.size")?
.unwrap_or(2048),
RandomState::default(),
config
.property::<u64>("global.shared-map.shard")?
.unwrap_or(32)
.next_power_of_two() as usize,
),
rate_requests: config.property_or_static("imap.rate-limit", "1000/1m")?,
rate_requests: config.property_or_static("imap.rate-limit.requests", "2000/1m")?,
rate_concurrent: config.property("imap.rate-limit.concurrent")?.unwrap_or(4),
allow_plain_auth: config.property_or_static("imap.auth.allow-plain-text", "false")?,
}))
Expand Down
25 changes: 25 additions & 0 deletions crates/install/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "stalwart-install"
description = "Stalwart Mail Server installer"
authors = ["Stalwart Labs Ltd. <hello@stalw.art>"]
license = "AGPL-3.0-only"
repository = "https://github.com/stalwartlabs/mail-server"
homepage = "https://github.com/stalwartlabs/mail-server"
version = "0.3.0"
edition = "2021"
readme = "README.md"
resolver = "2"

[dependencies]
reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-webpki-roots"]}
rusqlite = { version = "0.29.0", features = ["bundled"] }
rpassword = "7.0"
indicatif = "0.17.0"
dialoguer = "0.10.4"
openssl = { version = "0.10.55", features = ["vendored"] }
base64 = "0.21.2"
pwhash = "1.0.0"
rand = "0.8.5"

[target.'cfg(not(target_env = "msvc"))'.dependencies]
libc = "0.2.147"

0 comments on commit 843e611

Please sign in to comment.