Add enterprise feature to directory crate (#783 ).
Some checks are pending
trivy / Check (push) Waiting to run

This commit is contained in:
mdecimus 2024-09-22 10:36:40 +02:00
parent f3943f4a5f
commit 71c3c06c01
7 changed files with 22 additions and 7 deletions

View file

@ -42,3 +42,4 @@ tokio = { version = "1.23", features = ["full"] }
[features] [features]
test_mode = [] test_mode = []
enterprise = []

View file

@ -186,13 +186,14 @@ impl ManageDirectory for Store {
if name.is_empty() { if name.is_empty() {
return Err(err_missing(PrincipalField::Name)); return Err(err_missing(PrincipalField::Name));
} }
let mut valid_domains: AHashSet<String> = AHashSet::new();
// SPDX-SnippetBegin // SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art> // SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
// Validate tenant // Validate tenant
let mut valid_domains = AHashSet::new(); #[cfg(feature = "enterprise")]
if let Some(tenant_id) = tenant_id { if let Some(tenant_id) = tenant_id {
let tenant = self let tenant = self
.query(QueryBy::Id(tenant_id), false) .query(QueryBy::Id(tenant_id), false)
@ -246,6 +247,7 @@ impl ManageDirectory for Store {
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
// Obtain tenant id, only if no default tenant is provided // Obtain tenant id, only if no default tenant is provided
#[cfg(feature = "enterprise")]
if let (Some(tenant_name), None) = (principal.take_str(PrincipalField::Tenant), tenant_id) { if let (Some(tenant_name), None) = (principal.take_str(PrincipalField::Tenant), tenant_id) {
tenant_id = self tenant_id = self
.get_principal_info(&tenant_name) .get_principal_info(&tenant_name)
@ -258,6 +260,7 @@ impl ManageDirectory for Store {
} }
// Tenants must provide principal names including a valid domain // Tenants must provide principal names including a valid domain
#[cfg(feature = "enterprise")]
if let Some(tenant_id) = tenant_id { if let Some(tenant_id) = tenant_id {
if matches!(principal.typ, Type::Tenant) { if matches!(principal.typ, Type::Tenant) {
return Err(error( return Err(error(
@ -475,13 +478,14 @@ impl ManageDirectory for Store {
.await .await
.caused_by(trc::location!())? .caused_by(trc::location!())?
.ok_or_else(|| not_found(principal_id.to_string()))?; .ok_or_else(|| not_found(principal_id.to_string()))?;
let mut batch = BatchBuilder::new();
// SPDX-SnippetBegin // SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art> // SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
// Make sure tenant has no data // Make sure tenant has no data
let mut batch = BatchBuilder::new(); #[cfg(feature = "enterprise")]
match principal.typ { match principal.typ {
Type::Individual | Type::Group => { Type::Individual | Type::Group => {
// Update tenant quota // Update tenant quota
@ -676,12 +680,14 @@ impl ManageDirectory for Store {
); );
} }
let mut used_quota: Option<i64> = None;
// SPDX-SnippetBegin // SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art> // SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
// Obtain used quota // Obtain used quota
let mut used_quota = None; #[cfg(feature = "enterprise")]
if tenant_id.is_none() if tenant_id.is_none()
&& changes && changes
.iter() .iter()
@ -781,6 +787,7 @@ impl ManageDirectory for Store {
// SPDX-SnippetBegin // SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art> // SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
#[cfg(feature = "enterprise")]
( (
PrincipalAction::Set, PrincipalAction::Set,
PrincipalField::Tenant, PrincipalField::Tenant,
@ -1679,6 +1686,7 @@ impl ManageDirectory for Store {
// SPDX-License-Identifier: LicenseRef-SEL // SPDX-License-Identifier: LicenseRef-SEL
// Map tenant name // Map tenant name
#[cfg(feature = "enterprise")]
if let Some(tenant_id) = principal.take_int(PrincipalField::Tenant) { if let Some(tenant_id) = principal.take_int(PrincipalField::Tenant) {
if fields.is_empty() || fields.contains(&PrincipalField::Tenant) { if fields.is_empty() || fields.contains(&PrincipalField::Tenant) {
if let Some(name) = self if let Some(name) = self

View file

@ -98,6 +98,7 @@ impl Deserialize for Principal {
} }
} }
#[cfg(feature = "enterprise")]
impl PrincipalInfo { impl PrincipalInfo {
// SPDX-SnippetBegin // SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art> // SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
@ -113,6 +114,13 @@ impl PrincipalInfo {
// SPDX-SnippetEnd // SPDX-SnippetEnd
} }
#[cfg(not(feature = "enterprise"))]
impl PrincipalInfo {
pub fn has_tenant_access(&self, _tenant_id: Option<u32>) -> bool {
true
}
}
impl Serialize for PrincipalInfo { impl Serialize for PrincipalInfo {
fn serialize(self) -> Vec<u8> { fn serialize(self) -> Vec<u8> {
if let Some(tenant) = self.tenant { if let Some(tenant) = self.tenant {

View file

@ -44,4 +44,4 @@ rocks = ["store/rocks"]
elastic = ["store/elastic"] elastic = ["store/elastic"]
s3 = ["store/s3"] s3 = ["store/s3"]
redis = ["store/redis"] redis = ["store/redis"]
enterprise = ["jmap/enterprise", "common/enterprise", "store/enterprise", "managesieve/enterprise"] enterprise = ["jmap/enterprise", "common/enterprise", "store/enterprise", "managesieve/enterprise", "directory/enterprise"]

View file

@ -151,7 +151,6 @@ KillSignal=SIGINT
Restart=on-failure Restart=on-failure
RestartSec=5 RestartSec=5
ExecStart=__PATH__/bin/stalwart-mail --config=__PATH__/etc/config.toml ExecStart=__PATH__/bin/stalwart-mail --config=__PATH__/etc/config.toml
PermissionsStartOnly=true
SyslogIdentifier=stalwart-mail SyslogIdentifier=stalwart-mail
User=stalwart-mail User=stalwart-mail
Group=stalwart-mail Group=stalwart-mail

View file

@ -12,7 +12,6 @@ KillSignal=SIGINT
Restart=on-failure Restart=on-failure
RestartSec=5 RestartSec=5
ExecStart=__PATH__/bin/stalwart-mail --config=__PATH__/etc/config.toml ExecStart=__PATH__/bin/stalwart-mail --config=__PATH__/etc/config.toml
PermissionsStartOnly=true
SyslogIdentifier=stalwart-mail SyslogIdentifier=stalwart-mail
User=stalwart-mail User=stalwart-mail
Group=stalwart-mail Group=stalwart-mail

View file

@ -19,7 +19,7 @@ redis = ["store/redis"]
[dev-dependencies] [dev-dependencies]
store = { path = "../crates/store", features = ["test_mode", "enterprise"] } store = { path = "../crates/store", features = ["test_mode", "enterprise"] }
nlp = { path = "../crates/nlp" } nlp = { path = "../crates/nlp" }
directory = { path = "../crates/directory", features = ["test_mode"] } directory = { path = "../crates/directory", features = ["test_mode", "enterprise"] }
jmap = { path = "../crates/jmap", features = ["test_mode", "enterprise"] } jmap = { path = "../crates/jmap", features = ["test_mode", "enterprise"] }
jmap_proto = { path = "../crates/jmap-proto" } jmap_proto = { path = "../crates/jmap-proto" }
imap = { path = "../crates/imap", features = ["test_mode"] } imap = { path = "../crates/imap", features = ["test_mode"] }