From e10aa551eba2f42fddacd2b44ed32a17fe98e6d5 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Mon, 18 Aug 2025 11:44:58 +0100 Subject: [PATCH] Clippy fixes --- crates/cli/src/modules/import.rs | 23 +- crates/common/src/addresses.rs | 10 +- crates/common/src/auth/access_token.rs | 53 ++-- crates/common/src/auth/mod.rs | 24 +- crates/common/src/auth/rate_limit.rs | 35 ++- crates/common/src/config/spamfilter.rs | 9 +- crates/common/src/config/telemetry.rs | 55 ++-- crates/common/src/core.rs | 68 ++--- crates/common/src/expr/eval.rs | 4 +- crates/common/src/listener/listen.rs | 32 +-- crates/common/src/manager/boot.rs | 13 +- crates/common/src/sharing/resources.rs | 32 +-- crates/common/src/telemetry/tracers/otel.rs | 48 ++-- crates/dav-proto/src/parser/tokenizer.rs | 2 +- crates/dav/src/calendar/query.rs | 52 ++-- crates/dav/src/card/query.rs | 10 +- crates/dav/src/common/lock.rs | 27 +- crates/dav/src/common/propfind.rs | 27 +- crates/dav/src/file/copy_move.rs | 19 +- crates/dav/src/lib.rs | 2 +- .../directory/src/backend/internal/lookup.rs | 64 ++--- .../directory/src/backend/internal/manage.rs | 81 +++--- crates/directory/src/backend/ldap/lookup.rs | 29 +- crates/directory/src/backend/sql/lookup.rs | 8 +- crates/directory/src/core/dispatch.rs | 16 +- crates/directory/src/core/mod.rs | 1 + crates/directory/src/core/principal.rs | 20 +- crates/email/src/cache/email.rs | 17 +- crates/email/src/cache/mailbox.rs | 17 +- crates/email/src/message/delete.rs | 42 +-- crates/email/src/message/ingest.rs | 271 +++++++++--------- crates/email/src/sieve/activate.rs | 35 ++- crates/email/src/sieve/ingest.rs | 30 +- crates/groupware/src/calendar/alarm.rs | 96 +++---- crates/http/src/auth/authenticate.rs | 7 +- crates/http/src/autoconfig/mod.rs | 29 +- crates/http/src/form/mod.rs | 35 ++- crates/http/src/management/principal.rs | 25 +- crates/http/src/management/queue.rs | 43 +-- crates/http/src/management/report.rs | 45 ++- crates/http/src/management/settings.rs | 30 +- crates/http/src/request.rs | 15 +- crates/imap-proto/src/protocol/capability.rs | 2 +- crates/imap-proto/src/protocol/expunge.rs | 2 +- crates/imap-proto/src/protocol/quota.rs | 2 +- crates/imap-proto/src/protocol/search.rs | 16 +- crates/imap-proto/src/protocol/status.rs | 4 +- crates/imap-proto/src/protocol/thread.rs | 2 +- crates/imap/src/core/client.rs | 47 ++- crates/imap/src/core/mailbox.rs | 11 +- crates/imap/src/core/session.rs | 12 +- crates/imap/src/op/create.rs | 8 +- crates/imap/src/op/fetch.rs | 76 +++-- crates/imap/src/op/subscribe.rs | 22 +- crates/imap/src/op/thread.rs | 8 +- crates/jmap-proto/src/error/request.rs | 4 +- crates/jmap-proto/src/response/references.rs | 38 +-- crates/jmap-proto/src/types/value.rs | 17 +- crates/jmap/src/changes/state.rs | 16 +- crates/jmap/src/lib.rs | 8 +- crates/jmap/src/mailbox/query.rs | 8 +- crates/jmap/src/sieve/set.rs | 18 +- crates/jmap/src/submission/get.rs | 58 ++-- crates/jmap/src/submission/set.rs | 48 ++-- crates/jmap/src/vacation/set.rs | 15 +- crates/managesieve/src/core/client.rs | 11 +- crates/managesieve/src/core/session.rs | 11 +- crates/migration/src/submission.rs | 32 +-- crates/nlp/src/tokenizers/space.rs | 2 +- crates/nlp/src/tokenizers/types.rs | 11 +- crates/nlp/src/tokenizers/word.rs | 2 +- crates/pop3/src/session.rs | 13 +- crates/services/src/housekeeper/mod.rs | 55 ++-- crates/services/src/state_manager/manager.rs | 48 ++-- crates/services/src/task_manager/imip.rs | 129 ++++----- crates/smtp/src/inbound/data.rs | 50 ++-- crates/smtp/src/inbound/ehlo.rs | 14 +- crates/smtp/src/inbound/spawn.rs | 15 +- crates/smtp/src/outbound/delivery.rs | 52 ++-- crates/smtp/src/outbound/mta_sts/lookup.rs | 8 +- crates/smtp/src/outbound/mta_sts/verify.rs | 8 +- crates/smtp/src/queue/dsn.rs | 34 +-- crates/smtp/src/reporting/tls.rs | 8 +- crates/spam-filter/src/analysis/bayes.rs | 27 +- crates/spam-filter/src/analysis/domain.rs | 23 +- crates/spam-filter/src/analysis/from.rs | 43 ++- crates/spam-filter/src/analysis/ip.rs | 18 +- crates/spam-filter/src/analysis/mime.rs | 18 +- crates/spam-filter/src/analysis/received.rs | 18 +- crates/spam-filter/src/analysis/recipient.rs | 10 +- .../spam-filter/src/analysis/trusted_reply.rs | 20 +- crates/spam-filter/src/analysis/url.rs | 17 +- crates/spam-filter/src/modules/dnsbl.rs | 10 +- crates/spam-filter/src/modules/pyzor.rs | 14 +- crates/store/src/backend/mysql/main.rs | 6 +- crates/store/src/backend/postgres/main.rs | 6 +- crates/store/src/config.rs | 8 +- crates/utils/src/json/pointer.rs | 8 +- tests/src/imap/mod.rs | 30 +- tests/src/lib.rs | 8 +- tests/src/smtp/inbound/antispam.rs | 8 +- tests/src/smtp/queue/manager.rs | 9 +- 102 files changed, 1336 insertions(+), 1411 deletions(-) diff --git a/crates/cli/src/modules/import.rs b/crates/cli/src/modules/import.rs index 2db88540..94bba580 100644 --- a/crates/cli/src/modules/import.rs +++ b/crates/cli/src/modules/import.rs @@ -473,20 +473,19 @@ async fn import_mailboxes( for (path, mailbox) in build_mailbox_tree(&mailboxes) { let id = mailbox.id().unwrap_result("obtain mailbox id"); // Find existing mailbox based on role - if !matches!(mailbox.role(), Role::None) { - if let Some(existing_mailbox) = existing_mailboxes + if !matches!(mailbox.role(), Role::None) + && let Some(existing_mailbox) = existing_mailboxes .iter() .find(|m| m.role() == mailbox.role()) - { - id_mappings.insert( - id.to_string(), - existing_mailbox - .id() - .unwrap_result("obtain mailbox id") - .to_string(), - ); - continue; - } + { + id_mappings.insert( + id.to_string(), + existing_mailbox + .id() + .unwrap_result("obtain mailbox id") + .to_string(), + ); + continue; } // Find existing mailbox by name diff --git a/crates/common/src/addresses.rs b/crates/common/src/addresses.rs index f3a6649b..06949669 100644 --- a/crates/common/src/addresses.rs +++ b/crates/common/src/addresses.rs @@ -168,7 +168,7 @@ impl AddressMapping { struct Address<'x>(&'x str); impl ResolveVariable for Address<'_> { - fn resolve_variable(&self, _: u32) -> crate::expr::Variable { + fn resolve_variable(&'_ self, _: u32) -> crate::expr::Variable<'_> { Variable::from(self.0) } @@ -186,10 +186,10 @@ impl AddressMapping { ) -> Cow<'x, str> { match self { AddressMapping::Enable => { - if let Some((local_part, domain_part)) = address.rsplit_once('@') { - if let Some((local_part, _)) = local_part.split_once('+') { - return format!("{}@{}", local_part, domain_part).into(); - } + if let Some((local_part, domain_part)) = address.rsplit_once('@') + && let Some((local_part, _)) = local_part.split_once('+') + { + return format!("{}@{}", local_part, domain_part).into(); } } AddressMapping::Custom(if_block) => { diff --git a/crates/common/src/auth/access_token.rs b/crates/common/src/auth/access_token.rs index 6bd37c81..1159eca7 100644 --- a/crates/common/src/auth/access_token.rs +++ b/crates/common/src/auth/access_token.rs @@ -69,32 +69,32 @@ impl Server { // SPDX-License-Identifier: LicenseRef-SEL #[cfg(feature = "enterprise")] - if self.is_enterprise_edition() { - if let Some(tenant_id) = principal.tenant { - // Limit tenant permissions + if self.is_enterprise_edition() + && let Some(tenant_id) = principal.tenant + { + // Limit tenant permissions - use directory::QueryParams; - permissions.intersection(&self.get_role_permissions(tenant_id).await?.enabled); + use directory::QueryParams; + permissions.intersection(&self.get_role_permissions(tenant_id).await?.enabled); - // Obtain tenant quota - tenant = Some(TenantInfo { - id: tenant_id, - quota: self - .store() - .query(QueryParams::id(tenant_id).with_return_member_of(false)) - .await - .caused_by(trc::location!())? - .ok_or_else(|| { - trc::SecurityEvent::Unauthorized - .into_err() - .details("Tenant not found") - .id(tenant_id) - .caused_by(trc::location!()) - })? - .quota - .unwrap_or_default(), - }); - } + // Obtain tenant quota + tenant = Some(TenantInfo { + id: tenant_id, + quota: self + .store() + .query(QueryParams::id(tenant_id).with_return_member_of(false)) + .await + .caused_by(trc::location!())? + .ok_or_else(|| { + trc::SecurityEvent::Unauthorized + .into_err() + .details("Tenant not found") + .id(tenant_id) + .caused_by(trc::location!()) + })? + .quota + .unwrap_or_default(), + }); } // SPDX-SnippetEnd @@ -112,10 +112,9 @@ impl Server { .query(QueryParams::id(group_id).with_return_member_of(false)) .await .caused_by(trc::location!())? + && group.typ == Type::Group { - if group.typ == Type::Group { - emails.extend(group.emails); - } + emails.extend(group.emails); } } diff --git a/crates/common/src/auth/mod.rs b/crates/common/src/auth/mod.rs index cddcc2a7..f8bc6692 100644 --- a/crates/common/src/auth/mod.rs +++ b/crates/common/src/auth/mod.rs @@ -167,26 +167,24 @@ impl Server { } _ => { // Validate API credentials - if req.allow_api_access { - if let Ok(Some(principal)) = self + if req.allow_api_access + && let Ok(Some(principal)) = self .store() .query( QueryParams::credentials(&req.credentials) .with_return_member_of(req.return_member_of), ) .await - { - if principal.typ == Type::ApiKey { - trc::event!( - Auth(trc::AuthEvent::Success), - AccountName = principal.name().to_string(), - AccountId = principal.id(), - SpanId = req.session_id, - ); + && principal.typ == Type::ApiKey + { + trc::event!( + Auth(trc::AuthEvent::Success), + AccountName = principal.name().to_string(), + AccountId = principal.id(), + SpanId = req.session_id, + ); - return Ok(principal); - } - } + return Ok(principal); } } } diff --git a/crates/common/src/auth/rate_limit.rs b/crates/common/src/auth/rate_limit.rs index 22e26029..59bd9f16 100644 --- a/crates/common/src/auth/rate_limit.rs +++ b/crates/common/src/auth/rate_limit.rs @@ -57,24 +57,23 @@ impl Server { } pub async fn is_http_anonymous_request_allowed(&self, addr: &IpAddr) -> trc::Result<()> { - if let Some(rate) = &self.core.jmap.rate_anonymous { - if !self.is_ip_allowed(addr) - && self - .core - .storage - .lookup - .is_rate_allowed( - KV_RATE_LIMIT_HTTP_ANONYMOUS, - &ip_to_bytes(addr), - rate, - false, - ) - .await - .caused_by(trc::location!())? - .is_some() - { - return Err(trc::LimitEvent::TooManyRequests.into_err()); - } + if let Some(rate) = &self.core.jmap.rate_anonymous + && !self.is_ip_allowed(addr) + && self + .core + .storage + .lookup + .is_rate_allowed( + KV_RATE_LIMIT_HTTP_ANONYMOUS, + &ip_to_bytes(addr), + rate, + false, + ) + .await + .caused_by(trc::location!())? + .is_some() + { + return Err(trc::LimitEvent::TooManyRequests.into_err()); } Ok(()) } diff --git a/crates/common/src/config/spamfilter.rs b/crates/common/src/config/spamfilter.rs index 279afae5..95584f03 100644 --- a/crates/common/src/config/spamfilter.rs +++ b/crates/common/src/config/spamfilter.rs @@ -331,12 +331,11 @@ impl SpamFilterHeaderConfig { if config .property_or_default(("spam-filter.header", typ, "enable"), "true") .unwrap_or(true) + && let Some(value) = config.value(("spam-filter.header", typ, "name")) { - if let Some(value) = config.value(("spam-filter.header", typ, "name")) { - let value = value.trim(); - if !value.is_empty() { - *var = value.to_string().into(); - } + let value = value.trim(); + if !value.is_empty() { + *var = value.to_string().into(); } } } diff --git a/crates/common/src/config/telemetry.rs b/crates/common/src/config/telemetry.rs index db395f1c..33f21390 100644 --- a/crates/common/src/config/telemetry.rs +++ b/crates/common/src/config/telemetry.rs @@ -171,12 +171,10 @@ impl Tracers { { if let Some(event_type) = config.try_parse_value::(("tracing.level", &event_name), &event_name) - { - if let Some(level) = + && let Some(level) = config.property_require::(("tracing.level", &event_name)) - { - custom_levels.insert(event_type, level); - } + { + custom_levels.insert(event_type, level); } } @@ -531,28 +529,27 @@ impl Tracers { if config .property_or_default("tracing.history.enable", "false") .unwrap_or(false) + && let Some(store_id) = config.value_require("tracing.history.store") { - if let Some(store_id) = config.value_require("tracing.history.store") { - if let Some(store) = stores.stores.get(store_id) { - let mut tracer = TelemetrySubscriber { - id: "history".to_string(), - interests: Default::default(), - lossy: false, - typ: TelemetrySubscriberType::StoreTracer(StoreTracer { - store: store.clone(), - }), - }; + if let Some(store) = stores.stores.get(store_id) { + let mut tracer = TelemetrySubscriber { + id: "history".to_string(), + interests: Default::default(), + lossy: false, + typ: TelemetrySubscriberType::StoreTracer(StoreTracer { + store: store.clone(), + }), + }; - for event_type in StoreTracer::default_events() { - tracer.interests.set(event_type); - global_interests.set(event_type); - } - - tracers.push(tracer); - } else { - let err = format!("Store {store_id} not found"); - config.new_build_error("tracing.history.store", err); + for event_type in StoreTracer::default_events() { + tracer.interests.set(event_type); + global_interests.set(event_type); } + + tracers.push(tracer); + } else { + let err = format!("Store {store_id} not found"); + config.new_build_error("tracing.history.store", err); } } } @@ -617,14 +614,12 @@ impl Metrics { .value(("tracer", tracer_id, "type")) .unwrap_or_default() == "log" - { - if let Some(path) = config + && let Some(path) = config .value(("tracer", tracer_id, "path")) .map(|s| s.to_string()) - { - metrics.log_path = Some(path); - break; - } + { + metrics.log_path = Some(path); + break; } } diff --git a/crates/common/src/core.rs b/crates/common/src/core.rs index 167a2bc2..e03d1825 100644 --- a/crates/common/src/core.rs +++ b/crates/common/src/core.rs @@ -412,16 +412,16 @@ impl Server { // SPDX-License-Identifier: LicenseRef-SEL #[cfg(feature = "enterprise")] - if self.core.is_enterprise_edition() { - if let Some(tenant) = quotas.tenant.filter(|tenant| tenant.quota != 0) { - let used_quota = self.get_used_quota(tenant.id).await? as u64; + if self.core.is_enterprise_edition() + && let Some(tenant) = quotas.tenant.filter(|tenant| tenant.quota != 0) + { + let used_quota = self.get_used_quota(tenant.id).await? as u64; - if used_quota + item_size > tenant.quota { - return Err(trc::LimitEvent::TenantQuota - .into_err() - .ctx(trc::Key::Limit, tenant.quota) - .ctx(trc::Key::Size, used_quota)); - } + if used_quota + item_size > tenant.quota { + return Err(trc::LimitEvent::TenantQuota + .into_err() + .ctx(trc::Key::Limit, tenant.quota) + .ctx(trc::Key::Size, used_quota)); } } @@ -462,24 +462,24 @@ impl Server { // SPDX-License-Identifier: LicenseRef-SEL #[cfg(feature = "enterprise")] - if self.core.is_enterprise_edition() { - if let Some(tenant_id) = principal.tenant() { - quotas.tenant = TenantInfo { - id: tenant_id, - quota: self - .core - .storage - .directory - .query(QueryParams::id(tenant_id).with_return_member_of(false)) - .await - .add_context(|err| { - err.caused_by(trc::location!()).account_id(tenant_id) - })? - .map(|tenant| tenant.quota()) - .unwrap_or_default(), - } - .into(); + if self.core.is_enterprise_edition() + && let Some(tenant_id) = principal.tenant() + { + quotas.tenant = TenantInfo { + id: tenant_id, + quota: self + .core + .storage + .directory + .query(QueryParams::id(tenant_id).with_return_member_of(false)) + .await + .add_context(|err| { + err.caused_by(trc::location!()).account_id(tenant_id) + })? + .map(|tenant| tenant.quota()) + .unwrap_or_default(), } + .into(); } // SPDX-SnippetEnd @@ -804,14 +804,14 @@ impl Server { } pub async fn cluster_broadcast(&self, event: BroadcastEvent) { - if let Some(broadcast_tx) = &self.inner.ipc.broadcast_tx.clone() { - if broadcast_tx.send(event).await.is_err() { - trc::event!( - Server(trc::ServerEvent::ThreadError), - Details = "Error sending broadcast event.", - CausedBy = trc::location!() - ); - } + if let Some(broadcast_tx) = &self.inner.ipc.broadcast_tx.clone() + && broadcast_tx.send(event).await.is_err() + { + trc::event!( + Server(trc::ServerEvent::ThreadError), + Details = "Error sending broadcast event.", + CausedBy = trc::location!() + ); } } diff --git a/crates/common/src/expr/eval.rs b/crates/common/src/expr/eval.rs index b756cff1..41d8b5b8 100644 --- a/crates/common/src/expr/eval.rs +++ b/crates/common/src/expr/eval.rs @@ -498,7 +498,7 @@ impl<'x> Variable<'x> { } } - pub fn to_string(&self) -> StringCow { + pub fn to_string(&'_ self) -> StringCow<'_> { match self { Variable::String(s) => StringCow::Borrowed(s.as_str()), Variable::Integer(n) => StringCow::Owned(n.to_compact_string()), @@ -577,7 +577,7 @@ impl<'x> Variable<'x> { } } - pub fn as_array(&self) -> Option<&[Variable]> { + pub fn as_array(&'_ self) -> Option<&'_ [Variable<'_>]> { match self { Variable::Array(l) => Some(l), _ => None, diff --git a/crates/common/src/listener/listen.rs b/crates/common/src/listener/listen.rs index 4b7f0deb..da0b6f0a 100644 --- a/crates/common/src/listener/listen.rs +++ b/crates/common/src/listener/listen.rs @@ -279,23 +279,23 @@ impl SocketOpts { Details = "Failed to set TCP_NODELAY", ); } - if let Some(ttl) = self.ttl { - if let Err(err) = stream.set_ttl(ttl) { - trc::event!( - Network(trc::NetworkEvent::SetOptError), - Reason = err.to_string(), - Details = "Failed to set TTL", - ); - } + if let Some(ttl) = self.ttl + && let Err(err) = stream.set_ttl(ttl) + { + trc::event!( + Network(trc::NetworkEvent::SetOptError), + Reason = err.to_string(), + Details = "Failed to set TTL", + ); } - if self.linger.is_some() { - if let Err(err) = stream.set_linger(self.linger) { - trc::event!( - Network(trc::NetworkEvent::SetOptError), - Reason = err.to_string(), - Details = "Failed to set LINGER", - ); - } + if self.linger.is_some() + && let Err(err) = stream.set_linger(self.linger) + { + trc::event!( + Network(trc::NetworkEvent::SetOptError), + Reason = err.to_string(), + Details = "Failed to set LINGER", + ); } } } diff --git a/crates/common/src/manager/boot.rs b/crates/common/src/manager/boot.rs index ef9c8c07..c26edd08 100644 --- a/crates/common/src/manager/boot.rs +++ b/crates/common/src/manager/boot.rs @@ -462,14 +462,13 @@ impl BootManager { if config .property_or_default::("spam-filter.auto-update", "false") .unwrap_or_default() + && let Err(err) = core.storage.config.update_spam_rules(false, false).await { - if let Err(err) = core.storage.config.update_spam_rules(false, false).await { - trc::event!( - Resource(trc::ResourceEvent::Error), - Details = "Failed to update spam-filter", - CausedBy = err - ); - } + trc::event!( + Resource(trc::ResourceEvent::Error), + Details = "Failed to update spam-filter", + CausedBy = err + ); } // Build shared inner diff --git a/crates/common/src/sharing/resources.rs b/crates/common/src/sharing/resources.rs index c3ec3462..14bbf9e7 100644 --- a/crates/common/src/sharing/resources.rs +++ b/crates/common/src/sharing/resources.rs @@ -45,17 +45,17 @@ impl DavResources { let check_acls = check_acls.into(); for resource in &self.resources { - if resource.document_id == document_id { - if let Some(acls) = resource.acls() { - for acl in acls { - if access_token.is_member(acl.account_id) { - let mut grants = acl.grants; - grants.intersection(&check_acls); - return !grants.is_empty(); - } + if resource.document_id == document_id + && let Some(acls) = resource.acls() + { + for acl in acls { + if access_token.is_member(acl.account_id) { + let mut grants = acl.grants; + grants.intersection(&check_acls); + return !grants.is_empty(); } - break; } + break; } } @@ -66,15 +66,15 @@ impl DavResources { let mut account_acls = Bitmap::::new(); for resource in &self.resources { - if resource.document_id == document_id { - if let Some(acls) = resource.acls() { - for acl in acls { - if access_token.is_member(acl.account_id) { - account_acls.union(&acl.grants); - } + if resource.document_id == document_id + && let Some(acls) = resource.acls() + { + for acl in acls { + if access_token.is_member(acl.account_id) { + account_acls.union(&acl.grants); } - break; } + break; } } diff --git a/crates/common/src/telemetry/tracers/otel.rs b/crates/common/src/telemetry/tracers/otel.rs index 50fc5f5e..47188f28 100644 --- a/crates/common/src/telemetry/tracers/otel.rs +++ b/crates/common/src/telemetry/tracers/otel.rs @@ -57,23 +57,22 @@ pub(crate) fn spawn_otel_tracer(builder: SubscriberBuilder, mut otel: OtelTracer pending_logs.push(otel.build_log_record(&event)); } - if otel.span_exporter_enable { - if let Some(span) = event.inner.span.as_ref() { - let span_id = span.span_id().unwrap(); - if !event.inner.typ.is_span_end() { - let events = - active_spans.entry(span_id).or_insert_with(Vec::new); - if events.len() < MAX_EVENTS { - events.push(event); - } - } else if let Some(events) = active_spans.remove(&span_id) { - pending_spans.push(build_span_data( - span, - &event, - events.iter().chain(std::iter::once(&event)), - &instrumentation, - )); + if otel.span_exporter_enable + && let Some(span) = event.inner.span.as_ref() + { + let span_id = span.span_id().unwrap(); + if !event.inner.typ.is_span_end() { + let events = active_spans.entry(span_id).or_insert_with(Vec::new); + if events.len() < MAX_EVENTS { + events.push(event); } + } else if let Some(events) = active_spans.remove(&span_id) { + pending_spans.push(build_span_data( + span, + &event, + events.iter().chain(std::iter::once(&event)), + &instrumentation, + )); } } } @@ -91,18 +90,17 @@ pub(crate) fn spawn_otel_tracer(builder: SubscriberBuilder, mut otel: OtelTracer if !pending_spans.is_empty() || !pending_logs.is_empty() { next_delivery = now + otel.throttle; - if !pending_spans.is_empty() { - if let Err(err) = otel + if !pending_spans.is_empty() + && let Err(err) = otel .span_exporter .export(std::mem::take(&mut pending_spans)) .await - { - trc::event!( - Telemetry(TelemetryEvent::OtelExporterError), - Details = "Failed to export spans", - Reason = err.to_string() - ); - } + { + trc::event!( + Telemetry(TelemetryEvent::OtelExporterError), + Details = "Failed to export spans", + Reason = err.to_string() + ); } if !pending_logs.is_empty() { diff --git a/crates/dav-proto/src/parser/tokenizer.rs b/crates/dav-proto/src/parser/tokenizer.rs index fdf9e5fa..8500b3b2 100644 --- a/crates/dav-proto/src/parser/tokenizer.rs +++ b/crates/dav-proto/src/parser/tokenizer.rs @@ -29,7 +29,7 @@ impl<'x> Tokenizer<'x> { } } - pub fn token(&mut self) -> super::Result { + pub fn token(&'_ mut self) -> super::Result> { loop { if self.last_is_end { self.last_is_end = false; diff --git a/crates/dav/src/calendar/query.rs b/crates/dav/src/calendar/query.rs index 384a3d2c..970763e8 100644 --- a/crates/dav/src/calendar/query.rs +++ b/crates/dav/src/calendar/query.rs @@ -275,11 +275,11 @@ impl CalendarQueryHandler { let mut matched_any = false; for value in entry.values.iter() { - if let Some(text) = value.as_text() { - if text_match.matches(text) { - matched_any = true; - break; - } + if let Some(text) = value.as_text() + && text_match.matches(text) + { + matched_any = true; + break; } } @@ -443,31 +443,29 @@ impl CalendarQueryHandler { .unwrap(); // Limit recurrence override - if let Some(limit_recurrence) = &data.limit_recurrence { - if component.is_recurrence_override() - && !self.expanded_times.iter().any(|event| { - event.comp_id == component_id - && limit_recurrence.is_in_range( - component.component_type == ICalendarComponentType::VTodo, - event.start, - event.end, - ) - }) - { - continue; - } + if let Some(limit_recurrence) = &data.limit_recurrence + && component.is_recurrence_override() + && !self.expanded_times.iter().any(|event| { + event.comp_id == component_id + && limit_recurrence.is_in_range( + component.component_type == ICalendarComponentType::VTodo, + event.start, + event.end, + ) + }) + { + continue; } // Limit freebusy - if let Some(limit_recurrence) = &data.limit_freebusy { - if component.component_type == ICalendarComponentType::VFreebusy - && !self.expanded_times.iter().any(|event| { - event.comp_id == component_id - && limit_recurrence.is_in_range(false, event.start, event.end) - }) - { - continue; - } + if let Some(limit_recurrence) = &data.limit_freebusy + && component.component_type == ICalendarComponentType::VFreebusy + && !self.expanded_times.iter().any(|event| { + event.comp_id == component_id + && limit_recurrence.is_in_range(false, event.start, event.end) + }) + { + continue; } // Filter entries diff --git a/crates/dav/src/card/query.rs b/crates/dav/src/card/query.rs index ced6a35c..3d5cf450 100644 --- a/crates/dav/src/card/query.rs +++ b/crates/dav/src/card/query.rs @@ -124,11 +124,11 @@ pub(crate) fn vcard_query(card: &ArchivedVCard, filters: &AddressbookFilter) -> let mut matched_any = false; for value in entry.values.iter() { - if let Some(text) = value.as_text() { - if text_match.matches(text) { - matched_any = true; - break; - } + if let Some(text) = value.as_text() + && text_match.matches(text) + { + matched_any = true; + break; } } diff --git a/crates/dav/src/common/lock.rs b/crates/dav/src/common/lock.rs index 4a16a05b..6931bc5f 100644 --- a/crates/dav/src/common/lock.rs +++ b/crates/dav/src/common/lock.rs @@ -526,8 +526,7 @@ impl LockRequestHandler for Server { if let Some(document_id) = resource_state.document_id.filter(|&id| id != u32::MAX) - { - if let Some(archive) = self + && let Some(archive) = self .get_archive( resource_state.account_id, resource_state.collection, @@ -535,22 +534,22 @@ impl LockRequestHandler for Server { ) .await .caused_by(trc::location!())? - { - resource_state.etag = archive.etag().into(); - } + { + resource_state.etag = archive.etag().into(); } } // Fetch lock token - if needs_lock_token && resource_state.lock_tokens.is_empty() { - if let Some(idx) = locks.find_cache_pos(self, resource_state).await? { - let found_locks = locks - .find_locks_by_pos(idx, resource_state, false)? - .iter() - .map(|(_, lock)| lock.urn().to_string()) - .collect::>(); - resource_state.lock_tokens = found_locks; - } + if needs_lock_token + && resource_state.lock_tokens.is_empty() + && let Some(idx) = locks.find_cache_pos(self, resource_state).await? + { + let found_locks = locks + .find_locks_by_pos(idx, resource_state, false)? + .iter() + .map(|(_, lock)| lock.urn().to_string()) + .collect::>(); + resource_state.lock_tokens = found_locks; } // Fetch sync token diff --git a/crates/dav/src/common/propfind.rs b/crates/dav/src/common/propfind.rs index 48cff6eb..5e15dcfb 100644 --- a/crates/dav/src/common/propfind.rs +++ b/crates/dav/src/common/propfind.rs @@ -1090,12 +1090,11 @@ impl PropFindRequestHandler for Server { } // Add dead properties - if skip_not_found { - if let Some(dead_properties) = + if skip_not_found + && let Some(dead_properties) = dead_properties.filter(|dead_properties| !dead_properties.0.is_empty()) - { - dead_properties.to_dav_values(&mut fields); - } + { + dead_properties.to_dav_values(&mut fields); } // Add response @@ -1297,15 +1296,15 @@ async fn get( } } - if maybe_has_vanished { - if let Some(vanished_collection) = sync_collection.vanished_collection() { - vanished = server - .store() - .vanished(account_id, vanished_collection, Query::Since(id)) - .await - .caused_by(trc::location!())?; - total_changes += vanished.len(); - } + if maybe_has_vanished + && let Some(vanished_collection) = sync_collection.vanished_collection() + { + vanished = server + .store() + .vanished(account_id, vanished_collection, Query::Since(id)) + .await + .caused_by(trc::location!())?; + total_changes += vanished.len(); } // Truncate changes diff --git a/crates/dav/src/file/copy_move.rs b/crates/dav/src/file/copy_move.rs index a7179f3c..0ba6be61 100644 --- a/crates/dav/src/file/copy_move.rs +++ b/crates/dav/src/file/copy_move.rs @@ -146,16 +146,15 @@ impl FileCopyMoveRequestHandler for Server { // Validate destination ACLs if let Some(document_id) = destination.document_id { - if let Some(delete_destination) = &delete_destination { - if !access_token.is_member(to_account_id) - && !from_resources.has_access_to_container( - access_token, - delete_destination.document_id.unwrap(), - Acl::Delete, - ) - { - return Err(DavError::Code(StatusCode::FORBIDDEN)); - } + if let Some(delete_destination) = &delete_destination + && !access_token.is_member(to_account_id) + && !from_resources.has_access_to_container( + access_token, + delete_destination.document_id.unwrap(), + Acl::Delete, + ) + { + return Err(DavError::Code(StatusCode::FORBIDDEN)); } if !access_token.is_member(to_account_id) diff --git a/crates/dav/src/lib.rs b/crates/dav/src/lib.rs index 244b59f4..61b105d5 100644 --- a/crates/dav/src/lib.rs +++ b/crates/dav/src/lib.rs @@ -235,7 +235,7 @@ impl PropStatBuilder { } // Workaround for Apple bug with missing percent encoding in paths -pub(crate) fn fix_percent_encoding(path: &str) -> Cow { +pub(crate) fn fix_percent_encoding(path: &'_ str) -> Cow<'_, str> { let (parent, name) = if let Some((parent, name)) = path.rsplit_once('/') { (Some(parent), name) } else { diff --git a/crates/directory/src/backend/internal/lookup.rs b/crates/directory/src/backend/internal/lookup.rs index bd2b4e31..01ce9f1a 100644 --- a/crates/directory/src/backend/internal/lookup.rs +++ b/crates/directory/src/backend/internal/lookup.rs @@ -45,39 +45,39 @@ impl DirectoryStore for Store { }, }; - if let Some(account_id) = account_id { - if let Some(mut principal) = self.get_principal(account_id).await? { - if let Some(secret) = secret { - if !principal.verify_secret(secret, by.only_app_pass).await? { - return Ok(None); - } - } - - if by.return_member_of { - let mut roles = vec![]; - let mut lists = vec![]; - let mut member_of = vec![]; - - for member in self.get_member_of(principal.id).await? { - match member.typ { - Type::List => lists.push(member.principal_id), - Type::Role => roles.push(member.principal_id), - _ => member_of.push(member.principal_id), - } - } - - if !roles.is_empty() { - principal.data.push(PrincipalData::Roles(roles)); - } - if !lists.is_empty() { - principal.data.push(PrincipalData::Lists(lists)); - } - if !member_of.is_empty() { - principal.data.push(PrincipalData::MemberOf(member_of)); - } - } - return Ok(Some(principal)); + if let Some(account_id) = account_id + && let Some(mut principal) = self.get_principal(account_id).await? + { + if let Some(secret) = secret + && !principal.verify_secret(secret, by.only_app_pass).await? + { + return Ok(None); } + + if by.return_member_of { + let mut roles = vec![]; + let mut lists = vec![]; + let mut member_of = vec![]; + + for member in self.get_member_of(principal.id).await? { + match member.typ { + Type::List => lists.push(member.principal_id), + Type::Role => roles.push(member.principal_id), + _ => member_of.push(member.principal_id), + } + } + + if !roles.is_empty() { + principal.data.push(PrincipalData::Roles(roles)); + } + if !lists.is_empty() { + principal.data.push(PrincipalData::Lists(lists)); + } + if !member_of.is_empty() { + principal.data.push(PrincipalData::MemberOf(member_of)); + } + } + return Ok(Some(principal)); } Ok(None) } diff --git a/crates/directory/src/backend/internal/manage.rs b/crates/directory/src/backend/internal/manage.rs index 0182c1e4..7794e123 100644 --- a/crates/directory/src/backend/internal/manage.rs +++ b/crates/directory/src/backend/internal/manage.rs @@ -354,16 +354,15 @@ impl ManageDirectory for Store { principal_create.tenant = tenant_id.into(); if !matches!(principal_create.typ, Type::Tenant | Type::Domain) { - if let Some(domain) = name.split('@').nth(1) { - if self + if let Some(domain) = name.split('@').nth(1) + && self .get_principal_info(domain) .await .caused_by(trc::location!())? .filter(|v| v.typ == Type::Domain && v.has_tenant_access(tenant_id.into())) .is_some() - { - valid_domains.insert(domain.into()); - } + { + valid_domains.insert(domain.into()); } if valid_domains.is_empty() { @@ -524,14 +523,14 @@ impl ManageDirectory for Store { if self.rcpt(&email).await.caused_by(trc::location!())? != RcptType::Invalid { return Err(err_exists(PrincipalField::Emails, email.to_string())); } - if let Some(domain) = email.split('@').nth(1) { - if valid_domains.insert(domain.into()) { - self.get_principal_info(domain) - .await - .caused_by(trc::location!())? - .filter(|v| v.typ == Type::Domain && v.has_tenant_access(tenant_id)) - .ok_or_else(|| not_found(domain.to_string()))?; - } + if let Some(domain) = email.split('@').nth(1) + && valid_domains.insert(domain.into()) + { + self.get_principal_info(domain) + .await + .caused_by(trc::location!())? + .filter(|v| v.typ == Type::Domain && v.has_tenant_access(tenant_id)) + .ok_or_else(|| not_found(domain.to_string()))?; } principal_create.emails.push(email); } @@ -1004,8 +1003,8 @@ impl ManageDirectory for Store { if tenant_id.is_some() && !matches!(principal_type, Type::Tenant | Type::Domain) { - if let Some(domain) = new_name.split('@').nth(1) { - if self + if let Some(domain) = new_name.split('@').nth(1) + && self .get_principal_info(domain) .await .caused_by(trc::location!())? @@ -1013,9 +1012,8 @@ impl ManageDirectory for Store { v.typ == Type::Domain && v.has_tenant_access(tenant_id) }) .is_some() - { - valid_domains.insert(domain.to_string()); - } + { + valid_domains.insert(domain.to_string()); } if valid_domains.is_empty() { @@ -1574,19 +1572,18 @@ impl ManageDirectory for Store { for member_id in &members { if !new_members.contains(member_id) { // Update changed principal ids - if principal_type != Type::List { - if let Some(member_info) = self + if principal_type != Type::List + && let Some(member_info) = self .get_principal(*member_id) .await .caused_by(trc::location!())? - { - changed_principals.add_member_change( - *member_id, - member_info.typ, - principal_id, - principal_type, - ); - } + { + changed_principals.add_member_change( + *member_id, + member_info.typ, + principal_id, + principal_type, + ); } batch.clear(ValueClass::Directory(DirectoryClass::MemberOf { @@ -2331,16 +2328,14 @@ impl ManageDirectory for Store { // Map tenant name #[cfg(feature = "enterprise")] - if let Some(tenant_id) = principal.tenant { - if fields.is_empty() || fields.contains(&PrincipalField::Tenant) { - if let Some(name) = self - .get_principal_name(tenant_id) - .await - .caused_by(trc::location!())? - { - result.set(PrincipalField::Tenant, name); - } - } + if let Some(tenant_id) = principal.tenant + && (fields.is_empty() || fields.contains(&PrincipalField::Tenant)) + && let Some(name) = self + .get_principal_name(tenant_id) + .await + .caused_by(trc::location!())? + { + result.set(PrincipalField::Tenant, name); } // SPDX-SnippetEnd @@ -2350,10 +2345,10 @@ impl ManageDirectory for Store { (PrincipalField::Name, Some(principal.name)), (PrincipalField::Description, principal.description), ] { - if let Some(value) = value { - if fields.is_empty() || fields.contains(&name) { - result.set(name, value); - } + if let Some(value) = value + && (fields.is_empty() || fields.contains(&name)) + { + result.set(name, value); } } for (name, value) in [ @@ -2637,7 +2632,7 @@ impl ChangedPrincipals { self.0.contains_key(&principal_id) } - pub fn iter(&self) -> std::collections::hash_map::Iter { + pub fn iter(&'_ self) -> std::collections::hash_map::Iter<'_, u32, ChangedPrincipal> { self.0.iter() } diff --git a/crates/directory/src/backend/ldap/lookup.rs b/crates/directory/src/backend/ldap/lookup.rs index 274e9738..8c0760eb 100644 --- a/crates/directory/src/backend/ldap/lookup.rs +++ b/crates/directory/src/backend/ldap/lookup.rs @@ -230,13 +230,12 @@ impl LdapDirectory { .map_err(|err| err.into_error().caused_by(trc::location!()))?; for entry in rs { 'outer: for (attr, value) in SearchEntry::construct(entry).attrs { - if self.mappings.attr_name.contains(&attr) { - if let Some(group) = value.into_iter().next() { - if !group.is_empty() { - name = group; - break 'outer; - } - } + if self.mappings.attr_name.contains(&attr) + && let Some(group) = value.into_iter().next() + && !group.is_empty() + { + name = group; + break 'outer; } } } @@ -314,14 +313,14 @@ impl LdapDirectory { for entry in rs { let entry = SearchEntry::construct(entry); for attr in &self.mappings.attr_name { - if let Some(name) = entry.attrs.get(attr).and_then(|v| v.first()) { - if !name.is_empty() { - return self - .data_store - .get_or_create_principal_id(name, Type::Individual) - .await - .map(Some); - } + if let Some(name) = entry.attrs.get(attr).and_then(|v| v.first()) + && !name.is_empty() + { + return self + .data_store + .get_or_create_principal_id(name, Type::Individual) + .await + .map(Some); } } } diff --git a/crates/directory/src/backend/sql/lookup.rs b/crates/directory/src/backend/sql/lookup.rs index 856aa0a3..17b8915a 100644 --- a/crates/directory/src/backend/sql/lookup.rs +++ b/crates/directory/src/backend/sql/lookup.rs @@ -294,10 +294,10 @@ impl SqlMappings { if let Value::Text(text) = value { principal.emails.push(text.to_lowercase()); } - } else if name.eq_ignore_ascii_case(&self.column_quota) { - if let Value::Integer(quota) = value { - principal.quota = (quota as u64).into(); - } + } else if name.eq_ignore_ascii_case(&self.column_quota) + && let Value::Integer(quota) = value + { + principal.quota = (quota as u64).into(); } } } diff --git a/crates/directory/src/core/dispatch.rs b/crates/directory/src/core/dispatch.rs index 71ceac2f..f0dd92f7 100644 --- a/crates/directory/src/core/dispatch.rs +++ b/crates/directory/src/core/dispatch.rs @@ -40,10 +40,10 @@ impl Directory { pub async fn is_local_domain(&self, domain: &str) -> trc::Result { // Check cache - if let Some(cache) = &self.cache { - if let Some(result) = cache.get_domain(domain) { - return Ok(result); - } + if let Some(cache) = &self.cache + && let Some(result) = cache.get_domain(domain) + { + return Ok(result); } let result = match &self.store { @@ -67,10 +67,10 @@ impl Directory { pub async fn rcpt(&self, email: &str) -> trc::Result { // Check cache - if let Some(cache) = &self.cache { - if let Some(result) = cache.get_rcpt(email) { - return Ok(result); - } + if let Some(cache) = &self.cache + && let Some(result) = cache.get_rcpt(email) + { + return Ok(result); } let result = match &self.store { diff --git a/crates/directory/src/core/mod.rs b/crates/directory/src/core/mod.rs index c85d4dec..76b43698 100644 --- a/crates/directory/src/core/mod.rs +++ b/crates/directory/src/core/mod.rs @@ -261,6 +261,7 @@ mod test { #[test] #[ignore] + #[allow(clippy::obfuscated_if_else)] fn print_permissions() { const CHECK: &str = ":white_check_mark:"; diff --git a/crates/directory/src/core/principal.rs b/crates/directory/src/core/principal.rs index 657012f1..9ffb9661 100644 --- a/crates/directory/src/core/principal.rs +++ b/crates/directory/src/core/principal.rs @@ -238,13 +238,11 @@ impl Principal { } else { None } - }) { - if let Some(idx) = permissions - .iter_mut() - .position(|p| p.permission == permission && p.grant == grant) - { - permissions.swap_remove(idx); - } + }) && let Some(idx) = permissions + .iter_mut() + .position(|p| p.permission == permission && p.grant == grant) + { + permissions.swap_remove(idx); } } @@ -270,10 +268,10 @@ impl Principal { } // If the principal has no roles, take the ones from the external principal - if let Some(roles) = external.roles_mut().filter(|s| !s.is_empty()) { - if self.roles().is_empty() { - self.data.push(PrincipalData::Roles(std::mem::take(roles))); - } + if let Some(roles) = external.roles_mut().filter(|s| !s.is_empty()) + && self.roles().is_empty() + { + self.data.push(PrincipalData::Roles(std::mem::take(roles))); } if external.description.as_ref().is_some_and(|v| !v.is_empty()) diff --git a/crates/email/src/cache/email.rs b/crates/email/src/cache/email.rs index a1a0297d..23f95cfa 100644 --- a/crates/email/src/cache/email.rs +++ b/crates/email/src/cache/email.rs @@ -33,18 +33,17 @@ pub(crate) async fn update_email_cache( }; for (document_id, is_update) in changed_ids { - if *is_update { - if let Some(archive) = server + if *is_update + && let Some(archive) = server .get_archive(account_id, Collection::Email, *document_id) .await .caused_by(trc::location!())? - { - insert_item( - &mut new_cache, - *document_id, - archive.to_unarchived::()?, - ); - } + { + insert_item( + &mut new_cache, + *document_id, + archive.to_unarchived::()?, + ); } } diff --git a/crates/email/src/cache/mailbox.rs b/crates/email/src/cache/mailbox.rs index 4cfa62c5..8d25824f 100644 --- a/crates/email/src/cache/mailbox.rs +++ b/crates/email/src/cache/mailbox.rs @@ -28,18 +28,17 @@ pub(crate) async fn update_mailbox_cache( }; for (document_id, is_update) in changed_ids { - if *is_update { - if let Some(archive) = server + if *is_update + && let Some(archive) = server .get_archive(account_id, Collection::Mailbox, *document_id) .await .caused_by(trc::location!())? - { - insert_item( - &mut new_cache, - *document_id, - archive.unarchive::()?, - ); - } + { + insert_item( + &mut new_cache, + *document_id, + archive.unarchive::()?, + ); } } diff --git a/crates/email/src/message/delete.rs b/crates/email/src/message/delete.rs index fce45635..f2e94d8a 100644 --- a/crates/email/src/message/delete.rs +++ b/crates/email/src/message/delete.rs @@ -136,23 +136,23 @@ impl EmailDeletion for Server { } // Auto-expunge deleted and junk messages - if let Some(hold_period) = self.core.jmap.mail_autoexpunge_after { - if let Err(err) = self.emails_auto_expunge(account_id, hold_period).await { - trc::error!( - err.details("Failed to auto-expunge e-mail messages.") - .account_id(account_id) - ); - } + if let Some(hold_period) = self.core.jmap.mail_autoexpunge_after + && let Err(err) = self.emails_auto_expunge(account_id, hold_period).await + { + trc::error!( + err.details("Failed to auto-expunge e-mail messages.") + .account_id(account_id) + ); } // Auto-expunge iMIP messages - if let Some(hold_period) = self.core.groupware.itip_inbox_auto_expunge { - if let Err(err) = self.itip_auto_expunge(account_id, hold_period).await { - trc::error!( - err.details("Failed to auto-expunge iTIP messages.") - .account_id(account_id) - ); - } + if let Some(hold_period) = self.core.groupware.itip_inbox_auto_expunge + && let Err(err) = self.itip_auto_expunge(account_id, hold_period).await + { + trc::error!( + err.details("Failed to auto-expunge iTIP messages.") + .account_id(account_id) + ); } // Purge tombstoned messages @@ -164,13 +164,13 @@ impl EmailDeletion for Server { } // Purge changelogs - if let Some(history) = self.core.jmap.changes_max_history { - if let Err(err) = self.delete_changes(account_id, history).await { - trc::error!( - err.details("Failed to purge changes.") - .account_id(account_id) - ); - } + if let Some(history) = self.core.jmap.changes_max_history + && let Err(err) = self.delete_changes(account_id, history).await + { + trc::error!( + err.details("Failed to purge changes.") + .account_id(account_id) + ); } // Delete lock diff --git a/crates/email/src/message/ingest.rs b/crates/email/src/message/ingest.rs index 71f897b3..bb5d3efb 100644 --- a/crates/email/src/message/ingest.rs +++ b/crates/email/src/message/ingest.rs @@ -205,38 +205,36 @@ impl EmailIngest for Server { } // If the message is classified as spam, check whether the sender address is present in the user's address book - if is_spam && self.core.spam.card_is_ham { - if let Some(sender) = message + if is_spam + && self.core.spam.card_is_ham + && let Some(sender) = message .from() .and_then(|s| s.first()) .and_then(|s| s.address()) .and_then(sanitize_email) + && sender != deliver_to + && is_sender_authenticated + && !self + .store() + .filter( + account_id, + Collection::ContactCard, + vec![Filter::eq(IDX_EMAIL, sender.into_bytes())], + ) + .await + .caused_by(trc::location!())? + .results + .is_empty() + { + is_spam = false; + if self + .core + .spam + .bayes + .as_ref() + .is_some_and(|config| config.auto_learn_card_is_ham) { - if sender != deliver_to - && is_sender_authenticated - && !self - .store() - .filter( - account_id, - Collection::ContactCard, - vec![Filter::eq(IDX_EMAIL, sender.into_bytes())], - ) - .await - .caused_by(trc::location!())? - .results - .is_empty() - { - is_spam = false; - if self - .core - .spam - .bayes - .as_ref() - .is_some_and(|config| config.auto_learn_card_is_ham) - { - train_spam = Some(false); - } - } + train_spam = Some(false); } } @@ -315,75 +313,72 @@ impl EmailIngest for Server { .subtype() .is_some_and(|st| st.eq_ignore_ascii_case("calendar")) && ct.has_attribute("method") - }) { - if let Some(itip_message) = part.text_contents() { - if itip_message.len() - < self.core.groupware.itip_inbound_max_ical_size - { - if let Some(sender) = sender.get_or_insert_with(|| { - message - .from() - .and_then(|s| s.first()) - .and_then(|s| s.address()) - .and_then(sanitize_email) - }) { - match self - .itip_ingest( - params.access_token, - &resource_token, - sender, - itip_message, - ) - .await - { - Ok(message) => { - if let Some(message) = message { - itip_messages.push(message); - } - trc::event!( - Calendar( - trc::CalendarEvent::ItipMessageReceived - ), - SpanId = params.session_id, - From = sender.to_string(), - AccountId = account_id, - ); + }) && let Some(itip_message) = part.text_contents() + { + if itip_message.len() < self.core.groupware.itip_inbound_max_ical_size { + if let Some(sender) = sender.get_or_insert_with(|| { + message + .from() + .and_then(|s| s.first()) + .and_then(|s| s.address()) + .and_then(sanitize_email) + }) { + match self + .itip_ingest( + params.access_token, + &resource_token, + sender, + itip_message, + ) + .await + { + Ok(message) => { + if let Some(message) = message { + itip_messages.push(message); } - Err(ItipIngestError::Message(itip_error)) => { - match itip_error { - ItipError::NothingToSend - | ItipError::OtherSchedulingAgent => (), - err => { - trc::event!( - Calendar(trc::CalendarEvent::ItipMessageError), - SpanId = params.session_id, - From = sender.to_string(), - AccountId = account_id, - Details = err.to_string(), - ) - } + trc::event!( + Calendar(trc::CalendarEvent::ItipMessageReceived), + SpanId = params.session_id, + From = sender.to_string(), + AccountId = account_id, + ); + } + Err(ItipIngestError::Message(itip_error)) => { + match itip_error { + ItipError::NothingToSend + | ItipError::OtherSchedulingAgent => (), + err => { + trc::event!( + Calendar( + trc::CalendarEvent::ItipMessageError + ), + SpanId = params.session_id, + From = sender.to_string(), + AccountId = account_id, + Details = err.to_string(), + ) } } - Err(ItipIngestError::Internal(err)) => { - trc::error!(err.caused_by(trc::location!())); - } + } + Err(ItipIngestError::Internal(err)) => { + trc::error!(err.caused_by(trc::location!())); } } - } else { - trc::event!( - Calendar(trc::CalendarEvent::ItipMessageError), - SpanId = params.session_id, - From = message - .from() - .and_then(|a| a.first()) - .and_then(|a| a.address()) - .map(|a| a.to_string()), - AccountId = account_id, - Details = "iMIP message too large", - Limit = self.core.groupware.itip_inbound_max_ical_size, - Size = itip_message.len(), - ) } + } else { + trc::event!( + Calendar(trc::CalendarEvent::ItipMessageError), + SpanId = params.session_id, + From = message + .from() + .and_then(|a| a.first()) + .and_then(|a| a.address()) + .map(|a| a.to_string()), + AccountId = account_id, + Details = "iMIP message too large", + Limit = self.core.groupware.itip_inbound_max_ical_size, + Size = itip_message.len(), + ) } } } @@ -515,12 +510,12 @@ impl EmailIngest for Server { part.offset_end += offset_start as u32; part.offset_header += offset_start as u32; - if let PartType::Message(sub_message) = &mut part.body { - if sub_message.root_part().offset_header != 0 { - sub_message.raw_message = raw_message.as_ref().into(); - part_iter_stack.push(part_iter); - part_iter = sub_message.parts.iter_mut(); - } + if let PartType::Message(sub_message) = &mut part.body + && sub_message.root_part().offset_header != 0 + { + sub_message.raw_message = raw_message.as_ref().into(); + part_iter_stack.push(part_iter); + part_iter = sub_message.parts.iter_mut(); } } else if let Some(iter) = part_iter_stack.pop() { part_iter = iter; @@ -544,56 +539,56 @@ impl EmailIngest for Server { IngestSource::Smtp { .. } => self.core.jmap.encrypt, IngestSource::Restore => false, }; - if do_encrypt && !message.is_encrypted() { - if let Some(encrypt_params_) = self + if do_encrypt + && !message.is_encrypted() + && let Some(encrypt_params_) = self .get_archive_by_property(account_id, Collection::Principal, 0, Property::Parameters) .await .caused_by(trc::location!())? - { - let encrypt_params = encrypt_params_ - .unarchive::() - .caused_by(trc::location!())?; - match message.encrypt(encrypt_params).await { - Ok(new_raw_message) => { - raw_message = Cow::from(new_raw_message); - raw_message_len = raw_message.len() as u64; - message = MessageParser::default() - .parse(raw_message.as_ref()) - .ok_or_else(|| { - trc::EventType::MessageIngest(trc::MessageIngestEvent::Error) - .ctx(trc::Key::Code, 550) - .ctx( - trc::Key::Reason, - "Failed to parse encrypted e-mail message.", - ) - })?; + { + let encrypt_params = encrypt_params_ + .unarchive::() + .caused_by(trc::location!())?; + match message.encrypt(encrypt_params).await { + Ok(new_raw_message) => { + raw_message = Cow::from(new_raw_message); + raw_message_len = raw_message.len() as u64; + message = MessageParser::default() + .parse(raw_message.as_ref()) + .ok_or_else(|| { + trc::EventType::MessageIngest(trc::MessageIngestEvent::Error) + .ctx(trc::Key::Code, 550) + .ctx( + trc::Key::Reason, + "Failed to parse encrypted e-mail message.", + ) + })?; - // Remove contents from parsed message - for part in &mut message.parts { - match &mut part.body { - PartType::Text(txt) | PartType::Html(txt) => { - *txt = Cow::from(""); - } - PartType::Binary(bin) | PartType::InlineBinary(bin) => { - *bin = Cow::from(&[][..]); - } - PartType::Message(_) => { - part.body = PartType::Binary(Cow::from(&[][..])); - } - PartType::Multipart(_) => (), + // Remove contents from parsed message + for part in &mut message.parts { + match &mut part.body { + PartType::Text(txt) | PartType::Html(txt) => { + *txt = Cow::from(""); } + PartType::Binary(bin) | PartType::InlineBinary(bin) => { + *bin = Cow::from(&[][..]); + } + PartType::Message(_) => { + part.body = PartType::Binary(Cow::from(&[][..])); + } + PartType::Multipart(_) => (), } } - Err(EncryptMessageError::Error(err)) => { - trc::bail!( - trc::StoreEvent::CryptoError - .into_err() - .caused_by(trc::location!()) - .reason(err) - ); - } - _ => unreachable!(), } + Err(EncryptMessageError::Error(err)) => { + trc::bail!( + trc::StoreEvent::CryptoError + .into_err() + .caused_by(trc::location!()) + .reason(err) + ); + } + _ => unreachable!(), } } diff --git a/crates/email/src/sieve/activate.rs b/crates/email/src/sieve/activate.rs index 05fdf031..941cbf3b 100644 --- a/crates/email/src/sieve/activate.rs +++ b/crates/email/src/sieve/activate.rs @@ -78,26 +78,25 @@ impl SieveScriptActivate for Server { } // Activate script - if let Some(document_id) = activate_id { - if let Some(sieve_) = self + if let Some(document_id) = activate_id + && let Some(sieve_) = self .get_archive(account_id, Collection::SieveScript, document_id) .await? - { - let sieve = sieve_ - .to_unarchived::() - .caused_by(trc::location!())?; - let mut new_sieve = sieve.deserialize().caused_by(trc::location!())?; - new_sieve.is_active = true; - batch - .update_document(document_id) - .custom( - ObjectIndexBuilder::new() - .with_changes(new_sieve) - .with_current(sieve), - ) - .caused_by(trc::location!())?; - changed_ids.push((document_id, true)); - } + { + let sieve = sieve_ + .to_unarchived::() + .caused_by(trc::location!())?; + let mut new_sieve = sieve.deserialize().caused_by(trc::location!())?; + new_sieve.is_active = true; + batch + .update_document(document_id) + .custom( + ObjectIndexBuilder::new() + .with_changes(new_sieve) + .with_current(sieve), + ) + .caused_by(trc::location!())?; + changed_ids.push((document_id, true)); } // Write changes diff --git a/crates/email/src/sieve/ingest.rs b/crates/email/src/sieve/ingest.rs index 25aeaabb..4622154c 100644 --- a/crates/email/src/sieve/ingest.rs +++ b/crates/email/src/sieve/ingest.rs @@ -186,10 +186,10 @@ impl SieveScriptIngest for Server { TRASH_ID } else { let mut mailbox_id = u32::MAX; - if let Ok(role) = SpecialUse::parse_value(&role) { - if let Some(m) = cache.mailbox_by_role(&role) { - mailbox_id = m.document_id; - } + if let Ok(role) = SpecialUse::parse_value(&role) + && let Some(m) = cache.mailbox_by_role(&role) + { + mailbox_id = m.document_id; } mailbox_id @@ -317,17 +317,17 @@ impl SieveScriptIngest for Server { } // Find mailbox by role - if let Some(special_use) = special_use { - if target_id == u32::MAX { - if special_use.eq_ignore_ascii_case("inbox") { - target_id = INBOX_ID; - } else if special_use.eq_ignore_ascii_case("trash") { - target_id = TRASH_ID; - } else if let Ok(role) = SpecialUse::parse_value(&special_use) { - if let Some(item) = cache.mailbox_by_role(&role) { - target_id = item.document_id; - } - } + if let Some(special_use) = special_use + && target_id == u32::MAX + { + if special_use.eq_ignore_ascii_case("inbox") { + target_id = INBOX_ID; + } else if special_use.eq_ignore_ascii_case("trash") { + target_id = TRASH_ID; + } else if let Ok(role) = SpecialUse::parse_value(&special_use) + && let Some(item) = cache.mailbox_by_role(&role) + { + target_id = item.document_id; } } diff --git a/crates/groupware/src/calendar/alarm.rs b/crates/groupware/src/calendar/alarm.rs index 3852f016..ce6f89a2 100644 --- a/crates/groupware/src/calendar/alarm.rs +++ b/crates/groupware/src/calendar/alarm.rs @@ -80,54 +80,9 @@ impl ArchivedCalendarEventData { .single()? .timestamp(); - if let Some(alarm_time) = alarm.delta.to_timestamp(start, end, default_tz) { - if alarm_time > start_time { - if let Some(next) = next_alarm { - if alarm_time < next.alarm_time { - next_alarm = Some(CalendarAlarm { - alarm_id: alarm.id.to_native(), - event_id: alarm.parent_id.to_native(), - alarm_time, - event_start: start_date_naive, - event_start_tz: start_tz.as_id(), - event_end: end_date_naive, - event_end_tz: end_tz.as_id(), - }); - } - } else { - next_alarm = Some(CalendarAlarm { - alarm_id: alarm.id.to_native(), - event_id: alarm.parent_id.to_native(), - alarm_time, - event_start: start_date_naive, - event_start_tz: start_tz.as_id(), - event_end: end_date_naive, - event_end_tz: end_tz.as_id(), - }); - } - continue 'outer; - } - } - } - } else { - // Single event - let start_date_naive = offset_or_count as i64 + base_offset; - let end_date_naive = start_date_naive + duration; - let start = start_tz - .from_local_datetime( - &DateTime::from_timestamp(start_date_naive, 0)?.naive_local(), - ) - .single()? - .timestamp(); - let end = end_tz - .from_local_datetime( - &DateTime::from_timestamp(end_date_naive, 0)?.naive_local(), - ) - .single()? - .timestamp(); - - if let Some(alarm_time) = alarm.delta.to_timestamp(start, end, default_tz) { - if alarm_time > start_time { + if let Some(alarm_time) = alarm.delta.to_timestamp(start, end, default_tz) + && alarm_time > start_time + { if let Some(next) = next_alarm { if alarm_time < next.alarm_time { next_alarm = Some(CalendarAlarm { @@ -151,6 +106,51 @@ impl ArchivedCalendarEventData { event_end_tz: end_tz.as_id(), }); } + continue 'outer; + } + } + } else { + // Single event + let start_date_naive = offset_or_count as i64 + base_offset; + let end_date_naive = start_date_naive + duration; + let start = start_tz + .from_local_datetime( + &DateTime::from_timestamp(start_date_naive, 0)?.naive_local(), + ) + .single()? + .timestamp(); + let end = end_tz + .from_local_datetime( + &DateTime::from_timestamp(end_date_naive, 0)?.naive_local(), + ) + .single()? + .timestamp(); + + if let Some(alarm_time) = alarm.delta.to_timestamp(start, end, default_tz) + && alarm_time > start_time + { + if let Some(next) = next_alarm { + if alarm_time < next.alarm_time { + next_alarm = Some(CalendarAlarm { + alarm_id: alarm.id.to_native(), + event_id: alarm.parent_id.to_native(), + alarm_time, + event_start: start_date_naive, + event_start_tz: start_tz.as_id(), + event_end: end_date_naive, + event_end_tz: end_tz.as_id(), + }); + } + } else { + next_alarm = Some(CalendarAlarm { + alarm_id: alarm.id.to_native(), + event_id: alarm.parent_id.to_native(), + alarm_time, + event_start: start_date_naive, + event_start_tz: start_tz.as_id(), + event_end: end_date_naive, + event_end_tz: end_tz.as_id(), + }); } } } diff --git a/crates/http/src/auth/authenticate.rs b/crates/http/src/auth/authenticate.rs index eaae76c8..e14f61e3 100644 --- a/crates/http/src/auth/authenticate.rs +++ b/crates/http/src/auth/authenticate.rs @@ -160,10 +160,9 @@ fn decode_plain_auth(token: &str) -> Option> { } fn decode_bearer_token(token: &str, allow_api_access: bool) -> Option> { - if allow_api_access { - if let Some(token) = token.strip_prefix("api_").and_then(decode_plain_auth) { - return Some(token); - } + if allow_api_access && let Some(token) = token.strip_prefix("api_").and_then(decode_plain_auth) + { + return Some(token); } Some(Credentials::OAuthBearer { diff --git a/crates/http/src/autoconfig/mod.rs b/crates/http/src/autoconfig/mod.rs index 6ea76b64..17bfb653 100644 --- a/crates/http/src/autoconfig/mod.rs +++ b/crates/http/src/autoconfig/mod.rs @@ -203,22 +203,18 @@ impl Autoconfig for Server { .email_to_id(emailaddress) .await .caused_by(trc::location!())? - { - if let Ok(Some(principal)) = self + && let Ok(Some(principal)) = self .core .storage .directory .query(QueryParams::id(id).with_return_member_of(false)) .await - { - if principal - .emails - .first() - .is_some_and(|email| email.eq_ignore_ascii_case(emailaddress)) - { - account_name = principal.name; - } - } + && principal + .emails + .first() + .is_some_and(|email| email.eq_ignore_ascii_case(emailaddress)) + { + account_name = principal.name; } Ok((account_name, self.core.network.server_name.clone(), domain)) @@ -296,12 +292,11 @@ fn parse_autodiscover_request(bytes: &[u8]) -> Result { } } - if let Ok(Event::Text(text)) = reader.read_event_into(&mut buf) { - if let Ok(text) = text.unescape() { - if text.contains('@') { - return Ok(text.trim().to_lowercase()); - } - } + if let Ok(Event::Text(text)) = reader.read_event_into(&mut buf) + && let Ok(text) = text.unescape() + && text.contains('@') + { + return Ok(text.trim().to_lowercase()); } Err(format!( diff --git a/crates/http/src/form/mod.rs b/crates/http/src/form/mod.rs index db3e0f34..1be59d7f 100644 --- a/crates/http/src/form/mod.rs +++ b/crates/http/src/form/mod.rs @@ -50,24 +50,23 @@ impl FormHandler for Server { form_data: FormData, ) -> trc::Result { // Validate rate - if let Some(rate) = &form.rate { - if !session.remote_ip.is_loopback() - && self - .core - .storage - .lookup - .is_rate_allowed( - KV_RATE_LIMIT_CONTACT, - &ip_to_bytes(&session.remote_ip), - rate, - false, - ) - .await - .caused_by(trc::location!())? - .is_some() - { - return Err(trc::LimitEvent::TooManyRequests.into_err()); - } + if let Some(rate) = &form.rate + && !session.remote_ip.is_loopback() + && self + .core + .storage + .lookup + .is_rate_allowed( + KV_RATE_LIMIT_CONTACT, + &ip_to_bytes(&session.remote_ip), + rate, + false, + ) + .await + .caused_by(trc::location!())? + .is_some() + { + return Err(trc::LimitEvent::TooManyRequests.into_err()); } // Validate honeypot diff --git a/crates/http/src/management/principal.rs b/crates/http/src/management/principal.rs index 2524c295..e9b17330 100644 --- a/crates/http/src/management/principal.rs +++ b/crates/http/src/management/principal.rs @@ -168,16 +168,15 @@ impl PrincipalManager for Server { .await?; // Set report domain - if let Some(report_domain) = report_domain { - if let Err(err) = self + if let Some(report_domain) = report_domain + && let Err(err) = self .core .storage .config .set([("report.domain", report_domain)], true) .await - { - trc::error!(err.details("Failed to set report domain")); - } + { + trc::error!(err.details("Failed to set report domain")); } // Increment revision @@ -205,20 +204,20 @@ impl PrincipalManager for Server { .unwrap_or_default() .split(',') { - if let Some(typ) = Type::parse(typ) { - if !types.contains(&typ) { - types.push(typ); - } + if let Some(typ) = Type::parse(typ) + && !types.contains(&typ) + { + types.push(typ); } } // Parse fields let mut fields = Vec::new(); for field in params.get("fields").unwrap_or_default().split(',') { - if let Some(field) = PrincipalField::try_parse(field) { - if !fields.contains(&field) { - fields.push(field); - } + if let Some(field) = PrincipalField::try_parse(field) + && !fields.contains(&field) + { + fields.push(field); } } diff --git a/crates/http/src/management/queue.rs b/crates/http/src/management/queue.rs index 6be706e5..a05ea4a9 100644 --- a/crates/http/src/management/queue.rs +++ b/crates/http/src/management/queue.rs @@ -145,24 +145,24 @@ impl QueueManagement for Server { // Limit to tenant domains #[cfg(feature = "enterprise")] - if self.core.is_enterprise_edition() { - if let Some(tenant) = access_token.tenant { - tenant_domains = self - .core - .storage - .data - .list_principals(None, tenant.id.into(), &[Type::Domain], false, 0, 0) - .await - .map(|principals| { - principals - .items - .into_iter() - .map(|p| p.name) - .collect::>() - }) - .caused_by(trc::location!())? - .into(); - } + if self.core.is_enterprise_edition() + && let Some(tenant) = access_token.tenant + { + tenant_domains = self + .core + .storage + .data + .list_principals(None, tenant.id.into(), &[Type::Domain], false, 0, 0) + .await + .map(|principals| { + principals + .items + .into_iter() + .map(|p| p.name) + .collect::>() + }) + .caused_by(trc::location!())? + .into(); } // SPDX-SnippetEnd @@ -458,7 +458,12 @@ impl QueueManagement for Server { { let mut rua = Vec::new(); if let Some(report) = self - .generate_tls_aggregate_report(&[event.clone()], &mut rua, None, 0) + .generate_tls_aggregate_report( + std::slice::from_ref(&event), + &mut rua, + None, + 0, + ) .await? { result = Report::tls(event, report, rua).into(); diff --git a/crates/http/src/management/report.rs b/crates/http/src/management/report.rs index 8f755f47..cdaeeb2e 100644 --- a/crates/http/src/management/report.rs +++ b/crates/http/src/management/report.rs @@ -53,24 +53,24 @@ impl ManageReports for Server { // Limit to tenant domains #[cfg(feature = "enterprise")] - if self.core.is_enterprise_edition() { - if let Some(tenant) = access_token.tenant { - tenant_domains = self - .core - .storage - .data - .list_principals(None, tenant.id.into(), &[Type::Domain], false, 0, 0) - .await - .map(|principals| { - principals - .items - .into_iter() - .map(|p| p.name) - .collect::>() - }) - .caused_by(trc::location!())? - .into(); - } + if self.core.is_enterprise_edition() + && let Some(tenant) = access_token.tenant + { + tenant_domains = self + .core + .storage + .data + .list_principals(None, tenant.id.into(), &[Type::Domain], false, 0, 0) + .await + .map(|principals| { + principals + .items + .into_iter() + .map(|p| p.name) + .collect::>() + }) + .caused_by(trc::location!())? + .into(); } // SPDX-SnippetEnd @@ -206,12 +206,11 @@ impl ManageReports for Server { } } - if !batch.is_empty() { - if let Err(err) = + if !batch.is_empty() + && let Err(err) = server.core.storage.data.write(batch.build_all()).await - { - trc::error!(err.caused_by(trc::location!())); - } + { + trc::error!(err.caused_by(trc::location!())); } }); } diff --git a/crates/http/src/management/settings.rs b/crates/http/src/management/settings.rs index 66c3c1af..87168290 100644 --- a/crates/http/src/management/settings.rs +++ b/crates/http/src/management/settings.rs @@ -91,20 +91,20 @@ impl ManageSettings for Server { let mut total = 0; let mut ids = Vec::new(); for key in settings.keys() { - if let Some(id) = key.strip_suffix(&suffix) { - if !id.is_empty() { - if !has_filter { - if offset == 0 { - if limit == 0 || ids.len() < limit { - ids.push(id); - } - } else { - offset -= 1; + if let Some(id) = key.strip_suffix(&suffix) + && !id.is_empty() + { + if !has_filter { + if offset == 0 { + if limit == 0 || ids.len() < limit { + ids.push(id); } - total += 1; } else { - ids.push(id); + offset -= 1; } + total += 1; + } else { + ids.push(id); } } } @@ -318,10 +318,10 @@ impl ManageSettings for Server { { return Err(trc::ManageEvent::AssertFailed.into_err()); } - } else if let Some((key, _)) = values.first() { - if self.core.storage.config.get(key).await?.is_some() { - return Err(trc::ManageEvent::AssertFailed.into_err()); - } + } else if let Some((key, _)) = values.first() + && self.core.storage.config.get(key).await?.is_some() + { + return Err(trc::ManageEvent::AssertFailed.into_err()); } } diff --git a/crates/http/src/request.rs b/crates/http/src/request.rs index d6a3d16d..5a71ce0e 100644 --- a/crates/http/src/request.rs +++ b/crates/http/src/request.rs @@ -557,16 +557,15 @@ impl ParseHttp for Server { "metrics" => match path.next().unwrap_or_default() { "prometheus" => { if let Some(prometheus) = &self.core.metrics.prometheus { - if let Some(auth) = &prometheus.auth { - if req + if let Some(auth) = &prometheus.auth + && req .authorization_basic() .is_none_or(|secret| secret != auth) - { - return Err(trc::AuthEvent::Failed - .into_err() - .details("Invalid or missing credentials.") - .caused_by(trc::location!())); - } + { + return Err(trc::AuthEvent::Failed + .into_err() + .details("Invalid or missing credentials.") + .caused_by(trc::location!())); } return Ok(Resource::new( diff --git a/crates/imap-proto/src/protocol/capability.rs b/crates/imap-proto/src/protocol/capability.rs index 84db95c7..626b10dd 100644 --- a/crates/imap-proto/src/protocol/capability.rs +++ b/crates/imap-proto/src/protocol/capability.rs @@ -220,7 +220,7 @@ mod tests { ], } .serialize(), - concat!("* CAPABILITY IMAP4rev2 STARTTLS LOGINDISABLED\r\n",).as_bytes() + "* CAPABILITY IMAP4rev2 STARTTLS LOGINDISABLED\r\n".as_bytes() ); } } diff --git a/crates/imap-proto/src/protocol/expunge.rs b/crates/imap-proto/src/protocol/expunge.rs index 135c459c..2a8dbaa9 100644 --- a/crates/imap-proto/src/protocol/expunge.rs +++ b/crates/imap-proto/src/protocol/expunge.rs @@ -105,7 +105,7 @@ mod tests { .serialize() ) .unwrap(), - concat!("* VANISHED 3:5\r\n") + "* VANISHED 3:5\r\n" ); } } diff --git a/crates/imap-proto/src/protocol/quota.rs b/crates/imap-proto/src/protocol/quota.rs index d3290f35..6399544b 100644 --- a/crates/imap-proto/src/protocol/quota.rs +++ b/crates/imap-proto/src/protocol/quota.rs @@ -105,7 +105,7 @@ mod tests { }], }], }, - concat!("* QUOTA \"INBOX\" (STORAGE 1024 1048576)\r\n"), + "* QUOTA \"INBOX\" (STORAGE 1024 1048576)\r\n", ), ( super::Response { diff --git a/crates/imap-proto/src/protocol/search.rs b/crates/imap-proto/src/protocol/search.rs index 6b43b4a4..c3586eab 100644 --- a/crates/imap-proto/src/protocol/search.rs +++ b/crates/imap-proto/src/protocol/search.rs @@ -235,8 +235,8 @@ mod tests { highest_modseq: None, }, "A283", - concat!("* ESEARCH (TAG \"A283\") COUNT 3 MIN 2 MAX 11 ALL 2,10:11\r\n",), - concat!("* SEARCH 2 10 11\r\n"), + "* ESEARCH (TAG \"A283\") COUNT 3 MIN 2 MAX 11 ALL 2,10:11\r\n", + "* SEARCH 2 10 11\r\n", ), ( super::Response { @@ -252,8 +252,8 @@ mod tests { highest_modseq: None, }, "A283", - concat!("* ESEARCH (TAG \"A283\") ALL 1:3,5,10:13,90,92:99\r\n",), - concat!("* SEARCH 1 2 3 5 10 11 12 13 90 92 93 94 95 96 97 98 99\r\n",), + "* ESEARCH (TAG \"A283\") ALL 1:3,5,10:13,90,92:99\r\n", + "* SEARCH 1 2 3 5 10 11 12 13 90 92 93 94 95 96 97 98 99\r\n", ), ( super::Response { @@ -267,8 +267,8 @@ mod tests { highest_modseq: None, }, "A283", - concat!("* ESEARCH (TAG \"A283\")\r\n",), - concat!("* SEARCH\r\n"), + "* ESEARCH (TAG \"A283\")\r\n", + "* SEARCH\r\n", ), ( super::Response { @@ -282,8 +282,8 @@ mod tests { highest_modseq: 12345.into(), }, "A283", - concat!("* ESEARCH (TAG \"A283\") ALL 10:13,21 MODSEQ 12345\r\n",), - concat!("* SEARCH 10 11 12 13 21 (MODSEQ 12345)\r\n",), + "* ESEARCH (TAG \"A283\") ALL 10:13,21 MODSEQ 12345\r\n", + "* SEARCH 10 11 12 13 21 (MODSEQ 12345)\r\n", ), ] { let response_v2 = String::from_utf8(response.clone().serialize(tag)).unwrap(); diff --git a/crates/imap-proto/src/protocol/status.rs b/crates/imap-proto/src/protocol/status.rs index 07441ccc..18feedb2 100644 --- a/crates/imap-proto/src/protocol/status.rs +++ b/crates/imap-proto/src/protocol/status.rs @@ -102,9 +102,7 @@ mod tests { assert_eq!( String::from_utf8(buf).unwrap(), - concat!( - "* STATUS \"blurdybloop\" (MESSAGES 231 UIDNEXT 44292 MAILBOXID (abc-123))\r\n", - ) + "* STATUS \"blurdybloop\" (MESSAGES 231 UIDNEXT 44292 MAILBOXID (abc-123))\r\n" ); } } diff --git a/crates/imap-proto/src/protocol/thread.rs b/crates/imap-proto/src/protocol/thread.rs index 2d5879cf..77a3340b 100644 --- a/crates/imap-proto/src/protocol/thread.rs +++ b/crates/imap-proto/src/protocol/thread.rs @@ -59,7 +59,7 @@ mod tests { .serialize() ) .unwrap(), - concat!("* THREAD (2 10 11)(49)(1 3)\r\n",) + "* THREAD (2 10 11)(49)(1 3)\r\n" ); } } diff --git a/crates/imap/src/core/client.rs b/crates/imap/src/core/client.rs index e49ad242..4815262b 100644 --- a/crates/imap/src/core/client.rs +++ b/crates/imap/src/core/client.rs @@ -260,14 +260,13 @@ impl Session { } } - if let Some(needs_literal) = needs_literal { - if let Err(err) = self + if let Some(needs_literal) = needs_literal + && let Err(err) = self .write_bytes(format!("+ Ready for {} bytes.\r\n", needs_literal).into_bytes()) .await - { - self.write_error(err).await; - return SessionResult::Close; - } + { + self.write_error(err).await; + return SessionResult::Close; } SessionResult::Continue @@ -294,25 +293,23 @@ impl Session { async fn is_allowed(&self, request: Request) -> trc::Result> { let state = &self.state; // Rate limit request - if let State::Authenticated { data } | State::Selected { data, .. } = state { - if let Some(rate) = &self.server.core.imap.rate_requests { - if data - .server - .core - .storage - .lookup - .is_rate_allowed( - KV_RATE_LIMIT_IMAP, - &data.account_id.to_be_bytes(), - rate, - true, - ) - .await? - .is_some() - { - return Err(trc::LimitEvent::TooManyRequests.into_err()); - } - } + if let State::Authenticated { data } | State::Selected { data, .. } = state + && let Some(rate) = &self.server.core.imap.rate_requests + && data + .server + .core + .storage + .lookup + .is_rate_allowed( + KV_RATE_LIMIT_IMAP, + &data.account_id.to_be_bytes(), + rate, + true, + ) + .await? + .is_some() + { + return Err(trc::LimitEvent::TooManyRequests.into_err()); } match &request.command { diff --git a/crates/imap/src/core/mailbox.rs b/crates/imap/src/core/mailbox.rs index 171d58d4..e4f0cb25 100644 --- a/crates/imap/src/core/mailbox.rs +++ b/crates/imap/src/core/mailbox.rs @@ -316,12 +316,11 @@ impl SessionData { // Add new mailboxes for (mailbox_name, mailbox_id) in new_account.mailbox_names.iter() { if let Some(old_mailbox) = old_account.mailbox_state.get(mailbox_id) { - if let Some(mailbox) = new_account.mailbox_state.get(mailbox_id) { - if mailbox.total_messages != old_mailbox.total_messages - || mailbox.total_unseen != old_mailbox.total_unseen - { - changes.changed.push(mailbox_name.clone()); - } + if let Some(mailbox) = new_account.mailbox_state.get(mailbox_id) + && (mailbox.total_messages != old_mailbox.total_messages + || mailbox.total_unseen != old_mailbox.total_unseen) + { + changes.changed.push(mailbox_name.clone()); } } else { changes.added.push(mailbox_name.clone()); diff --git a/crates/imap/src/core/session.rs b/crates/imap/src/core/session.rs index a361e61b..c809ced6 100644 --- a/crates/imap/src/core/session.rs +++ b/crates/imap/src/core/session.rs @@ -28,12 +28,12 @@ impl SessionManager for ImapSessionManager { session: SessionData, ) -> impl std::future::Future + Send { async move { - if let Ok(mut session) = Session::new(session, self).await { - if session.handle_conn().await && session.instance.acceptor.is_tls() { - if let Ok(mut session) = session.into_tls().await { - session.handle_conn().await; - } - } + if let Ok(mut session) = Session::new(session, self).await + && session.handle_conn().await + && session.instance.acceptor.is_tls() + && let Ok(mut session) = session.into_tls().await + { + session.handle_conn().await; } } } diff --git a/crates/imap/src/op/create.rs b/crates/imap/src/op/create.rs index 119d38a2..ca773584 100644 --- a/crates/imap/src/op/create.rs +++ b/crates/imap/src/op/create.rs @@ -85,10 +85,10 @@ impl SessionData { for (pos, &path_item) in params.path.iter().enumerate() { let mut mailbox = email::mailbox::Mailbox::new(path_item).with_parent_id(parent_id); - if pos == params.path.len() - 1 { - if let Some(mailbox_role) = arguments.mailbox_role.map(attr_to_role) { - mailbox.role = mailbox_role; - } + if pos == params.path.len() - 1 + && let Some(mailbox_role) = arguments.mailbox_role.map(attr_to_role) + { + mailbox.role = mailbox_role; } let mailbox_id = next_document_id; next_document_id -= 1; diff --git a/crates/imap/src/op/fetch.rs b/crates/imap/src/op/fetch.rs index 0c723ed2..fa351705 100644 --- a/crates/imap/src/op/fetch.rs +++ b/crates/imap/src/op/fetch.rs @@ -540,33 +540,32 @@ impl SessionData { self.write_bytes(buf).await?; // Add to set flags - if set_seen_flag { - if let Some(data_) = self + if set_seen_flag + && let Some(data_) = self .server .get_archive(account_id, Collection::Email, id) .await .imap_ctx(&arguments.tag, trc::location!())? - { - let data = data_ - .to_unarchived::() - .imap_ctx(&arguments.tag, trc::location!())?; - let mut new_data = data - .deserialize() - .imap_ctx(&arguments.tag, trc::location!())?; - new_data.keywords.push(Keyword::Seen); + { + let data = data_ + .to_unarchived::() + .imap_ctx(&arguments.tag, trc::location!())?; + let mut new_data = data + .deserialize() + .imap_ctx(&arguments.tag, trc::location!())?; + new_data.keywords.push(Keyword::Seen); - batch - .with_account_id(account_id) - .with_collection(Collection::Email) - .update_document(id) - .custom( - ObjectIndexBuilder::new() - .with_current(data) - .with_changes(new_data), - ) - .imap_ctx(&arguments.tag, trc::location!())? - .commit_point(); - } + batch + .with_account_id(account_id) + .with_collection(Collection::Email) + .update_document(id) + .custom( + ObjectIndexBuilder::new() + .with_current(data) + .with_changes(new_data), + ) + .imap_ctx(&arguments.tag, trc::location!())? + .commit_point(); } } @@ -620,7 +619,7 @@ impl SessionData { #[allow(clippy::result_unit_err)] pub trait AsImapDataItem { - fn body_structure(&self, decoded: &DecodedParts<'_>, is_extended: bool) -> BodyPart; + fn body_structure(&'_ self, decoded: &DecodedParts<'_>, is_extended: bool) -> BodyPart<'_>; fn body_section<'x>( &self, decoded: &'x DecodedParts<'x>, @@ -639,24 +638,24 @@ pub trait AsImapDataItem { #[allow(clippy::result_unit_err)] pub trait AsImapDataItemPart { fn as_body_part( - &self, + &'_ self, decoded: &DecodedParts<'_>, message_id: usize, part_id: usize, is_extended: bool, - ) -> BodyPart; + ) -> BodyPart<'_>; - fn envelope(&self) -> Envelope; + fn envelope(&'_ self) -> Envelope<'_>; } impl AsImapDataItemPart for ArchivedMessageMetadataContents { fn as_body_part( - &self, + &'_ self, decoded: &DecodedParts<'_>, message_id: usize, part_id: usize, is_extended: bool, - ) -> BodyPart { + ) -> BodyPart<'_> { let part = &self.parts[part_id]; let body = decoded.raw_message_section_arch(message_id, part.offset_body, part.offset_end); let (is_multipart, is_text) = match &part.body { @@ -800,7 +799,7 @@ impl AsImapDataItemPart for ArchivedMessageMetadataContents { } } - fn envelope(&self) -> Envelope { + fn envelope(&'_ self) -> Envelope<'_> { let headers = self.root_part(); Envelope { date: headers.date(), @@ -847,7 +846,7 @@ impl AsImapDataItemPart for ArchivedMessageMetadataContents { } impl AsImapDataItem for ArchivedMessageMetadata { - fn body_structure(&self, decoded: &DecodedParts<'_>, is_extended: bool) -> BodyPart { + fn body_structure(&'_ self, decoded: &DecodedParts<'_>, is_extended: bool) -> BodyPart<'_> { let mut stack = Vec::new(); let base_part = [u16_le::from_native(0)]; let mut parts = base_part.as_slice().iter(); @@ -941,19 +940,18 @@ impl AsImapDataItem for ArchivedMessageMetadata { None }?; - if let ArchivedMetadataPartType::Message(nested_message_id) = &part.body { - if let Some(( + if let ArchivedMetadataPartType::Message(nested_message_id) = &part.body + && let Some(( _, Section::Part { .. } | Section::Header | Section::HeaderFields { .. } | Section::Text, )) = sections_iter.peek() - { - message = self.message_id(*nested_message_id); - part = message.root_part(); - message_id = u16::from(nested_message_id) as usize; - } + { + message = self.message_id(*nested_message_id); + part = message.root_part(); + message_id = u16::from(nested_message_id) as usize; } } Section::Header => { @@ -1208,11 +1206,11 @@ fn get_partial_bytes(bytes: &[u8], partial: Option<(u32, u32)>) -> &[u8] { } trait AsImapAddress { - fn as_imap_address(&self) -> Vec; + fn as_imap_address(&'_ self) -> Vec>; } impl AsImapAddress for ArchivedHeaderValue<'_> { - fn as_imap_address(&self) -> Vec { + fn as_imap_address(&'_ self) -> Vec> { let mut addresses = Vec::new(); match self { diff --git a/crates/imap/src/op/subscribe.rs b/crates/imap/src/op/subscribe.rs index 5dcc27f0..e49eaab2 100644 --- a/crates/imap/src/op/subscribe.rs +++ b/crates/imap/src/op/subscribe.rs @@ -76,17 +76,17 @@ impl SessionData { // Verify if mailbox is already subscribed/unsubscribed for account in self.mailboxes.lock().iter_mut() { if account.account_id == account_id { - if let Some(mailbox) = account.mailbox_state.get(&mailbox_id) { - if mailbox.is_subscribed == subscribe { - return Err(trc::ImapEvent::Error - .into_err() - .details(if subscribe { - "Mailbox is already subscribed." - } else { - "Mailbox is already unsubscribed." - }) - .id(tag)); - } + if let Some(mailbox) = account.mailbox_state.get(&mailbox_id) + && mailbox.is_subscribed == subscribe + { + return Err(trc::ImapEvent::Error + .into_err() + .details(if subscribe { + "Mailbox is already subscribed." + } else { + "Mailbox is already unsubscribed." + }) + .id(tag)); } break; } diff --git a/crates/imap/src/op/thread.rs b/crates/imap/src/op/thread.rs index f87cbc41..761ea968 100644 --- a/crates/imap/src/op/thread.rs +++ b/crates/imap/src/op/thread.rs @@ -89,10 +89,10 @@ impl SessionData { let mut threads: AHashMap> = AHashMap::new(); let state = mailbox.state.lock(); for item in &cache.emails.items { - if result_set.results.contains(item.document_id) { - if let Some((imap_id, _)) = state.map_result_id(item.document_id, is_uid) { - threads.entry(item.thread_id).or_default().push(imap_id); - } + if result_set.results.contains(item.document_id) + && let Some((imap_id, _)) = state.map_result_id(item.document_id, is_uid) + { + threads.entry(item.thread_id).or_default().push(imap_id); } } diff --git a/crates/jmap-proto/src/error/request.rs b/crates/jmap-proto/src/error/request.rs index de489460..e2a6d3ea 100644 --- a/crates/jmap-proto/src/error/request.rs +++ b/crates/jmap-proto/src/error/request.rs @@ -186,7 +186,7 @@ impl<'x> RequestError<'x> { RequestError::blank(401, "Unauthorized", "You have to authenticate first.") } - pub fn unknown_capability(capability: &str) -> RequestError { + pub fn unknown_capability(capability: &'_ str) -> RequestError<'_> { RequestError { p_type: RequestErrorType::UnknownCapability, limit: None, @@ -204,7 +204,7 @@ impl<'x> RequestError<'x> { } } - pub fn not_json(detail: &str) -> RequestError { + pub fn not_json(detail: &'_ str) -> RequestError<'_> { RequestError { p_type: RequestErrorType::NotJSON, limit: None, diff --git a/crates/jmap-proto/src/response/references.rs b/crates/jmap-proto/src/response/references.rs index 074fa1f6..caebbc2d 100644 --- a/crates/jmap-proto/src/response/references.rs +++ b/crates/jmap-proto/src/response/references.rs @@ -144,25 +144,25 @@ impl Response { let mut graph = HashMap::with_capacity(request.create.len()); for (create_id, object) in request.create.iter_mut() { for data in &mut object.data { - if let DataSourceObject::Id { id, .. } = data { - if let MaybeReference::Reference(parent_id) = id { - match self.created_ids.get(parent_id) { - Some(AnyId::Blob(blob_id)) => { - *id = MaybeReference::Value(blob_id.clone()); - } - Some(_) => { - return Err(trc::JmapEvent::InvalidResultReference - .into_err() - .details(format_compact!( - "Id reference {parent_id:?} points to invalid type." - ))); - } - None => { - graph - .entry(create_id.to_string()) - .or_insert_with(Vec::new) - .push(parent_id.to_string()); - } + if let DataSourceObject::Id { id, .. } = data + && let MaybeReference::Reference(parent_id) = id + { + match self.created_ids.get(parent_id) { + Some(AnyId::Blob(blob_id)) => { + *id = MaybeReference::Value(blob_id.clone()); + } + Some(_) => { + return Err(trc::JmapEvent::InvalidResultReference + .into_err() + .details(format_compact!( + "Id reference {parent_id:?} points to invalid type." + ))); + } + None => { + graph + .entry(create_id.to_string()) + .or_insert_with(Vec::new) + .push(parent_id.to_string()); } } } diff --git a/crates/jmap-proto/src/types/value.rs b/crates/jmap-proto/src/types/value.rs index a3213fc0..3de2d9e1 100644 --- a/crates/jmap-proto/src/types/value.rs +++ b/crates/jmap-proto/src/types/value.rs @@ -580,21 +580,20 @@ impl JsonQueryable for Value { ) { match pointer.next() { Some(JsonPointerItem::String(n)) => { - if let Value::Object(map) = self { - if let Some(v) = map + if let Value::Object(map) = self + && let Some(v) = map .0 .iter() .find_map(|(k, v)| if k.as_str() == n { Some(v) } else { None }) - { - v.eval_pointer(pointer, results); - } + { + v.eval_pointer(pointer, results); } } Some(JsonPointerItem::Number(n)) => { - if let Value::List(values) = self { - if let Some(v) = values.get(*n as usize) { - v.eval_pointer(pointer, results); - } + if let Value::List(values) = self + && let Some(v) = values.get(*n as usize) + { + v.eval_pointer(pointer, results); } } Some(JsonPointerItem::Wildcard) => match self { diff --git a/crates/jmap/src/changes/state.rs b/crates/jmap/src/changes/state.rs index 9ccf7400..0772e55e 100644 --- a/crates/jmap/src/changes/state.rs +++ b/crates/jmap/src/changes/state.rs @@ -48,10 +48,10 @@ impl StateManager for Server { if_in_state: &Option, ) -> trc::Result { let old_state: State = self.get_state(account_id, collection).await?; - if let Some(if_in_state) = if_in_state { - if &old_state != if_in_state { - return Err(trc::JmapEvent::StateMismatch.into_err()); - } + if let Some(if_in_state) = if_in_state + && &old_state != if_in_state + { + return Err(trc::JmapEvent::StateMismatch.into_err()); } Ok(old_state) @@ -69,10 +69,10 @@ impl MessageCacheState for MessageStoreCache { fn assert_state(&self, is_mailbox: bool, if_in_state: &Option) -> trc::Result { let old_state: State = self.get_state(is_mailbox); - if let Some(if_in_state) = if_in_state { - if &old_state != if_in_state { - return Err(trc::JmapEvent::StateMismatch.into_err()); - } + if let Some(if_in_state) = if_in_state + && &old_state != if_in_state + { + return Err(trc::JmapEvent::StateMismatch.into_err()); } Ok(old_state) } diff --git a/crates/jmap/src/lib.rs b/crates/jmap/src/lib.rs index 0243ed0b..497919f8 100644 --- a/crates/jmap/src/lib.rs +++ b/crates/jmap/src/lib.rs @@ -86,11 +86,11 @@ impl JmapMethods for Server { } async fn build_query_response( - &self, + &'_ self, result_set: &ResultSet, query_state: State, request: &QueryRequest, - ) -> trc::Result<(QueryResponse, Option)> { + ) -> trc::Result<(QueryResponse, Option>)> { let total = result_set.results.len() as usize; let (limit_total, limit) = if let Some(limit) = request.limit { if limit > 0 { @@ -182,11 +182,11 @@ pub trait JmapMethods: Sync + Send { ) -> impl Future> + Send; fn build_query_response( - &self, + &'_ self, result_set: &ResultSet, query_state: State, request: &QueryRequest, - ) -> impl Future)>> + Send; + ) -> impl Future>)>> + Send; fn sort( &self, diff --git a/crates/jmap/src/mailbox/query.rs b/crates/jmap/src/mailbox/query.rs index 94c61bfc..92505fdb 100644 --- a/crates/jmap/src/mailbox/query.rs +++ b/crates/jmap/src/mailbox/query.rs @@ -182,10 +182,10 @@ impl MailboxQuery for Server { if response.total.is_some() { response.total = Some(total); } - if let Some(paginate) = &mut paginate { - if paginate.limit > total { - paginate.limit = total; - } + if let Some(paginate) = &mut paginate + && paginate.limit > total + { + paginate.limit = total; } result_set.results = filtered_ids; } diff --git a/crates/jmap/src/sieve/set.rs b/crates/jmap/src/sieve/set.rs index dab9fbeb..384259fa 100644 --- a/crates/jmap/src/sieve/set.rs +++ b/crates/jmap/src/sieve/set.rs @@ -391,8 +391,7 @@ impl SieveScriptSet for Server { } else if update .as_ref() .is_none_or(|(_, obj)| obj.inner.name != value) - { - if let Some(id) = self + && let Some(id) = self .filter( ctx.resource_token.account_id, Collection::SieveScript, @@ -401,14 +400,13 @@ impl SieveScriptSet for Server { .await? .results .min() - { - return Ok(Err(SetError::already_exists() - .with_existing_id(id.into()) - .with_description(format!( - "A sieve script with name '{}' already exists.", - value - )))); - } + { + return Ok(Err(SetError::already_exists() + .with_existing_id(id.into()) + .with_description(format!( + "A sieve script with name '{}' already exists.", + value + )))); } changes.name = value; diff --git a/crates/jmap/src/submission/get.rs b/crates/jmap/src/submission/get.rs index b792fa8a..fee42c36 100644 --- a/crates/jmap/src/submission/get.rs +++ b/crates/jmap/src/submission/get.rs @@ -103,39 +103,39 @@ impl EmailSubmissionGet for Server { .map(|(k, v)| (k.to_string(), DeliveryStatus::from(v))) .collect::>(); let mut is_pending = false; - if let Some(queue_id) = submission.queue_id.as_ref().map(u64::from) { - if let Some(queued_message_) = self + if let Some(queue_id) = submission.queue_id.as_ref().map(u64::from) + && let Some(queued_message_) = self .read_message_archive(queue_id) .await .caused_by(trc::location!())? - { - let queued_message = queued_message_ - .unarchive::() - .caused_by(trc::location!())?; - for rcpt in queued_message.recipients.iter() { - *delivery_status.get_mut_or_insert(rcpt.address().to_string()) = - DeliveryStatus { - smtp_reply: match &rcpt.status { - ArchivedStatus::Completed(reply) => { - format_archived_response(&reply.response) - } - ArchivedStatus::TemporaryFailure(reply) - | ArchivedStatus::PermanentFailure(reply) => { - format_archived_error_details(reply) - } - ArchivedStatus::Scheduled => "250 2.1.5 Queued".to_string(), - }, - delivered: match &rcpt.status { - ArchivedStatus::Scheduled - | ArchivedStatus::TemporaryFailure(_) => Delivered::Queued, - ArchivedStatus::Completed(_) => Delivered::Yes, - ArchivedStatus::PermanentFailure(_) => Delivered::No, - }, - displayed: false, - }; - } - is_pending = true; + { + let queued_message = queued_message_ + .unarchive::() + .caused_by(trc::location!())?; + for rcpt in queued_message.recipients.iter() { + *delivery_status.get_mut_or_insert(rcpt.address().to_string()) = + DeliveryStatus { + smtp_reply: match &rcpt.status { + ArchivedStatus::Completed(reply) => { + format_archived_response(&reply.response) + } + ArchivedStatus::TemporaryFailure(reply) + | ArchivedStatus::PermanentFailure(reply) => { + format_archived_error_details(reply) + } + ArchivedStatus::Scheduled => "250 2.1.5 Queued".to_string(), + }, + delivered: match &rcpt.status { + ArchivedStatus::Scheduled | ArchivedStatus::TemporaryFailure(_) => { + Delivered::Queued + } + ArchivedStatus::Completed(_) => Delivered::Yes, + ArchivedStatus::PermanentFailure(_) => Delivered::No, + }, + displayed: false, + }; } + is_pending = true; } let mut result = Object::with_capacity(properties.len()); diff --git a/crates/jmap/src/submission/set.rs b/crates/jmap/src/submission/set.rs index a89b0561..60ac91b2 100644 --- a/crates/jmap/src/submission/set.rs +++ b/crates/jmap/src/submission/set.rs @@ -511,17 +511,17 @@ impl EmailSubmissionSet for Server { } if let ArchivedHeaderValue::Address(addr) = &header.value { for address in addr.iter() { - if let Some(address) = address.address().and_then(sanitize_email) { - if !rcpt_to.iter().any(|rcpt| rcpt.address == address) { - submission.envelope.rcpt_to.push(Address { - email: address.to_string(), - parameters: None, - }); - rcpt_to.push(RcptTo { - address, - ..Default::default() - }); - } + if let Some(address) = address.address().and_then(sanitize_email) + && !rcpt_to.iter().any(|rcpt| rcpt.address == address) + { + submission.envelope.rcpt_to.push(Address { + email: address.to_string(), + parameters: None, + }); + rcpt_to.push(RcptTo { + address, + ..Default::default() + }); } } } @@ -696,19 +696,19 @@ fn parse_envelope_address( let mut params_list = VecMap::with_capacity(params.0.len()); for (k, v) in params.0 { - if let Property::_T(k) = k { - if !k.is_empty() { - if !params_text.is_empty() { - params_text.push(' '); - } - params_text.push_str(&k); - if let Value::Text(v) = v { - params_text.push('='); - params_text.push_str(&v); - params_list.append(k, Some(v)); - } else { - params_list.append(k, None); - } + if let Property::_T(k) = k + && !k.is_empty() + { + if !params_text.is_empty() { + params_text.push(' '); + } + params_text.push_str(&k); + if let Value::Text(v) = v { + params_text.push('='); + params_text.push_str(&v); + params_list.append(k, Some(v)); + } else { + params_list.append(k, None); } } } diff --git a/crates/jmap/src/vacation/set.rs b/crates/jmap/src/vacation/set.rs index 87fecf53..06bae1a4 100644 --- a/crates/jmap/src/vacation/set.rs +++ b/crates/jmap/src/vacation/set.rs @@ -315,14 +315,13 @@ impl VacationResponseSet for Server { } } else if !will_destroy.is_empty() { for id in will_destroy { - if id.is_singleton() { - if let Some(document_id) = self.get_vacation_sieve_script_id(account_id).await? - { - self.sieve_script_delete(&resource_token, document_id, false, &mut batch) - .await?; - response.destroyed.push(id); - continue; - } + if id.is_singleton() + && let Some(document_id) = self.get_vacation_sieve_script_id(account_id).await? + { + self.sieve_script_delete(&resource_token, document_id, false, &mut batch) + .await?; + response.destroyed.push(id); + continue; } response.not_destroyed.append(id, SetError::not_found()); diff --git a/crates/managesieve/src/core/client.rs b/crates/managesieve/src/core/client.rs index 612b1201..213a8d5d 100644 --- a/crates/managesieve/src/core/client.rs +++ b/crates/managesieve/src/core/client.rs @@ -132,14 +132,13 @@ impl Session { } } - if let Some(needs_literal) = needs_literal { - if let Err(err) = self + if let Some(needs_literal) = needs_literal + && let Err(err) = self .write(format!("OK Ready for {} bytes.\r\n", needs_literal).as_bytes()) .await - { - trc::error!(err.span_id(self.session_id)); - return SessionResult::Close; - } + { + trc::error!(err.span_id(self.session_id)); + return SessionResult::Close; } SessionResult::Continue diff --git a/crates/managesieve/src/core/session.rs b/crates/managesieve/src/core/session.rs index f0a8bd4a..f316cc38 100644 --- a/crates/managesieve/src/core/session.rs +++ b/crates/managesieve/src/core/session.rs @@ -42,13 +42,12 @@ impl SessionManager for ManageSieveSessionManager { .is_ok() && session.handle_conn().await && session.instance.acceptor.is_tls() + && let Ok(mut session) = session.into_tls().await { - if let Ok(mut session) = session.into_tls().await { - let _ = session - .write(&session.handle_capability(SERVER_GREETING).await.unwrap()) - .await; - session.handle_conn().await; - } + let _ = session + .write(&session.handle_capability(SERVER_GREETING).await.unwrap()) + .await; + session.handle_conn().await; } } } diff --git a/crates/migration/src/submission.rs b/crates/migration/src/submission.rs index deb951a3..a81a3134 100644 --- a/crates/migration/src/submission.rs +++ b/crates/migration/src/submission.rs @@ -236,27 +236,27 @@ fn convert_envelope(value: &Value) -> Envelope { } fn convert_envelope_address(envelope: &Value) -> Option
{ - if let Value::Object(envelope) = envelope { - if let (Value::Text(email), Value::Object(params)) = ( + if let Value::Object(envelope) = envelope + && let (Value::Text(email), Value::Object(params)) = ( envelope.get(&Property::Email), envelope.get(&Property::Parameters), - ) { - let mut addr = Address { - email: email.to_string(), - parameters: None, - }; - for (k, v) in params.0.iter() { - if let Property::_T(k) = &k { - if !k.is_empty() { - let k = k.to_string(); - let v = v.as_string().map(|s| s.to_string()); + ) + { + let mut addr = Address { + email: email.to_string(), + parameters: None, + }; + for (k, v) in params.0.iter() { + if let Property::_T(k) = &k + && !k.is_empty() + { + let k = k.to_string(); + let v = v.as_string().map(|s| s.to_string()); - addr.parameters.get_or_insert_default().append(k, v); - } - } + addr.parameters.get_or_insert_default().append(k, v); } - return Some(addr); } + return Some(addr); } None diff --git a/crates/nlp/src/tokenizers/space.rs b/crates/nlp/src/tokenizers/space.rs index 2668f40c..9dbec5ee 100644 --- a/crates/nlp/src/tokenizers/space.rs +++ b/crates/nlp/src/tokenizers/space.rs @@ -13,7 +13,7 @@ pub struct SpaceTokenizer<'x> { } impl SpaceTokenizer<'_> { - pub fn new(text: &str, max_token_length: usize) -> SpaceTokenizer { + pub fn new(text: &'_ str, max_token_length: usize) -> SpaceTokenizer<'_> { SpaceTokenizer { iterator: text.chars(), token: String::new(), diff --git a/crates/nlp/src/tokenizers/types.rs b/crates/nlp/src/tokenizers/types.rs index 4bc78405..96b1b1d8 100644 --- a/crates/nlp/src/tokenizers/types.rs +++ b/crates/nlp/src/tokenizers/types.rs @@ -88,11 +88,12 @@ impl<'x> Iterator for TypesTokenizer<'x> { } // Try parsing currencies and floating point numbers - if self.tokenize_numbers && !last_is_dot { - if let Some(num) = self.try_parse_number() { - self.peek_advance(); - return Some(num); - } + if self.tokenize_numbers + && !last_is_dot + && let Some(num) = self.try_parse_number() + { + self.peek_advance(); + return Some(num); } self.peek_rewind(); diff --git a/crates/nlp/src/tokenizers/word.rs b/crates/nlp/src/tokenizers/word.rs index 87a745b0..18ef22b6 100644 --- a/crates/nlp/src/tokenizers/word.rs +++ b/crates/nlp/src/tokenizers/word.rs @@ -15,7 +15,7 @@ pub struct WordTokenizer<'x> { } impl WordTokenizer<'_> { - pub fn new(text: &str, max_token_length: usize) -> WordTokenizer { + pub fn new(text: &'_ str, max_token_length: usize) -> WordTokenizer<'_> { WordTokenizer { max_token_length, text, diff --git a/crates/pop3/src/session.rs b/crates/pop3/src/session.rs index 0a1617a6..1da1e4bf 100644 --- a/crates/pop3/src/session.rs +++ b/crates/pop3/src/session.rs @@ -49,10 +49,9 @@ impl SessionManager for Pop3SessionManager { .is_ok() && session.handle_conn().await && session.instance.acceptor.is_tls() + && let Ok(mut session) = session.into_tls().await { - if let Ok(mut session) = session.into_tls().await { - session.handle_conn().await; - } + session.handle_conn().await; } } } @@ -190,11 +189,9 @@ impl Session { trc::error!(err.span_id(self.session_id)); - if write_err { - if let Err(err) = self.write_bytes(response).await { - trc::error!(err.span_id(self.session_id)); - return false; - } + if write_err && let Err(err) = self.write_bytes(response).await { + trc::error!(err.span_id(self.session_id)); + return false; } !disconnect diff --git a/crates/services/src/housekeeper/mod.rs b/crates/services/src/housekeeper/mod.rs index 37281ba5..fec0a1ac 100644 --- a/crates/services/src/housekeeper/mod.rs +++ b/crates/services/src/housekeeper/mod.rs @@ -98,11 +98,11 @@ pub fn spawn_housekeeper(inner: Arc, mut rx: mpsc::Receiver, mut rx: mpsc::Receiver // SPDX-License-Identifier: LicenseRef-SEL #[cfg(feature = "enterprise")] - if let Some(trace_retention) = trace_retention { - if let Err(err) = store.purge_spans(trace_retention).await { - trc::error!(err.details("Failed to purge tracing spans")); - } + if let Some(trace_retention) = trace_retention + && let Err(err) = store.purge_spans(trace_retention).await + { + trc::error!(err.details("Failed to purge tracing spans")); } #[cfg(feature = "enterprise")] - if let Some(metrics_retention) = metrics_retention { - if let Err(err) = store.purge_metrics(metrics_retention).await { - trc::error!(err.details("Failed to purge metrics")); - } + if let Some(metrics_retention) = metrics_retention + && let Err(err) = store.purge_metrics(metrics_retention).await + { + trc::error!(err.details("Failed to purge metrics")); } // SPDX-SnippetEnd } @@ -767,17 +767,16 @@ impl Purge for Server { ); // Remove lock - if let Some(lock_name) = &lock_name { - if let Err(err) = self + if let Some(lock_name) = &lock_name + && let Err(err) = self .in_memory_store() .remove_lock(KV_LOCK_HOUSEKEEPER, lock_name) .await - { - trc::error!( - err.details("Failed to delete task lock.") - .details(lock_type) - ); - } + { + trc::error!( + err.details("Failed to delete task lock.") + .details(lock_type) + ); } } } diff --git a/crates/services/src/state_manager/manager.rs b/crates/services/src/state_manager/manager.rs index d303c06e..711d3ee0 100644 --- a/crates/services/src/state_manager/manager.rs +++ b/crates/services/src/state_manager/manager.rs @@ -75,14 +75,12 @@ pub fn spawn_state_manager(inner: Arc, mut change_rx: mpsc::Receiver, mut change_rx: mpsc::Receiver { // Publish event to cluster - if broadcast { - if let Some(broadcast_tx) = &inner.ipc.broadcast_tx.clone() { - if broadcast_tx - .send(BroadcastEvent::StateChange(state_change)) - .await - .is_err() - { - trc::event!( - Server(trc::ServerEvent::ThreadError), - Details = "Error sending broadcast event.", - CausedBy = trc::location!() - ); - } - } + if broadcast + && let Some(broadcast_tx) = &inner.ipc.broadcast_tx.clone() + && broadcast_tx + .send(BroadcastEvent::StateChange(state_change)) + .await + .is_err() + { + trc::event!( + Server(trc::ServerEvent::ThreadError), + Details = "Error sending broadcast event.", + CausedBy = trc::location!() + ); } if let Some(shared_accounts) = shared_accounts_map.get(&state_change.account_id) @@ -247,14 +243,14 @@ pub fn spawn_state_manager(inner: Arc, mut change_rx: mpsc::Receiver Session { } // Add Received-SPF header - if let Some(spf_output) = &self.data.spf_mail_from { - if self + if let Some(spf_output) = &self.data.spf_mail_from + && self .server .eval_if(&dc.add_received_spf, self, self.data.session_id) .await .unwrap_or(true) - { - ReceivedSpf::new( - spf_output, - self.data.remote_ip, - &self.data.helo_domain, - &mail_from.address_lcase, - &self.hostname, - ) - .write_header(&mut headers); - } + { + ReceivedSpf::new( + spf_output, + self.data.remote_ip, + &self.data.helo_domain, + &mail_from.address_lcase, + &self.hostname, + ) + .write_header(&mut headers); } // ARC Seal - if let (Some(arc_sealer), Some(arc_output)) = (arc_sealer, &arc_output) { - if !dkim_output.is_empty() && arc_output.can_be_sealed() { - match arc_sealer.seal(&auth_message, &auth_results, arc_output) { - Ok(set) => { - set.write_header(&mut headers); - } - Err(err) => { - trc::error!( - trc::Error::from(err) - .span_id(self.data.session_id) - .details("Failed to ARC seal message") - ); - } + if let (Some(arc_sealer), Some(arc_output)) = (arc_sealer, &arc_output) + && !dkim_output.is_empty() + && arc_output.can_be_sealed() + { + match arc_sealer.seal(&auth_message, &auth_results, arc_output) { + Ok(set) => { + set.write_header(&mut headers); + } + Err(err) => { + trc::error!( + trc::Error::from(err) + .span_id(self.data.session_id) + .details("Failed to ARC seal message") + ); } } } diff --git a/crates/smtp/src/inbound/ehlo.rs b/crates/smtp/src/inbound/ehlo.rs index 8d154b37..c5b9135b 100644 --- a/crates/smtp/src/inbound/ehlo.rs +++ b/crates/smtp/src/inbound/ehlo.rs @@ -98,20 +98,18 @@ impl Session { .get_trusted_sieve_script(&name, self.data.session_id) .map(|s| (s, name)) }) - { - if let ScriptResult::Reject(message) = self + && let ScriptResult::Reject(message) = self .run_script( script_id, script.clone(), self.build_script_parameters("ehlo"), ) .await - { - self.data.mail_from = None; - self.data.helo_domain = prev_helo_domain; - self.data.spf_ehlo = None; - return self.write(message.as_bytes()).await; - } + { + self.data.mail_from = None; + self.data.helo_domain = prev_helo_domain; + self.data.spf_ehlo = None; + return self.write(message.as_bytes()).await; } // Milter filtering diff --git a/crates/smtp/src/inbound/spawn.rs b/crates/smtp/src/inbound/spawn.rs index 6cc66430..d861899e 100644 --- a/crates/smtp/src/inbound/spawn.rs +++ b/crates/smtp/src/inbound/spawn.rs @@ -47,10 +47,9 @@ impl SessionManager for SmtpSessionManager { && session.init_conn().await && session.handle_conn().await && session.instance.acceptor.is_tls() + && let Ok(mut session) = session.into_tls().await { - if let Ok(mut session) = session.into_tls().await { - session.handle_conn().await; - } + session.handle_conn().await; } } @@ -89,18 +88,16 @@ impl Session { .get_trusted_sieve_script(&name, self.data.session_id) .map(|s| (s, name)) }) - { - if let ScriptResult::Reject(message) = self + && let ScriptResult::Reject(message) = self .run_script( script_id, script.clone(), self.build_script_parameters("connect"), ) .await - { - let _ = self.write(message.as_bytes()).await; - return false; - } + { + let _ = self.write(message.as_bytes()).await; + return false; } // Milter filtering diff --git a/crates/smtp/src/outbound/delivery.rs b/crates/smtp/src/outbound/delivery.rs index 7f573cc8..b21f50ef 100644 --- a/crates/smtp/src/outbound/delivery.rs +++ b/crates/smtp/src/outbound/delivery.rs @@ -1029,36 +1029,36 @@ impl QueuedMessage { ); // Verify DANE - if let Some(dane_policy) = &dane_policy { - if let Err(status) = dane_policy.verify( + if let Some(dane_policy) = &dane_policy + && let Err(status) = dane_policy.verify( message.span_id, envelope.mx, smtp_client.tls_connection().peer_certificates(), - ) { - // Report DANE verification failure - if let Some(tls_report) = &tls_report { - server - .schedule_report(TlsEvent { - policy: dane_policy.into(), - domain: domain.to_string(), - failure: FailureDetails::new( - ResultType::ValidationFailure, - ) - .with_receiving_mx_hostname(envelope.mx) - .with_receiving_ip(remote_ip) - .with_failure_reason_code( - "No matching certificates found.", - ) - .into(), - tls_record: tls_report.record.clone(), - interval: tls_report.interval, - }) - .await; - } - - last_status = status; - continue 'next_host; + ) + { + // Report DANE verification failure + if let Some(tls_report) = &tls_report { + server + .schedule_report(TlsEvent { + policy: dane_policy.into(), + domain: domain.to_string(), + failure: FailureDetails::new( + ResultType::ValidationFailure, + ) + .with_receiving_mx_hostname(envelope.mx) + .with_receiving_ip(remote_ip) + .with_failure_reason_code( + "No matching certificates found.", + ) + .into(), + tls_record: tls_report.record.clone(), + interval: tls_report.interval, + }) + .await; } + + last_status = status; + continue 'next_host; } // Report TLS success diff --git a/crates/smtp/src/outbound/mta_sts/lookup.rs b/crates/smtp/src/outbound/mta_sts/lookup.rs index 8691683d..febaf7fa 100644 --- a/crates/smtp/src/outbound/mta_sts/lookup.rs +++ b/crates/smtp/src/outbound/mta_sts/lookup.rs @@ -59,10 +59,10 @@ impl MtaStsLookup for Server { }; // Check if the policy has been cached - if let Some(value) = self.inner.cache.dbs_mta_sts.get(domain) { - if value.id == record.id { - return Ok(value); - } + if let Some(value) = self.inner.cache.dbs_mta_sts.get(domain) + && value.id == record.id + { + return Ok(value); } // Fetch policy diff --git a/crates/smtp/src/outbound/mta_sts/verify.rs b/crates/smtp/src/outbound/mta_sts/verify.rs index 49634b1c..757679b7 100644 --- a/crates/smtp/src/outbound/mta_sts/verify.rs +++ b/crates/smtp/src/outbound/mta_sts/verify.rs @@ -22,10 +22,10 @@ impl VerifyPolicy for Policy { } } MxPattern::StartsWith(domain) => { - if let Some((_, suffix)) = mx_host.split_once('.') { - if suffix == domain { - return true; - } + if let Some((_, suffix)) = mx_host.split_once('.') + && suffix == domain + { + return true; } } } diff --git a/crates/smtp/src/queue/dsn.rs b/crates/smtp/src/queue/dsn.rs index fa5a9b44..1c1557a5 100644 --- a/crates/smtp/src/queue/dsn.rs +++ b/crates/smtp/src/queue/dsn.rs @@ -396,13 +396,13 @@ impl MessageWrapper { let now = now(); for rcpt in &mut self.message.recipients { - if !rcpt.has_flag(RCPT_DSN_SENT | RCPT_NOTIFY_NEVER) { - if let Status::PermanentFailure(err) = &rcpt.status { - rcpt.flags |= RCPT_DSN_SENT; - let mut dsn = String::new(); - err.write_dsn_text(&rcpt.address, &mut dsn); - is_double_bounce.push(dsn); - } + if !rcpt.has_flag(RCPT_DSN_SENT | RCPT_NOTIFY_NEVER) + && let Status::PermanentFailure(err) = &rcpt.status + { + rcpt.flags |= RCPT_DSN_SENT; + let mut dsn = String::new(); + err.write_dsn_text(&rcpt.address, &mut dsn); + is_double_bounce.push(dsn); } if rcpt.notify.due <= now { @@ -529,12 +529,12 @@ impl Recipient { } fn write_dsn_will_retry_until(&self, created: u64, dsn: &mut String) { - if let Some(expires) = self.expiration_time(created) { - if expires > now() { - dsn.push_str("Will-Retry-Until: "); - dsn.push_str(&DateTime::from_timestamp(expires as i64).to_rfc822()); - dsn.push_str("\r\n"); - } + if let Some(expires) = self.expiration_time(created) + && expires > now() + { + dsn.push_str("Will-Retry-Until: "); + dsn.push_str(&DateTime::from_timestamp(expires as i64).to_rfc822()); + dsn.push_str("\r\n"); } } } @@ -624,10 +624,10 @@ impl Status, ErrorDetails> { } fn write_dsn_diagnostic(&self, dsn: &mut String) { - if let Status::PermanentFailure(err) | Status::TemporaryFailure(err) = self { - if let Error::UnexpectedResponse(response) = &err.details { - response.response.write_dsn_diagnostic(dsn); - } + if let Status::PermanentFailure(err) | Status::TemporaryFailure(err) = self + && let Error::UnexpectedResponse(response) = &err.details + { + response.response.write_dsn_diagnostic(dsn); } } } diff --git a/crates/smtp/src/reporting/tls.rs b/crates/smtp/src/reporting/tls.rs index 7f75cb07..cc24f240 100644 --- a/crates/smtp/src/reporting/tls.rs +++ b/crates/smtp/src/reporting/tls.rs @@ -303,10 +303,10 @@ impl TlsReporting for Server { continue; }; - if let Some(serialized_size) = serialized_size.as_deref_mut() { - if serde::Serialize::serialize(&tls, serialized_size).is_err() { - continue; - } + if let Some(serialized_size) = serialized_size.as_deref_mut() + && serde::Serialize::serialize(&tls, serialized_size).is_err() + { + continue; } // Group duplicates diff --git a/crates/spam-filter/src/analysis/bayes.rs b/crates/spam-filter/src/analysis/bayes.rs index ed3ffeca..a2da8a13 100644 --- a/crates/spam-filter/src/analysis/bayes.rs +++ b/crates/spam-filter/src/analysis/bayes.rs @@ -24,21 +24,22 @@ pub trait SpamFilterAnalyzeBayes: Sync + Send { impl SpamFilterAnalyzeBayes for Server { async fn spam_filter_analyze_bayes_classify(&self, ctx: &mut SpamFilterContext<'_>) { - if let Some(config) = &self.core.spam.bayes { - if !ctx.result.has_tag("SPAM_TRAP") && !ctx.result.has_tag("TRUSTED_REPLY") { - match self.bayes_classify(ctx).await { - Ok(Some(score)) => { - if score > config.score_spam { - ctx.result.add_tag("BAYES_SPAM"); - } else if score < config.score_ham { - ctx.result.add_tag("BAYES_HAM"); - } - } - Ok(None) => (), - Err(err) => { - trc::error!(err.span_id(ctx.input.span_id).caused_by(trc::location!())); + if let Some(config) = &self.core.spam.bayes + && !ctx.result.has_tag("SPAM_TRAP") + && !ctx.result.has_tag("TRUSTED_REPLY") + { + match self.bayes_classify(ctx).await { + Ok(Some(score)) => { + if score > config.score_spam { + ctx.result.add_tag("BAYES_SPAM"); + } else if score < config.score_ham { + ctx.result.add_tag("BAYES_HAM"); } } + Ok(None) => (), + Err(err) => { + trc::error!(err.span_id(ctx.input.span_id).caused_by(trc::location!())); + } } } } diff --git a/crates/spam-filter/src/analysis/domain.rs b/crates/spam-filter/src/analysis/domain.rs index f121ba59..1fa0c057 100644 --- a/crates/spam-filter/src/analysis/domain.rs +++ b/crates/spam-filter/src/analysis/domain.rs @@ -41,13 +41,13 @@ impl SpamFilterAnalyzeDomain for Server { // Add DKIM domains for dkim in ctx.input.dkim_result { - if dkim.result() == &DkimResult::Pass { - if let Some(domain) = dkim.signature().map(|s| &s.d) { - domains.insert(ElementLocation::new( - CompactString::from_str_to_lowercase(domain), - Location::HeaderDkimPass, - )); - } + if dkim.result() == &DkimResult::Pass + && let Some(domain) = dkim.signature().map(|s| &s.d) + { + domains.insert(ElementLocation::new( + CompactString::from_str_to_lowercase(domain), + Location::HeaderDkimPass, + )); } } @@ -59,11 +59,10 @@ impl SpamFilterAnalyzeDomain for Server { .into_iter() .flatten() { - if let Host::Name(name) = host { - if let Some(name) = Hostname::new(name.as_ref()).sld { - domains - .insert(ElementLocation::new(name, Location::HeaderReceived)); - } + if let Host::Name(name) = host + && let Some(name) = Hostname::new(name.as_ref()).sld + { + domains.insert(ElementLocation::new(name, Location::HeaderReceived)); } } } diff --git a/crates/spam-filter/src/analysis/from.rs b/crates/spam-filter/src/analysis/from.rs index 34dd7345..12c3c9ad 100644 --- a/crates/spam-filter/src/analysis/from.rs +++ b/crates/spam-filter/src/analysis/from.rs @@ -86,8 +86,8 @@ impl SpamFilterAnalyzeFrom for Server { ctx.result.add_tag("FROM_HAS_DN"); } - if from_name_trimmed.contains('@') { - if let Some(from_name_addr) = TypesTokenizer::new(from_name_trimmed) + if from_name_trimmed.contains('@') + && let Some(from_name_addr) = TypesTokenizer::new(from_name_trimmed) .tokenize_numbers(false) .tokenize_urls(false) .tokenize_urls_without_scheme(false) @@ -100,19 +100,18 @@ impl SpamFilterAnalyzeFrom for Server { _ => None, }) .next() + { + if (from_addr_is_valid + && from_name_addr.domain_part.sld != from_addr.domain_part.sld) + || (!env_from_empty + && ctx.output.env_from_addr.domain_part.sld + != from_name_addr.domain_part.sld) + || (env_from_empty + && ctx.output.ehlo_host.sld != from_name_addr.domain_part.sld) { - if (from_addr_is_valid - && from_name_addr.domain_part.sld != from_addr.domain_part.sld) - || (!env_from_empty - && ctx.output.env_from_addr.domain_part.sld - != from_name_addr.domain_part.sld) - || (env_from_empty - && ctx.output.ehlo_host.sld != from_name_addr.domain_part.sld) - { - ctx.result.add_tag("SPOOF_DISPLAY_NAME"); - } else { - ctx.result.add_tag("FROM_NEQ_DISPLAY_NAME"); - } + ctx.result.add_tag("SPOOF_DISPLAY_NAME"); + } else { + ctx.result.add_tag("FROM_NEQ_DISPLAY_NAME"); } } } @@ -188,10 +187,10 @@ impl SpamFilterAnalyzeFrom for Server { } // Check whether read confirmation address is different to from address - if let Some(crt) = crt { - if crt != from_addr.address { - ctx.result.add_tag("HEADER_RCONFIRM_MISMATCH"); - } + if let Some(crt) = crt + && crt != from_addr.address + { + ctx.result.add_tag("HEADER_RCONFIRM_MISMATCH"); } } @@ -216,10 +215,10 @@ impl SpamFilterAnalyzeFrom for Server { } // Check whether disposition notification address is different to return path - if let Some(dnt) = dnt { - if dnt != ctx.output.env_from_addr.address { - ctx.result.add_tag("HEADER_FORGED_MDN"); - } + if let Some(dnt) = dnt + && dnt != ctx.output.env_from_addr.address + { + ctx.result.add_tag("HEADER_FORGED_MDN"); } } } diff --git a/crates/spam-filter/src/analysis/ip.rs b/crates/spam-filter/src/analysis/ip.rs index 6453d746..2f0408ce 100644 --- a/crates/spam-filter/src/analysis/ip.rs +++ b/crates/spam-filter/src/analysis/ip.rs @@ -38,19 +38,21 @@ impl SpamFilterAnalyzeIp for Server { if let (HeaderName::Received, HeaderValue::Received(received)) = (&header.name, &header.value) { - if let Some(ip) = received.from_ip() { - if !ip.is_loopback() && !self.is_ip_allowed(&ip) { - ips.insert(ElementLocation::new(ip, Location::HeaderReceived)); - } + if let Some(ip) = received.from_ip() + && !ip.is_loopback() + && !self.is_ip_allowed(&ip) + { + ips.insert(ElementLocation::new(ip, Location::HeaderReceived)); } for host in [&received.from, &received.helo, &received.by] .into_iter() .flatten() { - if let Host::IpAddr(ip) = host { - if !ip.is_loopback() && !self.is_ip_allowed(ip) { - ips.insert(ElementLocation::new(*ip, Location::HeaderReceived)); - } + if let Host::IpAddr(ip) = host + && !ip.is_loopback() + && !self.is_ip_allowed(ip) + { + ips.insert(ElementLocation::new(*ip, Location::HeaderReceived)); } } } diff --git a/crates/spam-filter/src/analysis/mime.rs b/crates/spam-filter/src/analysis/mime.rs index d5db8066..4046f21a 100644 --- a/crates/spam-filter/src/analysis/mime.rs +++ b/crates/spam-filter/src/analysis/mime.rs @@ -366,15 +366,15 @@ impl SpamFilterAnalyzeMime for Server { if is_attachment { // Has a MIME attachment ctx.result.add_tag("HAS_ATTACHMENT"); - if ct_full != "application/octet-stream" { - if let Some(t) = infer::get(part.contents()) { - if t.mime_type() == ct_full { - // Known content-type - ctx.result.add_tag("MIME_GOOD"); - } else { - // Known bad content-type - ctx.result.add_tag("MIME_BAD"); - } + if ct_full != "application/octet-stream" + && let Some(t) = infer::get(part.contents()) + { + if t.mime_type() == ct_full { + // Known content-type + ctx.result.add_tag("MIME_GOOD"); + } else { + // Known bad content-type + ctx.result.add_tag("MIME_BAD"); } } } diff --git a/crates/spam-filter/src/analysis/received.rs b/crates/spam-filter/src/analysis/received.rs index b8f173a9..5c996a48 100644 --- a/crates/spam-filter/src/analysis/received.rs +++ b/crates/spam-filter/src/analysis/received.rs @@ -48,22 +48,20 @@ impl SpamFilterAnalyzeReceived for Server { ctx.result.add_tag("RCVD_HELO_USER"); } else if let (Some(Host::Name(helo_domain)), Some(ip_rev)) = (helo_domain, ip_rev) + && helo_domain.to_lowercase() != ip_rev.to_lowercase() { - if helo_domain.to_lowercase() != ip_rev.to_lowercase() { - // HELO domain does not match PTR record - ctx.result.add_tag("FORGED_RCVD_TRAIL"); - } + // HELO domain does not match PTR record + ctx.result.add_tag("FORGED_RCVD_TRAIL"); } - if let Some(delivered_for) = received.for_().map(|s| s.to_lowercase()) { - if ctx + if let Some(delivered_for) = received.for_().map(|s| s.to_lowercase()) + && ctx .output .all_recipients() .any(|r| r.email.address == delivered_for) - { - // Recipient appears on Received trail - ctx.result.add_tag("PREVIOUSLY_DELIVERED"); - } + { + // Recipient appears on Received trail + ctx.result.add_tag("PREVIOUSLY_DELIVERED"); } if matches!(received.from, Some(Host::IpAddr(_))) { diff --git a/crates/spam-filter/src/analysis/recipient.rs b/crates/spam-filter/src/analysis/recipient.rs index e5836f84..f180048a 100644 --- a/crates/spam-filter/src/analysis/recipient.rs +++ b/crates/spam-filter/src/analysis/recipient.rs @@ -101,11 +101,11 @@ impl SpamFilterAnalyzeRecipient for Server { // Check for spaces in recipient addresses for token in raw_utf8.split('<') { - if let Some((addr, _)) = token.split_once('>') { - if addr.starts_with(' ') || addr.ends_with(' ') { - ctx.result.add_tag("TO_WRAPPED_IN_SPACES"); - break; - } + if let Some((addr, _)) = token.split_once('>') + && (addr.starts_with(' ') || addr.ends_with(' ')) + { + ctx.result.add_tag("TO_WRAPPED_IN_SPACES"); + break; } } } diff --git a/crates/spam-filter/src/analysis/trusted_reply.rs b/crates/spam-filter/src/analysis/trusted_reply.rs index 119cc3ea..a6fe1f99 100644 --- a/crates/spam-filter/src/analysis/trusted_reply.rs +++ b/crates/spam-filter/src/analysis/trusted_reply.rs @@ -64,17 +64,15 @@ impl SpamFilterAnalyzeTrustedReply for Server { if let (Some(hold_time), Some(message_id)) = ( self.core.spam.expiry.trusted_reply, ctx.input.message.message_id(), - ) { - if let Err(err) = self - .in_memory_store() - .key_set( - KeyValue::with_prefix(KV_TRUSTED_REPLY, message_id.as_bytes(), vec![]) - .expires(hold_time), - ) - .await - { - trc::error!(err.span_id(ctx.input.span_id).caused_by(trc::location!())); - } + ) && let Err(err) = self + .in_memory_store() + .key_set( + KeyValue::with_prefix(KV_TRUSTED_REPLY, message_id.as_bytes(), vec![]) + .expires(hold_time), + ) + .await + { + trc::error!(err.span_id(ctx.input.span_id).caused_by(trc::location!())); } if self diff --git a/crates/spam-filter/src/analysis/url.rs b/crates/spam-filter/src/analysis/url.rs index 4dda9640..30472800 100644 --- a/crates/spam-filter/src/analysis/url.rs +++ b/crates/spam-filter/src/analysis/url.rs @@ -96,14 +96,15 @@ impl SpamFilterAnalyzeUrl for Server { for token in tokens { match token { TokenType::Url(url) | TokenType::UrlNoScheme(url) => { - if is_body && !ctx.result.has_tag("RCPT_DOMAIN_IN_BODY") { - if let Some(url_parsed) = &url.url_parsed { - let host = url_parsed.host.sld_or_default(); - for rcpt in ctx.output.all_recipients() { - if rcpt.email.domain_part.sld_or_default() == host { - ctx.result.add_tag("RCPT_DOMAIN_IN_BODY"); - break; - } + if is_body + && !ctx.result.has_tag("RCPT_DOMAIN_IN_BODY") + && let Some(url_parsed) = &url.url_parsed + { + let host = url_parsed.host.sld_or_default(); + for rcpt in ctx.output.all_recipients() { + if rcpt.email.domain_part.sld_or_default() == host { + ctx.result.add_tag("RCPT_DOMAIN_IN_BODY"); + break; } } } diff --git a/crates/spam-filter/src/modules/dnsbl.rs b/crates/spam-filter/src/modules/dnsbl.rs index 7d0c3ddf..03888887 100644 --- a/crates/spam-filter/src/modules/dnsbl.rs +++ b/crates/spam-filter/src/modules/dnsbl.rs @@ -51,8 +51,9 @@ pub(crate) async fn check_dnsbl( }; for dnsbl in &server.core.spam.dnsbl.servers { - if dnsbl.scope == scope && checks < max_checks { - if let Some(tag) = is_dnsbl( + if dnsbl.scope == scope + && checks < max_checks + && let Some(tag) = is_dnsbl( server, dnsbl, SpamFilterResolver::new(ctx, resolver, location), @@ -60,9 +61,8 @@ pub(crate) async fn check_dnsbl( &mut checks, ) .await - { - ctx.result.add_tag(tag); - } + { + ctx.result.add_tag(tag); } } diff --git a/crates/spam-filter/src/modules/pyzor.rs b/crates/spam-filter/src/modules/pyzor.rs index 261511b9..de74845c 100644 --- a/crates/spam-filter/src/modules/pyzor.rs +++ b/crates/spam-filter/src/modules/pyzor.rs @@ -320,13 +320,13 @@ fn html_to_text(input: &str) -> String { continue; } b'>' if in_tag => { - if tag_token_pos == 1 { - if let Some(tag) = input.get(token_start..token_end + 1) { - if tag.eq_ignore_ascii_case(b"style") { - in_style = !is_tag_close; - } else if tag.eq_ignore_ascii_case(b"script") { - in_script = !is_tag_close; - } + if tag_token_pos == 1 + && let Some(tag) = input.get(token_start..token_end + 1) + { + if tag.eq_ignore_ascii_case(b"style") { + in_style = !is_tag_close; + } else if tag.eq_ignore_ascii_case(b"script") { + in_script = !is_tag_close; } } diff --git a/crates/store/src/backend/mysql/main.rs b/crates/store/src/backend/mysql/main.rs index 1c03e96e..e0f24a2f 100644 --- a/crates/store/src/backend/mysql/main.rs +++ b/crates/store/src/backend/mysql/main.rs @@ -78,10 +78,8 @@ impl MysqlStore { conn_pool: Pool::new(opts), }; - if create_tables { - if let Err(err) = db.create_tables().await { - config.new_build_error(prefix.as_str(), format!("Failed to create tables: {err}")); - } + if create_tables && let Err(err) = db.create_tables().await { + config.new_build_error(prefix.as_str(), format!("Failed to create tables: {err}")); } Some(db) diff --git a/crates/store/src/backend/postgres/main.rs b/crates/store/src/backend/postgres/main.rs index 02e4a941..b827c4e7 100644 --- a/crates/store/src/backend/postgres/main.rs +++ b/crates/store/src/backend/postgres/main.rs @@ -65,10 +65,8 @@ impl PostgresStore { .ok()?, }; - if create_tables { - if let Err(err) = db.create_tables().await { - config.new_build_error(prefix.as_str(), format!("Failed to create tables: {err}")); - } + if create_tables && let Err(err) = db.create_tables().await { + config.new_build_error(prefix.as_str(), format!("Failed to create tables: {err}")); } Some(db) diff --git a/crates/store/src/config.rs b/crates/store/src/config.rs index 7bd2cded..30957e2e 100644 --- a/crates/store/src/config.rs +++ b/crates/store/src/config.rs @@ -431,10 +431,10 @@ impl IsActiveStore for Config { "tracing.history.store", "metrics.history.store", ] { - if let Some(store_id) = self.value(key) { - if store_id == id { - return true; - } + if let Some(store_id) = self.value(key) + && store_id == id + { + return true; } } diff --git a/crates/utils/src/json/pointer.rs b/crates/utils/src/json/pointer.rs index 8343dad7..884905a6 100644 --- a/crates/utils/src/json/pointer.rs +++ b/crates/utils/src/json/pointer.rs @@ -71,10 +71,10 @@ impl JsonQueryable for serde_json::Value { ) { match pointer.next() { Some(JsonPointerItem::String(n)) => { - if let serde_json::Value::Object(map) = self { - if let Some(v) = map.get(n) { - v.eval_pointer(pointer, results); - } + if let serde_json::Value::Object(map) = self + && let Some(v) = map.get(n) + { + v.eval_pointer(pointer, results); } } Some(JsonPointerItem::Number(n)) => match self { diff --git a/tests/src/imap/mod.rs b/tests/src/imap/mod.rs index 5eaaaaec..f121ba9f 100644 --- a/tests/src/imap/mod.rs +++ b/tests/src/imap/mod.rs @@ -504,33 +504,31 @@ impl AssertResult for Vec { } fn into_response_code(self) -> String { - if let Some((_, code)) = self.last().unwrap().split_once('[') { - if let Some((code, _)) = code.split_once(']') { - return code.to_string(); - } + if let Some((_, code)) = self.last().unwrap().split_once('[') + && let Some((code, _)) = code.split_once(']') + { + return code.to_string(); } panic!("No response code found in {:?}", self.last().unwrap()); } fn into_append_uid(self) -> String { - if let Some((_, code)) = self.last().unwrap().split_once("[APPENDUID ") { - if let Some((code, _)) = code.split_once(']') { - if let Some((_, uid)) = code.split_once(' ') { - return uid.to_string(); - } - } + if let Some((_, code)) = self.last().unwrap().split_once("[APPENDUID ") + && let Some((code, _)) = code.split_once(']') + && let Some((_, uid)) = code.split_once(' ') + { + return uid.to_string(); } panic!("No APPENDUID found in {:?}", self.last().unwrap()); } fn into_copy_uid(self) -> String { for line in &self { - if let Some((_, code)) = line.split_once("[COPYUID ") { - if let Some((code, _)) = code.split_once(']') { - if let Some((_, uid)) = code.rsplit_once(' ') { - return uid.to_string(); - } - } + if let Some((_, code)) = line.split_once("[COPYUID ") + && let Some((code, _)) = code.split_once(']') + && let Some((_, uid)) = code.rsplit_once(' ') + { + return uid.to_string(); } } panic!("No COPYUID found in {:?}", self); diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 7a77595e..5cd7c5c1 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -72,10 +72,10 @@ impl AssertConfig for utils::config::Config { pub fn enable_logging() { use common::config::telemetry::Telemetry; - if let Ok(level) = std::env::var("LOG") { - if !Collector::is_enabled() { - Telemetry::test_tracer(level.parse().expect("Invalid log level")); - } + if let Ok(level) = std::env::var("LOG") + && !Collector::is_enabled() + { + Telemetry::test_tracer(level.parse().expect("Invalid log level")); } } diff --git a/tests/src/smtp/inbound/antispam.rs b/tests/src/smtp/inbound/antispam.rs index 2621caf6..89611c63 100644 --- a/tests/src/smtp/inbound/antispam.rs +++ b/tests/src/smtp/inbound/antispam.rs @@ -772,7 +772,7 @@ impl ParseConfigValue for Policy { fn html_tokens() { for (input, expected) in [ ( - concat!("hello
world
"), + "hello
world
", vec![ HtmlToken::StartTag { name: 1819112552, @@ -799,7 +799,7 @@ fn html_tokens() { ], ), ( - concat!("using <>
"), + "using <>
", vec![ HtmlToken::StartTag { name: 1819112552, @@ -818,7 +818,7 @@ fn html_tokens() { ], ), ( - concat!("test tag
"), + "test tag
", vec![ HtmlToken::Text { text: "test".to_compact_string(), @@ -839,7 +839,7 @@ fn html_tokens() { ], ), ( - concat!("<>< >>hello world< br \n />"), + "<>< >>hello world< br \n />", vec![ HtmlToken::StartTag { name: 6775156, diff --git a/tests/src/smtp/queue/manager.rs b/tests/src/smtp/queue/manager.rs index a4be03eb..8354576f 100644 --- a/tests/src/smtp/queue/manager.rs +++ b/tests/src/smtp/queue/manager.rs @@ -200,10 +200,11 @@ fn next_event_after(message: &Message, queue: Option, instant: u64) - { next_event = rcpt.notify.due.into(); } - if let Some(expires) = rcpt.expiration_time(message.created) { - if expires > instant && next_event.as_ref().is_none_or(|ne| expires.lt(ne)) { - next_event = expires.into(); - } + if let Some(expires) = rcpt.expiration_time(message.created) + && expires > instant + && next_event.as_ref().is_none_or(|ne| expires.lt(ne)) + { + next_event = expires.into(); } } }