diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 1ce96eda..f295c217 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -15,11 +15,12 @@ use clap::Parser; use console::style; use jmap_client::client::Credentials; use modules::{ + UnwrapResult, cli::{Cli, Client, Commands}, - is_localhost, UnwrapResult, + is_localhost, }; -use reqwest::{header::AUTHORIZATION, Method, StatusCode}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use reqwest::{Method, StatusCode, header::AUTHORIZATION}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use crate::modules::OAuthResponse; @@ -255,7 +256,9 @@ impl Client { return None; } StatusCode::UNAUTHORIZED => { - eprintln!("Authentication failed. Make sure the credentials are correct and that the account has administrator rights."); + eprintln!( + "Authentication failed. Make sure the credentials are correct and that the account has administrator rights." + ); std::process::exit(1); } _ => { diff --git a/crates/cli/src/modules/account.rs b/crates/cli/src/modules/account.rs index 093a6811..a2450127 100644 --- a/crates/cli/src/modules/account.rs +++ b/crates/cli/src/modules/account.rs @@ -12,8 +12,8 @@ use reqwest::Method; use serde_json::Value; use super::{ - cli::{AccountCommands, Client}, Principal, PrincipalField, PrincipalUpdate, PrincipalValue, Type, + cli::{AccountCommands, Client}, }; impl AccountCommands { @@ -325,7 +325,7 @@ impl Client { if !results.items.is_empty() { let mut table = Table::new(); table.add_row(Row::new(vec![ - Cell::new(&format!("{record_name} Name")).with_style(Attr::Bold) + Cell::new(&format!("{record_name} Name")).with_style(Attr::Bold), ])); for item in &results.items { diff --git a/crates/cli/src/modules/domain.rs b/crates/cli/src/modules/domain.rs index 6ba2b69b..8ea3b5fc 100644 --- a/crates/cli/src/modules/domain.rs +++ b/crates/cli/src/modules/domain.rs @@ -6,7 +6,7 @@ use std::borrow::Cow; -use prettytable::{format, Attr, Cell, Row, Table}; +use prettytable::{Attr, Cell, Row, Table, format}; use reqwest::Method; use serde_json::Value; @@ -102,7 +102,7 @@ impl DomainCommands { if !domains.items.is_empty() { let mut table = Table::new(); table.add_row(Row::new(vec![ - Cell::new("Domain Name").with_style(Attr::Bold) + Cell::new("Domain Name").with_style(Attr::Bold), ])); for domain in &domains.items { diff --git a/crates/cli/src/modules/export.rs b/crates/cli/src/modules/export.rs index a2ac9b3d..efc5f646 100644 --- a/crates/cli/src/modules/export.rs +++ b/crates/cli/src/modules/export.rs @@ -9,7 +9,7 @@ use std::{ sync::Arc, }; -use futures::{stream::FuturesUnordered, StreamExt}; +use futures::{StreamExt, stream::FuturesUnordered}; use jmap_client::{ email::{self, Email}, identity::{self, Identity}, @@ -23,8 +23,9 @@ use tokio::io::AsyncWriteExt; use crate::modules::RETRY_ATTEMPTS; use super::{ + UnwrapResult, cli::{Client, ExportCommands}, - name_to_id, UnwrapResult, + name_to_id, }; impl ExportCommands { diff --git a/crates/cli/src/modules/group.rs b/crates/cli/src/modules/group.rs index f658dc0e..f65eaeee 100644 --- a/crates/cli/src/modules/group.rs +++ b/crates/cli/src/modules/group.rs @@ -12,8 +12,8 @@ use serde_json::Value; use crate::modules::{Principal, Type}; use super::{ - cli::{Client, GroupCommands}, PrincipalField, PrincipalUpdate, PrincipalValue, + cli::{Client, GroupCommands}, }; impl GroupCommands { diff --git a/crates/cli/src/modules/import.rs b/crates/cli/src/modules/import.rs index 4bd1d7d0..d34175bc 100644 --- a/crates/cli/src/modules/import.rs +++ b/crates/cli/src/modules/import.rs @@ -9,14 +9,14 @@ use std::{ io::{self, Cursor}, path::{Path, PathBuf}, sync::{ - atomic::{AtomicUsize, Ordering}, Arc, Mutex, + atomic::{AtomicUsize, Ordering}, }, time::Duration, }; use console::style; -use futures::{stream::FuturesUnordered, StreamExt}; +use futures::{StreamExt, stream::FuturesUnordered}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use jmap_client::{ core::set::SetObject, @@ -30,7 +30,7 @@ use rand::Rng; use serde::de::DeserializeOwned; use tokio::{fs::File, io::AsyncReadExt}; -use crate::modules::{name_to_id, UnwrapResult, RETRY_ATTEMPTS}; +use crate::modules::{RETRY_ATTEMPTS, UnwrapResult, name_to_id}; use super::{ cli::{Client, ImportCommands, MailboxFormat}, @@ -363,8 +363,7 @@ impl ImportCommands { total_imported.fetch_add(1, Ordering::Relaxed); } Err(_) if retry_count < RETRY_ATTEMPTS => { - let backoff = - rand::rng().random_range(50..=300); + let backoff = rand::rng().random_range(50..=300); tokio::time::sleep(Duration::from_millis(backoff)) .await; retry_count += 1; diff --git a/crates/cli/src/modules/list.rs b/crates/cli/src/modules/list.rs index e14f6f98..0a77e2cc 100644 --- a/crates/cli/src/modules/list.rs +++ b/crates/cli/src/modules/list.rs @@ -12,8 +12,8 @@ use serde_json::Value; use crate::modules::{Principal, Type}; use super::{ - cli::{Client, ListCommands}, PrincipalField, PrincipalUpdate, PrincipalValue, + cli::{Client, ListCommands}, }; impl ListCommands { diff --git a/crates/cli/src/modules/queue.rs b/crates/cli/src/modules/queue.rs index 68d2e56e..d4288f26 100644 --- a/crates/cli/src/modules/queue.rs +++ b/crates/cli/src/modules/queue.rs @@ -5,13 +5,13 @@ */ use super::{ - cli::{Client, QueueCommands}, List, + cli::{Client, QueueCommands}, }; use console::Term; use human_size::{Byte, SpecificSize}; use mail_parser::DateTime; -use prettytable::{format::Alignment, Attr, Cell, Row, Table}; +use prettytable::{Attr, Cell, Row, Table, format::Alignment}; use reqwest::Method; use serde::{Deserialize, Deserializer}; @@ -204,13 +204,12 @@ impl QueueCommands { ])); } for domain in &message.domains { - table.add_row(Row::new(vec![Cell::new_align( - &domain.name, - Alignment::RIGHT, - ) - .with_style(Attr::Bold) - .with_style(Attr::Italic(true)) - .with_hspan(2)])); + table.add_row(Row::new(vec![ + Cell::new_align(&domain.name, Alignment::RIGHT) + .with_style(Attr::Bold) + .with_style(Attr::Italic(true)) + .with_hspan(2), + ])); table.add_row(Row::new(vec![ Cell::new("Status").with_style(Attr::Bold), Cell::new(domain.status.status()), @@ -259,11 +258,9 @@ impl QueueCommands { ])); } } else { - table.add_row(Row::new(vec![Cell::new_align( - "-- Not found --", - Alignment::CENTER, - ) - .with_hspan(2)])); + table.add_row(Row::new(vec![ + Cell::new_align("-- Not found --", Alignment::CENTER).with_hspan(2), + ])); } eprintln!(); diff --git a/crates/cli/src/modules/report.rs b/crates/cli/src/modules/report.rs index a76d6605..e43403ae 100644 --- a/crates/cli/src/modules/report.rs +++ b/crates/cli/src/modules/report.rs @@ -5,7 +5,7 @@ */ use super::cli::{Client, ReportCommands, ReportFormat}; -use crate::modules::{queue::deserialize_datetime, List}; +use crate::modules::{List, queue::deserialize_datetime}; use console::Term; use human_size::{Byte, SpecificSize}; use mail_auth::{ @@ -14,7 +14,7 @@ use mail_auth::{ report::{self, tlsrpt::TlsReport}, }; use mail_parser::DateTime; -use prettytable::{format, Attr, Cell, Row, Table}; +use prettytable::{Attr, Cell, Row, Table, format}; use reqwest::Method; use serde::{Deserialize, Serialize}; @@ -197,11 +197,10 @@ impl ReportCommands { ), ])); } else { - table.add_row(Row::new(vec![Cell::new_align( - "-- Not found --", - format::Alignment::CENTER, - ) - .with_hspan(2)])); + table.add_row(Row::new(vec![ + Cell::new_align("-- Not found --", format::Alignment::CENTER) + .with_hspan(2), + ])); } eprintln!(); diff --git a/crates/common/src/addresses.rs b/crates/common/src/addresses.rs index edb7ec37..b850614a 100644 --- a/crates/common/src/addresses.rs +++ b/crates/common/src/addresses.rs @@ -6,15 +6,15 @@ use std::borrow::Cow; -use directory::{backend::RcptType, Directory}; -use utils::config::{utils::AsKey, Config}; +use directory::{Directory, backend::RcptType}; +use utils::config::{Config, utils::AsKey}; use crate::{ + Server, config::smtp::session::AddressMapping, expr::{ - functions::ResolveVariable, if_block::IfBlock, tokenizer::TokenMap, Variable, V_RECIPIENT, + V_RECIPIENT, Variable, functions::ResolveVariable, if_block::IfBlock, tokenizer::TokenMap, }, - Server, }; impl Server { diff --git a/crates/common/src/auth/oauth/crypto.rs b/crates/common/src/auth/oauth/crypto.rs index a576e4b2..28861ae5 100644 --- a/crates/common/src/auth/oauth/crypto.rs +++ b/crates/common/src/auth/oauth/crypto.rs @@ -5,8 +5,8 @@ */ use aes_gcm_siv::{ - aead::{generic_array::GenericArray, Aead}, AeadInPlace, Aes256GcmSiv, KeyInit, Nonce, + aead::{Aead, generic_array::GenericArray}, }; use store::blake3; diff --git a/crates/common/src/auth/oauth/introspect.rs b/crates/common/src/auth/oauth/introspect.rs index 348cc211..243c4d2c 100644 --- a/crates/common/src/auth/oauth/introspect.rs +++ b/crates/common/src/auth/oauth/introspect.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use trc::{AddContext, AuthEvent, EventType}; -use crate::{auth::AccessToken, Server}; +use crate::{Server, auth::AccessToken}; #[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)] pub struct OAuthIntrospect { diff --git a/crates/common/src/auth/oauth/oidc.rs b/crates/common/src/auth/oauth/oidc.rs index fc5ed046..bde3b2f3 100644 --- a/crates/common/src/auth/oauth/oidc.rs +++ b/crates/common/src/auth/oauth/oidc.rs @@ -6,10 +6,10 @@ use std::fmt; -use biscuit::{jws::RegisteredHeader, ClaimsSet, RegisteredClaims, SingleOrMultiple, JWT}; +use biscuit::{ClaimsSet, JWT, RegisteredClaims, SingleOrMultiple, jws::RegisteredHeader}; use serde::{ - de::{self, Visitor}, Deserialize, Deserializer, Serialize, + de::{self, Visitor}, }; use store::write::now; diff --git a/crates/common/src/auth/roles.rs b/crates/common/src/auth/roles.rs index ea7286d4..642f65be 100644 --- a/crates/common/src/auth/roles.rs +++ b/crates/common/src/auth/roles.rs @@ -8,8 +8,8 @@ use std::sync::{Arc, LazyLock}; use ahash::AHashSet; use directory::{ - backend::internal::{lookup::DirectoryStore, PrincipalField}, Permission, Permissions, QueryBy, ROLE_ADMIN, ROLE_TENANT_ADMIN, ROLE_USER, + backend::internal::{PrincipalField, lookup::DirectoryStore}, }; use trc::AddContext; use utils::cache::CacheItemWeight; diff --git a/crates/common/src/config/dav.rs b/crates/common/src/config/dav.rs index 61a80112..bd655371 100644 --- a/crates/common/src/config/dav.rs +++ b/crates/common/src/config/dav.rs @@ -12,6 +12,7 @@ pub struct DavConfig { pub dead_property_size: Option, pub live_property_size: usize, pub max_lock_timeout: u64, + pub max_locks_per_user: usize, pub max_changes: usize, } @@ -28,6 +29,9 @@ impl DavConfig { .property("dav.limits.size.live-property") .unwrap_or(250), max_lock_timeout: config.property("dav.limits.timeout.max-lock").unwrap_or(60), + max_locks_per_user: config + .property("dav.limits.max-locks-per-user") + .unwrap_or(10), max_changes: config.property("dav.limits.max-changes").unwrap_or(1000), } } diff --git a/crates/common/src/config/scripts.rs b/crates/common/src/config/scripts.rs index 184aa8d6..1e6b25df 100644 --- a/crates/common/src/config/scripts.rs +++ b/crates/common/src/config/scripts.rs @@ -7,7 +7,7 @@ use std::{sync::Arc, time::Duration}; use ahash::AHashMap; -use sieve::{compiler::grammar::Capability, Compiler, Runtime, Sieve}; +use sieve::{Compiler, Runtime, Sieve, compiler::grammar::Capability}; use store::Stores; use utils::config::Config; diff --git a/crates/common/src/config/server/listener.rs b/crates/common/src/config/server/listener.rs index 651b841d..8f9b62e9 100644 --- a/crates/common/src/config/server/listener.rs +++ b/crates/common/src/config/server/listener.rs @@ -7,28 +7,28 @@ use std::{net::SocketAddr, sync::Arc, time::Duration}; use rustls::{ - crypto::ring::{default_provider, ALL_CIPHER_SUITES}, - ServerConfig, SupportedCipherSuite, ALL_VERSIONS, + ALL_VERSIONS, ServerConfig, SupportedCipherSuite, + crypto::ring::{ALL_CIPHER_SUITES, default_provider}, }; use tokio::net::TcpSocket; use tokio_rustls::TlsAcceptor; use utils::{ config::{ - utils::{AsKey, ParseValue}, Config, + utils::{AsKey, ParseValue}, }, snowflake::SnowflakeIdGenerator, }; use crate::{ - listener::{tls::CertificateResolver, TcpAcceptor}, Inner, + listener::{TcpAcceptor, tls::CertificateResolver}, }; use super::{ - tls::{TLS12_VERSION, TLS13_VERSION}, Listener, Listeners, ServerProtocol, TcpListener, + tls::{TLS12_VERSION, TLS13_VERSION}, }; impl Listeners { diff --git a/crates/common/src/config/server/tls.rs b/crates/common/src/config/server/tls.rs index 51453694..12bfb58e 100644 --- a/crates/common/src/config/server/tls.rs +++ b/crates/common/src/config/server/tls.rs @@ -13,18 +13,18 @@ use std::{ use ahash::{AHashMap, AHashSet}; use base64::{ - engine::general_purpose::{self, STANDARD}, Engine, + engine::general_purpose::{self, STANDARD}, }; -use dns_update::{providers::rfc2136::DnsAddress, DnsUpdater, TsigAlgorithm}; +use dns_update::{DnsUpdater, TsigAlgorithm, providers::rfc2136::DnsAddress}; use rcgen::generate_simple_self_signed; use rustls::{ + SupportedProtocolVersion, crypto::ring::sign::any_supported_type, sign::CertifiedKey, version::{TLS12, TLS13}, - SupportedProtocolVersion, }; -use rustls_pemfile::{certs, read_one, Item}; +use rustls_pemfile::{Item, certs, read_one}; use rustls_pki_types::PrivateKeyDer; use utils::config::Config; use x509_parser::{ @@ -35,7 +35,7 @@ use x509_parser::{ use crate::listener::{ acme::{ - directory::LETS_ENCRYPT_PRODUCTION_DIRECTORY, AcmeProvider, ChallengeSettings, EabSettings, + AcmeProvider, ChallengeSettings, EabSettings, directory::LETS_ENCRYPT_PRODUCTION_DIRECTORY, }, tls::AcmeProviders, }; @@ -63,11 +63,7 @@ impl AcmeProviders { .values(("acme", acme_id, "contact")) .filter_map(|(_, v)| { let v = v.trim().to_string(); - if !v.is_empty() { - Some(v) - } else { - None - } + if !v.is_empty() { Some(v) } else { None } }) .collect::>(); let renew_before: Duration = config diff --git a/crates/common/src/config/smtp/mod.rs b/crates/common/src/config/smtp/mod.rs index eab742ff..f3ad8d87 100644 --- a/crates/common/src/config/smtp/mod.rs +++ b/crates/common/src/config/smtp/mod.rs @@ -13,7 +13,7 @@ pub mod resolver; pub mod session; pub mod throttle; -use crate::expr::{tokenizer::TokenMap, Expression}; +use crate::expr::{Expression, tokenizer::TokenMap}; use self::{ auth::MailAuthConfig, queue::QueueConfig, report::ReportConfig, resolver::Resolvers, diff --git a/crates/common/src/config/smtp/report.rs b/crates/common/src/config/smtp/report.rs index b442d74b..d8d81e05 100644 --- a/crates/common/src/config/smtp/report.rs +++ b/crates/common/src/config/smtp/report.rs @@ -6,9 +6,9 @@ use std::time::Duration; -use utils::config::{utils::ParseValue, Config}; +use utils::config::{Config, utils::ParseValue}; -use crate::expr::{if_block::IfBlock, tokenizer::TokenMap, Constant, ConstantValue, Variable}; +use crate::expr::{Constant, ConstantValue, Variable, if_block::IfBlock, tokenizer::TokenMap}; use super::*; diff --git a/crates/common/src/config/smtp/session.rs b/crates/common/src/config/smtp/session.rs index 52211cc8..9f7365fb 100644 --- a/crates/common/src/config/smtp/session.rs +++ b/crates/common/src/config/smtp/session.rs @@ -11,13 +11,13 @@ use std::{ }; use ahash::AHashSet; -use base64::{engine::general_purpose::STANDARD, Engine}; +use base64::{Engine, engine::general_purpose::STANDARD}; use hyper::{ - header::{HeaderName, HeaderValue, AUTHORIZATION, CONTENT_TYPE}, HeaderMap, + header::{AUTHORIZATION, CONTENT_TYPE, HeaderName, HeaderValue}, }; use smtp_proto::*; -use utils::config::{utils::ParseValue, Config}; +use utils::config::{Config, utils::ParseValue}; use crate::{ config::CONNECTION_VARS, diff --git a/crates/common/src/config/smtp/throttle.rs b/crates/common/src/config/smtp/throttle.rs index f76283e0..b800cf03 100644 --- a/crates/common/src/config/smtp/throttle.rs +++ b/crates/common/src/config/smtp/throttle.rs @@ -4,9 +4,9 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use utils::config::{utils::AsKey, Config, Rate}; +use utils::config::{Config, Rate, utils::AsKey}; -use crate::expr::{tokenizer::TokenMap, Expression}; +use crate::expr::{Expression, tokenizer::TokenMap}; use super::*; diff --git a/crates/common/src/config/spamfilter.rs b/crates/common/src/config/spamfilter.rs index 8e04bb1c..865bb6db 100644 --- a/crates/common/src/config/spamfilter.rs +++ b/crates/common/src/config/spamfilter.rs @@ -15,11 +15,11 @@ use nlp::bayes::BayesClassifier; use tokio::net::lookup_host; use utils::{ cache::CacheItemWeight, - config::{utils::ParseValue, Config}, + config::{Config, utils::ParseValue}, glob::GlobMap, }; -use super::{functions::ResolveVariable, if_block::IfBlock, tokenizer::TokenMap, Variable}; +use super::{Variable, functions::ResolveVariable, if_block::IfBlock, tokenizer::TokenMap}; #[derive(Debug, Clone, Default)] pub struct SpamFilterConfig { diff --git a/crates/common/src/config/telemetry.rs b/crates/common/src/config/telemetry.rs index c172c576..dc286a95 100644 --- a/crates/common/src/config/telemetry.rs +++ b/crates/common/src/config/telemetry.rs @@ -7,22 +7,22 @@ use std::{collections::HashMap, str::FromStr, sync::Arc, time::Duration}; use ahash::{AHashMap, AHashSet}; -use base64::{engine::general_purpose::STANDARD, Engine}; -use hyper::{header::CONTENT_TYPE, HeaderMap}; +use base64::{Engine, engine::general_purpose::STANDARD}; +use hyper::{HeaderMap, header::CONTENT_TYPE}; use opentelemetry::{InstrumentationLibrary, KeyValue}; use opentelemetry_otlp::WithExportConfig; use opentelemetry_sdk::{ + Resource, export::{logs::LogExporter, trace::SpanExporter}, metrics::{ exporter::PushMetricsExporter, reader::{DefaultAggregationSelector, DefaultTemporalitySelector}, }, - Resource, }; use opentelemetry_semantic_conventions::resource::{SERVICE_NAME, SERVICE_VERSION}; use store::Stores; -use trc::{ipc::subscriber::Interests, EventType, Level, TelemetryEvent}; -use utils::config::{utils::ParseValue, Config}; +use trc::{EventType, Level, TelemetryEvent, ipc::subscriber::Interests}; +use utils::config::{Config, utils::ParseValue}; use super::parse_http_headers; diff --git a/crates/common/src/enterprise/alerts.rs b/crates/common/src/enterprise/alerts.rs index dda7eea2..4d651fc6 100644 --- a/crates/common/src/enterprise/alerts.rs +++ b/crates/common/src/enterprise/alerts.rs @@ -9,18 +9,18 @@ */ use mail_builder::{ - headers::{ - address::{Address, EmailAddress}, - HeaderType, - }, MessageBuilder, + headers::{ + HeaderType, + address::{Address, EmailAddress}, + }, }; -use trc::{Collector, MetricType, TelemetryEvent, TOTAL_EVENT_COUNT}; +use trc::{Collector, MetricType, TOTAL_EVENT_COUNT, TelemetryEvent}; use super::{AlertContent, AlertContentToken, AlertMethod}; use crate::{ - expr::{functions::ResolveVariable, Variable}, Server, + expr::{Variable, functions::ResolveVariable}, }; use std::fmt::Write; diff --git a/crates/common/src/enterprise/config.rs b/crates/common/src/enterprise/config.rs index e9b8f192..0bc30d68 100644 --- a/crates/common/src/enterprise/config.rs +++ b/crates/common/src/enterprise/config.rs @@ -11,23 +11,23 @@ use std::{sync::Arc, time::Duration}; use ahash::AHashMap; -use directory::{backend::internal::manage::ManageDirectory, Type}; +use directory::{Type, backend::internal::manage::ManageDirectory}; use store::{Store, Stores}; use trc::{EventType, MetricType, TOTAL_EVENT_COUNT}; use utils::config::{ + Config, ConfigKey, cron::SimpleCron, utils::{AsKey, ParseValue}, - Config, ConfigKey, }; use crate::{ - expr::{tokenizer::TokenMap, Expression}, + expr::{Expression, tokenizer::TokenMap}, manager::config::ConfigManager, }; use super::{ - license::LicenseKey, llm::AiApiConfig, AlertContent, AlertContentToken, AlertMethod, - Enterprise, MetricAlert, MetricStore, SpamFilterLlmConfig, TraceStore, Undelete, + AlertContent, AlertContentToken, AlertMethod, Enterprise, MetricAlert, MetricStore, + SpamFilterLlmConfig, TraceStore, Undelete, license::LicenseKey, llm::AiApiConfig, }; impl Enterprise { @@ -103,9 +103,10 @@ impl Enterprise { ) .await { - trc::error!(err - .caused_by(trc::location!()) - .details("Failed to update license key")); + trc::error!( + err.caused_by(trc::location!()) + .details("Failed to update license key") + ); } } diff --git a/crates/common/src/enterprise/license.rs b/crates/common/src/enterprise/license.rs index b5f161f1..a925ec59 100644 --- a/crates/common/src/enterprise/license.rs +++ b/crates/common/src/enterprise/license.rs @@ -24,10 +24,10 @@ use std::{ time::Duration, }; -use hyper::{header::AUTHORIZATION, HeaderMap}; -use ring::signature::{UnparsedPublicKey, ED25519}; +use hyper::{HeaderMap, header::AUTHORIZATION}; +use ring::signature::{ED25519, UnparsedPublicKey}; -use base64::{engine::general_purpose::STANDARD, Engine}; +use base64::{Engine, engine::general_purpose::STANDARD}; use store::write::now; use trc::ServerEvent; diff --git a/crates/common/src/enterprise/llm.rs b/crates/common/src/enterprise/llm.rs index bc370b4b..8338f39d 100644 --- a/crates/common/src/enterprise/llm.rs +++ b/crates/common/src/enterprise/llm.rs @@ -10,7 +10,7 @@ use std::time::Duration; -use hyper::{header::CONTENT_TYPE, HeaderMap}; +use hyper::{HeaderMap, header::CONTENT_TYPE}; use serde::{Deserialize, Serialize}; use utils::config::Config; diff --git a/crates/common/src/enterprise/mod.rs b/crates/common/src/enterprise/mod.rs index 5eec0f98..ac7d7ee2 100644 --- a/crates/common/src/enterprise/mod.rs +++ b/crates/common/src/enterprise/mod.rs @@ -18,17 +18,17 @@ use std::{sync::Arc, time::Duration}; use ahash::{AHashMap, AHashSet}; use directory::{ - backend::internal::{lookup::DirectoryStore, PrincipalField}, QueryBy, Type, + backend::internal::{PrincipalField, lookup::DirectoryStore}, }; use license::LicenseKey; use llm::AiApiConfig; use mail_parser::DateTime; use store::Store; use trc::{AddContext, EventType, MetricType}; -use utils::{config::cron::SimpleCron, HttpLimitResponse}; +use utils::{HttpLimitResponse, config::cron::SimpleCron}; -use crate::{expr::Expression, manager::webadmin::Resource, Core, Server}; +use crate::{Core, Server, expr::Expression, manager::webadmin::Resource}; #[derive(Clone)] pub struct Enterprise { diff --git a/crates/common/src/enterprise/undelete.rs b/crates/common/src/enterprise/undelete.rs index 57355c43..9dd47bbf 100644 --- a/crates/common/src/enterprise/undelete.rs +++ b/crates/common/src/enterprise/undelete.rs @@ -10,14 +10,15 @@ use serde::{Deserialize, Serialize}; use store::{ + IterateParams, U32_LEN, U64_LEN, ValueKey, write::{ + BatchBuilder, BlobOp, ValueClass, key::{DeserializeBigEndian, KeySerializer}, - now, BatchBuilder, BlobOp, ValueClass, + now, }, - IterateParams, ValueKey, U32_LEN, U64_LEN, }; use trc::AddContext; -use utils::{BlobHash, BLOB_HASH_LEN}; +use utils::{BLOB_HASH_LEN, BlobHash}; use crate::Core; diff --git a/crates/common/src/expr/eval.rs b/crates/common/src/expr/eval.rs index a8a51855..4d6cf5e2 100644 --- a/crates/common/src/expr/eval.rs +++ b/crates/common/src/expr/eval.rs @@ -12,9 +12,9 @@ use trc::EvalEvent; use crate::Server; use super::{ - functions::{ResolveVariable, FUNCTIONS}, - if_block::IfBlock, BinaryOperator, Constant, Expression, ExpressionItem, Setting, UnaryOperator, Variable, + functions::{FUNCTIONS, ResolveVariable}, + if_block::IfBlock, }; impl Server { diff --git a/crates/common/src/expr/functions/asynch.rs b/crates/common/src/expr/functions/asynch.rs index b745961d..c44be31f 100644 --- a/crates/common/src/expr/functions/asynch.rs +++ b/crates/common/src/expr/functions/asynch.rs @@ -4,11 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - use std::{cmp::Ordering, net::IpAddr, vec::IntoIter}; +use std::{cmp::Ordering, net::IpAddr, vec::IntoIter}; use directory::backend::RcptType; use mail_auth::IpLookupStrategy; -use store::{dispatch::lookup::KeyValue, Deserialize, Rows, Value}; +use store::{Deserialize, Rows, Value, dispatch::lookup::KeyValue}; use trc::AddContext; use crate::Server; diff --git a/crates/common/src/expr/functions/misc.rs b/crates/common/src/expr/functions/misc.rs index 004b5d74..13cfac3c 100644 --- a/crates/common/src/expr/functions/misc.rs +++ b/crates/common/src/expr/functions/misc.rs @@ -55,9 +55,5 @@ pub(crate) fn fn_if_then(v: Vec) -> Variable { let iff = v.next().unwrap(); let then = v.next().unwrap(); - if condition.to_bool() { - iff - } else { - then - } + if condition.to_bool() { iff } else { then } } diff --git a/crates/common/src/expr/if_block.rs b/crates/common/src/expr/if_block.rs index 921a0c17..be643129 100644 --- a/crates/common/src/expr/if_block.rs +++ b/crates/common/src/expr/if_block.rs @@ -4,14 +4,14 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::expr::{Constant, Expression}; use super::{ + ConstantValue, ExpressionItem, parser::ExpressionParser, tokenizer::{TokenMap, Tokenizer}, - ConstantValue, ExpressionItem, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/common/src/expr/mod.rs b/crates/common/src/expr/mod.rs index 19ed51bd..6e5c4df3 100644 --- a/crates/common/src/expr/mod.rs +++ b/crates/common/src/expr/mod.rs @@ -69,7 +69,7 @@ pub const VARIABLES_MAP: &[(&str, u32)] = &[ ]; use regex::Regex; -use utils::config::{utils::ParseValue, Rate}; +use utils::config::{Rate, utils::ParseValue}; use self::tokenizer::TokenMap; diff --git a/crates/common/src/expr/parser.rs b/crates/common/src/expr/parser.rs index 63d2c71b..60eec29d 100644 --- a/crates/common/src/expr/parser.rs +++ b/crates/common/src/expr/parser.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{tokenizer::Tokenizer, BinaryOperator, Expression, ExpressionItem, Token}; +use super::{BinaryOperator, Expression, ExpressionItem, Token, tokenizer::Tokenizer}; pub struct ExpressionParser<'x> { pub(crate) tokenizer: Tokenizer<'x>, diff --git a/crates/common/src/listener/acme/cache.rs b/crates/common/src/listener/acme/cache.rs index e79df89a..32d14f6e 100644 --- a/crates/common/src/listener/acme/cache.rs +++ b/crates/common/src/listener/acme/cache.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine}; +use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD}; use trc::AddContext; use utils::config::ConfigKey; diff --git a/crates/common/src/listener/acme/directory.rs b/crates/common/src/listener/acme/directory.rs index 00a51513..e8b0de25 100644 --- a/crates/common/src/listener/acme/directory.rs +++ b/crates/common/src/listener/acme/directory.rs @@ -12,7 +12,7 @@ use ring::rand::SystemRandom; use ring::signature::{ECDSA_P256_SHA256_FIXED_SIGNING, EcdsaKeyPair, EcdsaSigningAlgorithm}; use serde::Deserialize; use store::write::Archiver; -use store::{Serialize, SerializedVersion, SERIALIZE_OBJ_01_V1}; +use store::{SERIALIZE_OBJ_01_V1, Serialize, SerializedVersion}; use trc::AddContext; use trc::event::conv::AssertSuccess; diff --git a/crates/common/src/listener/acme/jose.rs b/crates/common/src/listener/acme/jose.rs index 27f46663..0a25466b 100644 --- a/crates/common/src/listener/acme/jose.rs +++ b/crates/common/src/listener/acme/jose.rs @@ -1,8 +1,8 @@ // Adapted from rustls-acme (https://github.com/FlorianUekermann/rustls-acme), licensed under MIT/Apache-2.0. -use base64::engine::general_purpose::URL_SAFE_NO_PAD; use base64::Engine; -use ring::digest::{digest, Digest, SHA256}; +use base64::engine::general_purpose::URL_SAFE_NO_PAD; +use ring::digest::{Digest, SHA256, digest}; use ring::hmac; use ring::rand::SystemRandom; use ring::signature::{EcdsaKeyPair, KeyPair}; diff --git a/crates/common/src/listener/acme/order.rs b/crates/common/src/listener/acme/order.rs index 21b28c9a..e13bb8c3 100644 --- a/crates/common/src/listener/acme/order.rs +++ b/crates/common/src/listener/acme/order.rs @@ -13,12 +13,12 @@ use store::dispatch::lookup::KeyValue; use trc::{AcmeEvent, EventType}; use x509_parser::parse_x509_certificate; -use crate::listener::acme::directory::Identifier; use crate::listener::acme::ChallengeSettings; -use crate::{Server, KV_ACME}; +use crate::listener::acme::directory::Identifier; +use crate::{KV_ACME, Server}; -use super::directory::{Account, AuthStatus, Directory, OrderStatus}; use super::AcmeProvider; +use super::directory::{Account, AuthStatus, Directory, OrderStatus}; impl Server { pub(crate) async fn process_cert( @@ -76,7 +76,7 @@ impl Server { return Err(err .details("Failed to renew certificate") .ctx_unique(trc::Key::Id, provider.id.to_string()) - .ctx_unique(trc::Key::Hostname, provider.domains.as_slice())) + .ctx_unique(trc::Key::Hostname, provider.domains.as_slice())); } } } @@ -346,7 +346,7 @@ impl Server { return Err(EventType::Acme(AcmeEvent::AuthError) .into_err() .ctx(trc::Key::Id, provider.id.to_string()) - .ctx(trc::Key::Details, auth.status.as_str())) + .ctx(trc::Key::Details, auth.status.as_str())); } }; @@ -377,7 +377,7 @@ impl Server { return Err(EventType::Acme(AcmeEvent::AuthError) .into_err() .ctx(trc::Key::Id, provider.id.to_string()) - .ctx(trc::Key::Details, auth.status.as_str())) + .ctx(trc::Key::Details, auth.status.as_str())); } } } @@ -407,7 +407,7 @@ fn parse_cert(pem: &[u8]) -> trc::Result<(CertifiedKey, [DateTime; 2])> { Err(err) => { return Err(EventType::Acme(AcmeEvent::Error) .reason(err) - .caused_by(trc::location!())) + .caused_by(trc::location!())); } }; let cert_chain: Vec = pems @@ -426,7 +426,7 @@ fn parse_cert(pem: &[u8]) -> trc::Result<(CertifiedKey, [DateTime; 2])> { Err(err) => { return Err(EventType::Acme(AcmeEvent::Error) .reason(err) - .caused_by(trc::location!())) + .caused_by(trc::location!())); } }; let cert = CertifiedKey::new(cert_chain, pk); diff --git a/crates/common/src/listener/asn.rs b/crates/common/src/listener/asn.rs index 54ffbe47..4708f80a 100644 --- a/crates/common/src/listener/asn.rs +++ b/crates/common/src/listener/asn.rs @@ -6,7 +6,7 @@ use std::{ net::IpAddr, - sync::{atomic::AtomicU64, Arc}, + sync::{Arc, atomic::AtomicU64}, time::{Duration, Instant}, }; @@ -16,7 +16,7 @@ use mail_auth::common::resolver::ToReverseName; use store::write::now; use tokio::sync::Semaphore; -use crate::{config::network::AsnGeoLookupConfig, manager::fetch_resource, Server}; +use crate::{Server, config::network::AsnGeoLookupConfig, manager::fetch_resource}; pub struct AsnGeoLookupData { pub lock: Semaphore, diff --git a/crates/common/src/listener/blocked.rs b/crates/common/src/listener/blocked.rs index 33df6664..f92c92c0 100644 --- a/crates/common/src/listener/blocked.rs +++ b/crates/common/src/listener/blocked.rs @@ -9,16 +9,16 @@ use std::{fmt::Debug, net::IpAddr}; use ahash::AHashSet; use utils::{ config::{ + Config, ConfigKey, Rate, ipmask::{IpAddrMask, IpAddrOrMask}, utils::ParseValue, - Config, ConfigKey, Rate, }, glob::GlobPattern, }; use crate::{ - ip_to_bytes, manager::config::MatchType, Server, KV_RATE_LIMIT_AUTH, KV_RATE_LIMIT_LOITER, - KV_RATE_LIMIT_RCPT, KV_RATE_LIMIT_SCAN, + KV_RATE_LIMIT_AUTH, KV_RATE_LIMIT_LOITER, KV_RATE_LIMIT_RCPT, KV_RATE_LIMIT_SCAN, Server, + ip_to_bytes, manager::config::MatchType, }; #[derive(Debug, Clone)] diff --git a/crates/common/src/listener/limiter.rs b/crates/common/src/listener/limiter.rs index 5c009071..b21bce37 100644 --- a/crates/common/src/listener/limiter.rs +++ b/crates/common/src/listener/limiter.rs @@ -5,8 +5,8 @@ */ use std::sync::{ - atomic::{AtomicU64, Ordering}, Arc, + atomic::{AtomicU64, Ordering}, }; #[derive(Debug, Clone)] diff --git a/crates/common/src/listener/listen.rs b/crates/common/src/listener/listen.rs index 55ef0e8d..0347a55b 100644 --- a/crates/common/src/listener/listen.rs +++ b/crates/common/src/listener/listen.rs @@ -15,17 +15,17 @@ use rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256; use tokio::{net::TcpStream, sync::watch}; use tokio_rustls::server::TlsStream; use trc::{EventType, HttpEvent, ImapEvent, ManageSieveEvent, Pop3Event, SmtpEvent}; -use utils::{config::Config, UnwrapFailure}; +use utils::{UnwrapFailure, config::Config}; use crate::{ + Inner, Server, config::server::{Listener, Listeners, ServerProtocol, TcpListener}, core::BuildServer, - Inner, Server, }; use super::{ - limiter::{ConcurrencyLimiter, LimiterResult}, ServerInstance, SessionData, SessionManager, SessionStream, TcpAcceptor, + limiter::{ConcurrencyLimiter, LimiterResult}, }; impl Listener { diff --git a/crates/common/src/listener/mod.rs b/crates/common/src/listener/mod.rs index b0f7312f..9cbf7b6a 100644 --- a/crates/common/src/listener/mod.rs +++ b/crates/common/src/listener/mod.rs @@ -17,9 +17,9 @@ use trc::{Event, EventType, Key}; use utils::{config::ipmask::IpAddrMask, snowflake::SnowflakeIdGenerator}; use crate::{ + Server, config::server::ServerProtocol, expr::{functions::ResolveVariable, *}, - Server, }; use self::limiter::{ConcurrencyLimiter, InFlight}; diff --git a/crates/common/src/listener/tls.rs b/crates/common/src/listener/tls.rs index 15ec20f1..cac0b6c1 100644 --- a/crates/common/src/listener/tls.rs +++ b/crates/common/src/listener/tls.rs @@ -12,10 +12,10 @@ use std::{ use ahash::AHashMap; use rustls::{ + SupportedProtocolVersion, server::{ClientHello, ResolvesServerCert}, sign::CertifiedKey, version::{TLS12, TLS13}, - SupportedProtocolVersion, }; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use tokio_rustls::{Accept, LazyConfigAcceptor}; @@ -23,11 +23,11 @@ use tokio_rustls::{Accept, LazyConfigAcceptor}; use crate::{Inner, Server}; use super::{ - acme::{ - resolver::{build_acme_static_resolver, IsTlsAlpnChallenge}, - AcmeProvider, - }, ServerInstance, SessionStream, TcpAcceptor, TcpAcceptorResult, + acme::{ + AcmeProvider, + resolver::{IsTlsAlpnChallenge, build_acme_static_resolver}, + }, }; pub static TLS13_VERSION: &[&SupportedProtocolVersion] = &[&TLS13]; diff --git a/crates/common/src/manager/console.rs b/crates/common/src/manager/console.rs index ec92ed3f..9e149225 100644 --- a/crates/common/src/manager/console.rs +++ b/crates/common/src/manager/console.rs @@ -7,12 +7,12 @@ use std::env; use std::io::{self, Write}; -use base64::engine::general_purpose; use base64::Engine; +use base64::engine::general_purpose; use store::write::{AnyClass, AnyKey, BatchBuilder, ValueClass}; use store::{ - Deserialize, IterateParams, Store, SUBSPACE_BITMAP_ID, SUBSPACE_BITMAP_TAG, - SUBSPACE_BITMAP_TEXT, SUBSPACE_INDEXES, + Deserialize, IterateParams, SUBSPACE_BITMAP_ID, SUBSPACE_BITMAP_TAG, SUBSPACE_BITMAP_TEXT, + SUBSPACE_INDEXES, Store, }; const HELP: &str = concat!( diff --git a/crates/common/src/manager/reload.rs b/crates/common/src/manager/reload.rs index 6b4765f4..75e163d9 100644 --- a/crates/common/src/manager/reload.rs +++ b/crates/common/src/manager/reload.rs @@ -10,12 +10,12 @@ use store::Stores; use utils::config::Config; use crate::{ + Core, Server, config::{ - server::{tls::parse_certificates, Listeners}, + server::{Listeners, tls::parse_certificates}, telemetry::Telemetry, }, - listener::blocked::{BlockedIps, BLOCKED_IP_KEY}, - Core, Server, + listener::blocked::{BLOCKED_IP_KEY, BlockedIps}, }; use super::config::{ConfigManager, Patterns}; diff --git a/crates/common/src/scripts/functions/array.rs b/crates/common/src/scripts/functions/array.rs index 578c2bda..796dcc68 100644 --- a/crates/common/src/scripts/functions/array.rs +++ b/crates/common/src/scripts/functions/array.rs @@ -6,7 +6,7 @@ use std::collections::{HashMap, HashSet}; -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; pub fn fn_count<'x>(_: &'x Context<'x>, v: Vec) -> Variable { match &v[0] { diff --git a/crates/common/src/scripts/functions/email.rs b/crates/common/src/scripts/functions/email.rs index 4234fb52..75bba0f0 100644 --- a/crates/common/src/scripts/functions/email.rs +++ b/crates/common/src/scripts/functions/email.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; use super::ApplyString; diff --git a/crates/common/src/scripts/functions/header.rs b/crates/common/src/scripts/functions/header.rs index 5a1bb9b3..e6da15a8 100644 --- a/crates/common/src/scripts/functions/header.rs +++ b/crates/common/src/scripts/functions/header.rs @@ -4,8 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use mail_parser::{parsers::fields::thread::thread_name, HeaderName, HeaderValue, MimeHeaders}; -use sieve::{compiler::ReceivedPart, runtime::Variable, Context}; +use mail_parser::{HeaderName, HeaderValue, MimeHeaders, parsers::fields::thread::thread_name}; +use sieve::{Context, compiler::ReceivedPart, runtime::Variable}; use super::ApplyString; diff --git a/crates/common/src/scripts/functions/image.rs b/crates/common/src/scripts/functions/image.rs index 5d99187d..e3634f3f 100644 --- a/crates/common/src/scripts/functions/image.rs +++ b/crates/common/src/scripts/functions/image.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; pub fn fn_img_metadata<'x>(ctx: &'x Context<'x>, v: Vec) -> Variable { ctx.message() diff --git a/crates/common/src/scripts/functions/misc.rs b/crates/common/src/scripts/functions/misc.rs index d56137fc..af461879 100644 --- a/crates/common/src/scripts/functions/misc.rs +++ b/crates/common/src/scripts/functions/misc.rs @@ -9,7 +9,7 @@ use std::net::IpAddr; use mail_auth::common::resolver::ToReverseName; use sha1::Sha1; use sha2::{Sha256, Sha512}; -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; use super::ApplyString; diff --git a/crates/common/src/scripts/functions/mod.rs b/crates/common/src/scripts/functions/mod.rs index 18c09ba0..451110dc 100644 --- a/crates/common/src/scripts/functions/mod.rs +++ b/crates/common/src/scripts/functions/mod.rs @@ -13,7 +13,7 @@ pub mod text; pub mod unicode; pub mod url; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use self::{array::*, email::*, header::*, image::*, misc::*, text::*, unicode::*, url::*}; diff --git a/crates/common/src/scripts/functions/text.rs b/crates/common/src/scripts/functions/text.rs index 610db889..f74c0363 100644 --- a/crates/common/src/scripts/functions/text.rs +++ b/crates/common/src/scripts/functions/text.rs @@ -5,7 +5,7 @@ */ use mail_parser::decoders::html::html_to_text; -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; use super::ApplyString; diff --git a/crates/common/src/scripts/functions/unicode.rs b/crates/common/src/scripts/functions/unicode.rs index 720fc56f..e57f58fc 100644 --- a/crates/common/src/scripts/functions/unicode.rs +++ b/crates/common/src/scripts/functions/unicode.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; use crate::scripts::IsMixedCharset; diff --git a/crates/common/src/scripts/functions/url.rs b/crates/common/src/scripts/functions/url.rs index b6afd607..cf706144 100644 --- a/crates/common/src/scripts/functions/url.rs +++ b/crates/common/src/scripts/functions/url.rs @@ -5,7 +5,7 @@ */ use hyper::Uri; -use sieve::{runtime::Variable, Context}; +use sieve::{Context, runtime::Variable}; use super::ApplyString; diff --git a/crates/common/src/scripts/mod.rs b/crates/common/src/scripts/mod.rs index a40e067d..a7fed493 100644 --- a/crates/common/src/scripts/mod.rs +++ b/crates/common/src/scripts/mod.rs @@ -6,7 +6,7 @@ use std::sync::Arc; -use sieve::{runtime::Variable, Envelope}; +use sieve::{Envelope, runtime::Variable}; use store::Value; use unicode_security::mixed_script::AugmentedScriptSet; diff --git a/crates/common/src/scripts/plugins/dns.rs b/crates/common/src/scripts/plugins/dns.rs index bf8d9299..0be46011 100644 --- a/crates/common/src/scripts/plugins/dns.rs +++ b/crates/common/src/scripts/plugins/dns.rs @@ -7,7 +7,7 @@ use std::net::IpAddr; use mail_auth::IpLookupStrategy; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use super::PluginContext; diff --git a/crates/common/src/scripts/plugins/exec.rs b/crates/common/src/scripts/plugins/exec.rs index 5abd7758..9e910cda 100644 --- a/crates/common/src/scripts/plugins/exec.rs +++ b/crates/common/src/scripts/plugins/exec.rs @@ -6,7 +6,7 @@ use std::process::Command; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use super::PluginContext; diff --git a/crates/common/src/scripts/plugins/headers.rs b/crates/common/src/scripts/plugins/headers.rs index e33e1d79..77f3b1d3 100644 --- a/crates/common/src/scripts/plugins/headers.rs +++ b/crates/common/src/scripts/plugins/headers.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use crate::scripts::ScriptModification; diff --git a/crates/common/src/scripts/plugins/http.rs b/crates/common/src/scripts/plugins/http.rs index 6cba1fe6..42e2af55 100644 --- a/crates/common/src/scripts/plugins/http.rs +++ b/crates/common/src/scripts/plugins/http.rs @@ -7,7 +7,7 @@ use std::time::Duration; use reqwest::redirect::Policy; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use super::PluginContext; diff --git a/crates/common/src/scripts/plugins/lookup.rs b/crates/common/src/scripts/plugins/lookup.rs index 40c55f84..7abd2d72 100644 --- a/crates/common/src/scripts/plugins/lookup.rs +++ b/crates/common/src/scripts/plugins/lookup.rs @@ -4,8 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use sieve::{runtime::Variable, FunctionMap}; -use store::{dispatch::lookup::KeyValue, Deserialize, Value}; +use sieve::{FunctionMap, runtime::Variable}; +use store::{Deserialize, Value, dispatch::lookup::KeyValue}; use crate::scripts::into_sieve_value; diff --git a/crates/common/src/scripts/plugins/mod.rs b/crates/common/src/scripts/plugins/mod.rs index 4cdfd164..8c529267 100644 --- a/crates/common/src/scripts/plugins/mod.rs +++ b/crates/common/src/scripts/plugins/mod.rs @@ -14,9 +14,9 @@ pub mod query; pub mod text; use mail_parser::Message; -use sieve::{runtime::Variable, FunctionMap, Input}; +use sieve::{FunctionMap, Input, runtime::Variable}; -use crate::{auth::AccessToken, Core, Server}; +use crate::{Core, Server, auth::AccessToken}; use super::ScriptModification; diff --git a/crates/common/src/scripts/plugins/query.rs b/crates/common/src/scripts/plugins/query.rs index 70f918b7..c0a84f1d 100644 --- a/crates/common/src/scripts/plugins/query.rs +++ b/crates/common/src/scripts/plugins/query.rs @@ -7,7 +7,7 @@ use std::cmp::Ordering; use crate::scripts::{into_sieve_value, to_store_value}; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; use store::{Rows, Value}; use super::PluginContext; @@ -31,9 +31,11 @@ pub async fn exec(ctx: PluginContext<'_>) -> trc::Result { // Obtain query string let query = ctx.arguments[1].to_string(); if query.is_empty() { - trc::bail!(trc::SieveEvent::RuntimeError - .ctx(trc::Key::Id, ctx.arguments[0].to_string().into_owned()) - .details("Empty query string")); + trc::bail!( + trc::SieveEvent::RuntimeError + .ctx(trc::Key::Id, ctx.arguments[0].to_string().into_owned()) + .details("Empty query string") + ); } // Obtain arguments diff --git a/crates/common/src/scripts/plugins/text.rs b/crates/common/src/scripts/plugins/text.rs index 8ea351be..d36014ca 100644 --- a/crates/common/src/scripts/plugins/text.rs +++ b/crates/common/src/scripts/plugins/text.rs @@ -5,9 +5,9 @@ */ use nlp::tokenizers::types::{TokenType, TypesTokenizer}; -use sieve::{runtime::Variable, FunctionMap}; +use sieve::{FunctionMap, runtime::Variable}; -use crate::scripts::functions::{text::tokenize_words, ApplyString}; +use crate::scripts::functions::{ApplyString, text::tokenize_words}; use super::PluginContext; diff --git a/crates/common/src/telemetry/metrics/prometheus.rs b/crates/common/src/telemetry/metrics/prometheus.rs index 46bcf9c7..c614e87b 100644 --- a/crates/common/src/telemetry/metrics/prometheus.rs +++ b/crates/common/src/telemetry/metrics/prometheus.rs @@ -5,10 +5,10 @@ */ use prometheus::{ - proto::{Bucket, Counter, Gauge, Histogram, Metric, MetricFamily, MetricType}, TextEncoder, + proto::{Bucket, Counter, Gauge, Histogram, Metric, MetricFamily, MetricType}, }; -use trc::{atomics::histogram::AtomicHistogram, Collector}; +use trc::{Collector, atomics::histogram::AtomicHistogram}; use crate::Server; diff --git a/crates/common/src/telemetry/metrics/store.rs b/crates/common/src/telemetry/metrics/store.rs index 4af40f3e..e42e9753 100644 --- a/crates/common/src/telemetry/metrics/store.rs +++ b/crates/common/src/telemetry/metrics/store.rs @@ -14,11 +14,12 @@ use ahash::AHashMap; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use store::{ + IterateParams, Store, U32_LEN, U64_LEN, ValueKey, write::{ + BatchBuilder, TelemetryClass, ValueClass, key::{DeserializeBigEndian, KeySerializer}, - now, BatchBuilder, TelemetryClass, ValueClass, + now, }, - IterateParams, Store, ValueKey, U32_LEN, U64_LEN, }; use trc::*; use utils::codec::leb128::Leb128Reader; diff --git a/crates/common/src/telemetry/tracers/log.rs b/crates/common/src/telemetry/tracers/log.rs index 39c4a91b..50743708 100644 --- a/crates/common/src/telemetry/tracers/log.rs +++ b/crates/common/src/telemetry/tracers/log.rs @@ -13,7 +13,7 @@ use tokio::{ fs::{File, OpenOptions}, io::BufWriter, }; -use trc::{ipc::subscriber::SubscriberBuilder, serializers::text::FmtWriter, TelemetryEvent}; +use trc::{TelemetryEvent, ipc::subscriber::SubscriberBuilder, serializers::text::FmtWriter}; pub(crate) fn spawn_log_tracer(builder: SubscriberBuilder, settings: LogTracer) { let (_, mut rx) = builder.register(); diff --git a/crates/common/src/telemetry/tracers/stdout.rs b/crates/common/src/telemetry/tracers/stdout.rs index c46cdd0c..a727fe58 100644 --- a/crates/common/src/telemetry/tracers/stdout.rs +++ b/crates/common/src/telemetry/tracers/stdout.rs @@ -5,7 +5,7 @@ */ use std::{ - io::{stderr, Error}, + io::{Error, stderr}, pin::Pin, task::{Context, Poll}, }; diff --git a/crates/common/src/telemetry/tracers/store.rs b/crates/common/src/telemetry/tracers/store.rs index 3de86b08..a3f160d5 100644 --- a/crates/common/src/telemetry/tracers/store.rs +++ b/crates/common/src/telemetry/tracers/store.rs @@ -12,14 +12,14 @@ use std::{future::Future, time::Duration}; use ahash::{AHashMap, AHashSet}; use store::{ - write::{key::DeserializeBigEndian, BatchBuilder, MaybeDynamicId, TelemetryClass, ValueClass}, - Deserialize, IterateParams, Store, ValueKey, U64_LEN, + Deserialize, IterateParams, Store, U64_LEN, ValueKey, + write::{BatchBuilder, MaybeDynamicId, TelemetryClass, ValueClass, key::DeserializeBigEndian}, }; use trc::{ - ipc::subscriber::SubscriberBuilder, - serializers::binary::{deserialize_events, serialize_events}, AddContext, AuthEvent, Event, EventDetails, EventType, Key, MessageIngestEvent, OutgoingReportEvent, QueueEvent, Value, + ipc::subscriber::SubscriberBuilder, + serializers::binary::{deserialize_events, serialize_events}, }; use utils::snowflake::SnowflakeIdGenerator; diff --git a/crates/dav-proto/resources/requests/propertyupdate-001.json b/crates/dav-proto/resources/requests/propertyupdate-001.json index e89c3cf2..f3005bed 100644 --- a/crates/dav-proto/resources/requests/propertyupdate-001.json +++ b/crates/dav-proto/resources/requests/propertyupdate-001.json @@ -382,5 +382,6 @@ "type": "ResourceType" } } - ] + ], + "set_first": true } \ No newline at end of file diff --git a/crates/dav-proto/resources/requests/propertyupdate-002.json b/crates/dav-proto/resources/requests/propertyupdate-002.json new file mode 100644 index 00000000..f9e28327 --- /dev/null +++ b/crates/dav-proto/resources/requests/propertyupdate-002.json @@ -0,0 +1,176 @@ +{ + "set": [ + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop0", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value0" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop1", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value1" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop2", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value2" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop3", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value3" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop4", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value4" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop5", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value5" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop6", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value6" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop7", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value7" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop8", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value8" + } + ] + } + }, + { + "property": { + "type": "DeadProperty", + "data": { + "name": "prop9", + "attrs": "xmlns=\"http://example.com/neon/litmus/\"" + } + }, + "value": { + "DeadProperty": [ + { + "type": "Text", + "data": "value9" + } + ] + } + } + ], + "remove": [], + "set_first": true +} \ No newline at end of file diff --git a/crates/dav-proto/resources/requests/propertyupdate-002.xml b/crates/dav-proto/resources/requests/propertyupdate-002.xml new file mode 100644 index 00000000..1c386888 --- /dev/null +++ b/crates/dav-proto/resources/requests/propertyupdate-002.xml @@ -0,0 +1,11 @@ +value0 +value1 +value2 +value3 +value4 +value5 +value6 +value7 +value8 +value9 + \ No newline at end of file diff --git a/crates/dav-proto/resources/requests/propfind-009.json b/crates/dav-proto/resources/requests/propfind-009.json new file mode 100644 index 00000000..e69de29b diff --git a/crates/dav-proto/resources/requests/propfind-009.xml b/crates/dav-proto/resources/requests/propfind-009.xml new file mode 100644 index 00000000..cd262d14 --- /dev/null +++ b/crates/dav-proto/resources/requests/propfind-009.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/crates/dav-proto/resources/requests/report-017.json b/crates/dav-proto/resources/requests/report-017.json index 44ae3312..d433d1ae 100644 --- a/crates/dav-proto/resources/requests/report-017.json +++ b/crates/dav-proto/resources/requests/report-017.json @@ -1,5 +1,5 @@ { - "type": "AdressbookMultiGet", + "type": "AddressbookMultiGet", "properties": { "type": "Prop", "data": [ diff --git a/crates/dav-proto/resources/requests/report-018.json b/crates/dav-proto/resources/requests/report-018.json index ab2b0c89..8a9cfd64 100644 --- a/crates/dav-proto/resources/requests/report-018.json +++ b/crates/dav-proto/resources/requests/report-018.json @@ -1,5 +1,5 @@ { - "type": "AdressbookMultiGet", + "type": "AddressbookMultiGet", "properties": { "type": "Prop", "data": [ diff --git a/crates/dav-proto/src/parser/property.rs b/crates/dav-proto/src/parser/property.rs index 15bb95f4..0f873f31 100644 --- a/crates/dav-proto/src/parser/property.rs +++ b/crates/dav-proto/src/parser/property.rs @@ -25,9 +25,10 @@ use crate::schema::{ use super::{tokenizer::Tokenizer, DavParser, RawElement, Token, XmlValueParser}; impl Tokenizer<'_> { - pub(crate) fn collect_properties(&mut self) -> crate::parser::Result> { - let mut elements = Vec::new(); - + pub(crate) fn collect_properties( + &mut self, + mut elements: Vec, + ) -> crate::parser::Result> { loop { match self.token()? { Token::ElementStart { @@ -287,9 +288,8 @@ impl Tokenizer<'_> { impl Tokenizer<'_> { pub(crate) fn collect_property_values( &mut self, - ) -> crate::parser::Result> { - let mut elements = Vec::new(); - + elements: &mut Vec, + ) -> crate::parser::Result<()> { loop { match self.token()? { Token::ElementStart { name, .. } => { @@ -377,7 +377,7 @@ impl Tokenizer<'_> { } } - Ok(elements) + Ok(()) } } diff --git a/crates/dav-proto/src/parser/tokenizer.rs b/crates/dav-proto/src/parser/tokenizer.rs index e7f2496c..c78aba41 100644 --- a/crates/dav-proto/src/parser/tokenizer.rs +++ b/crates/dav-proto/src/parser/tokenizer.rs @@ -72,6 +72,11 @@ impl<'x> Tokenizer<'x> { return Ok(Token::UnknownElement(RawElement(tag))); } } + ResolveResult::Unknown(p) => { + return Err(Error::Xml(quick_xml::Error::Namespace( + quick_xml::name::NamespaceError::UnknownPrefix(p), + ))) + } _ => { return Ok(Token::UnknownElement(RawElement(tag))); } diff --git a/crates/dav-proto/src/requests/acl.rs b/crates/dav-proto/src/requests/acl.rs index 2c9206cc..22778360 100644 --- a/crates/dav-proto/src/requests/acl.rs +++ b/crates/dav-proto/src/requests/acl.rs @@ -179,7 +179,7 @@ impl DavParser for Principal { ns: Namespace::Dav, element: Element::Property, } => { - let property = stream.collect_properties()?; + let property = stream.collect_properties(Vec::new())?; Principal::Property(List( property .into_iter() @@ -271,7 +271,7 @@ impl DavParser for AclPrincipalPropSet { }, .. } => { - acps.properties.extend(stream.collect_properties()?); + acps.properties = stream.collect_properties(acps.properties)?; } Token::ElementEnd => { break; @@ -306,8 +306,9 @@ impl DavParser for PrincipalMatch { }, .. } => { - pm.principal_properties = - PrincipalMatchProperties::Properties(stream.collect_properties()?); + pm.principal_properties = PrincipalMatchProperties::Properties( + stream.collect_properties(Vec::new())?, + ); } Token::ElementStart { name: @@ -328,7 +329,7 @@ impl DavParser for PrincipalMatch { }, .. } => { - pm.properties = stream.collect_properties()?; + pm.properties = stream.collect_properties(pm.properties)?; } Token::ElementEnd => { break; @@ -376,7 +377,7 @@ impl DavParser for PrincipalPropertySearch { }, .. } => { - pps.properties = stream.collect_properties()?; + pps.properties = stream.collect_properties(pps.properties)?; } Token::ElementStart { name: @@ -420,7 +421,7 @@ impl PropertySearch { }, .. } => { - property = stream.collect_properties()?.into_iter().next(); + property = stream.collect_properties(Vec::new())?.into_iter().next(); } Token::ElementStart { name: diff --git a/crates/dav-proto/src/requests/mkcol.rs b/crates/dav-proto/src/requests/mkcol.rs index cc1498f1..d329b206 100644 --- a/crates/dav-proto/src/requests/mkcol.rs +++ b/crates/dav-proto/src/requests/mkcol.rs @@ -40,9 +40,26 @@ impl DavParser for MkCol { other => return Err(other.into_unexpected()), }; - stream.expect_named_element(NamedElement::dav(Element::Set))?; - stream.expect_named_element(NamedElement::dav(Element::Prop))?; - mkcol.props = stream.collect_property_values()?; + loop { + match stream.token()? { + Token::ElementStart { + name: + NamedElement { + ns: Namespace::Dav, + element: Element::Set, + }, + .. + } => { + stream.expect_named_element(NamedElement::dav(Element::Prop))?; + stream.collect_property_values(&mut mkcol.props)?; + stream.expect_element_end()?; + } + Token::ElementEnd | Token::Eof => { + break; + } + token => return Err(token.into_unexpected()), + } + } Ok(mkcol) } diff --git a/crates/dav-proto/src/requests/mod.rs b/crates/dav-proto/src/requests/mod.rs index 7807a508..79531ff6 100644 --- a/crates/dav-proto/src/requests/mod.rs +++ b/crates/dav-proto/src/requests/mod.rs @@ -177,10 +177,10 @@ mod tests { let json_path = path.with_extension("json"); let json_output = match filename.split_once('-').unwrap().0 { - "propfind" => { - serde_json::to_string_pretty(&PropFind::parse(&mut tokenizer).unwrap()) - .unwrap() - } + "propfind" => match PropFind::parse(&mut tokenizer) { + Ok(propfind) => serde_json::to_string_pretty(&propfind).unwrap(), + Err(_) => String::new(), + }, "propertyupdate" => serde_json::to_string_pretty( &PropertyUpdate::parse(&mut tokenizer).unwrap(), ) diff --git a/crates/dav-proto/src/requests/propertyupdate.rs b/crates/dav-proto/src/requests/propertyupdate.rs index c7a5c0cf..80d0c582 100644 --- a/crates/dav-proto/src/requests/propertyupdate.rs +++ b/crates/dav-proto/src/requests/propertyupdate.rs @@ -15,6 +15,7 @@ impl DavParser for PropertyUpdate { let mut update = PropertyUpdate { set: Vec::with_capacity(4), remove: Vec::with_capacity(4), + set_first: true, }; loop { @@ -28,8 +29,9 @@ impl DavParser for PropertyUpdate { .. } => { stream.expect_named_element(NamedElement::dav(Element::Prop))?; - update.set = stream.collect_property_values()?; + stream.collect_property_values(&mut update.set)?; stream.expect_element_end()?; + update.set_first = update.remove.is_empty(); } Token::ElementStart { name: @@ -40,7 +42,7 @@ impl DavParser for PropertyUpdate { .. } => { stream.expect_named_element(NamedElement::dav(Element::Prop))?; - update.remove = stream.collect_properties()?; + update.remove = stream.collect_properties(update.remove)?; stream.expect_element_end()?; } Token::ElementEnd | Token::Eof => { diff --git a/crates/dav-proto/src/requests/propfind.rs b/crates/dav-proto/src/requests/propfind.rs index fde66dd2..c2c786e7 100644 --- a/crates/dav-proto/src/requests/propfind.rs +++ b/crates/dav-proto/src/requests/propfind.rs @@ -32,7 +32,7 @@ impl DavParser for PropFind { .. } ) { - stream.collect_properties().map(PropFind::AllProp) + stream.collect_properties(Vec::new()).map(PropFind::AllProp) } else { Ok(PropFind::AllProp(vec![])) } @@ -40,7 +40,7 @@ impl DavParser for PropFind { NamedElement { ns: Namespace::Dav, element: Element::Prop, - } => stream.collect_properties().map(PropFind::Prop), + } => stream.collect_properties(Vec::new()).map(PropFind::Prop), element => Err(element.into_unexpected()), } } else { diff --git a/crates/dav-proto/src/requests/report.rs b/crates/dav-proto/src/requests/report.rs index 47294d81..13f55c4b 100644 --- a/crates/dav-proto/src/requests/report.rs +++ b/crates/dav-proto/src/requests/report.rs @@ -104,7 +104,7 @@ impl DavParser for CalendarQuery { ns: Namespace::Dav, element: Element::Prop, } if depth == 1 => { - cq.properties = PropFind::Prop(stream.collect_properties()?); + cq.properties = PropFind::Prop(stream.collect_properties(Vec::new())?); } NamedElement { ns: Namespace::CalDav, @@ -269,7 +269,7 @@ impl DavParser for AddressbookQuery { ns: Namespace::Dav, element: Element::Prop, } if depth == 1 => { - aq.properties = PropFind::Prop(stream.collect_properties()?); + aq.properties = PropFind::Prop(stream.collect_properties(Vec::new())?); } NamedElement { ns: Namespace::CardDav, @@ -409,7 +409,7 @@ impl DavParser for MultiGet { ns: Namespace::Dav, element: Element::Prop, } => { - mg.properties = PropFind::Prop(stream.collect_properties()?); + mg.properties = PropFind::Prop(stream.collect_properties(Vec::new())?); } NamedElement { ns: Namespace::Dav, @@ -448,7 +448,7 @@ impl DavParser for SyncCollection { ns: Namespace::Dav, element: Element::Prop, } => { - sc.properties = PropFind::Prop(stream.collect_properties()?); + sc.properties = PropFind::Prop(stream.collect_properties(Vec::new())?); } NamedElement { ns: Namespace::Dav, diff --git a/crates/dav-proto/src/schema/request.rs b/crates/dav-proto/src/schema/request.rs index 1ddeb12f..ed12bf8c 100644 --- a/crates/dav-proto/src/schema/request.rs +++ b/crates/dav-proto/src/schema/request.rs @@ -29,6 +29,7 @@ pub enum PropFind { pub struct PropertyUpdate { pub set: Vec, pub remove: Vec, + pub set_first: bool, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/dav/src/common/lock.rs b/crates/dav/src/common/lock.rs index c2862ec9..e9c83a65 100644 --- a/crates/dav/src/common/lock.rs +++ b/crates/dav/src/common/lock.rs @@ -4,8 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use std::collections::HashMap; - use common::KV_LOCK_DAV; use common::{Server, auth::AccessToken}; use dav_proto::schema::property::{ActiveLock, LockScope, WebDavProperty}; @@ -18,6 +16,7 @@ use http_proto::HttpResponse; use hyper::StatusCode; use jmap_proto::types::collection::Collection; use jmap_proto::types::property::Property; +use std::collections::HashMap; use store::dispatch::lookup::KeyValue; use store::write::serialize::rkyv_deserialize; use store::write::{AlignedBytes, Archive, Archiver, now}; @@ -34,17 +33,52 @@ pub struct ResourceState<'x> { pub collection: Collection, pub document_id: Option, pub etag: Option, - pub lock_token: Option, + pub lock_tokens: Vec, pub sync_token: Option, pub path: &'x str, } +#[derive(Debug, Default, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] +pub(crate) struct LockData { + locks: HashMap, +} + +#[derive(Debug, Default, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] +#[repr(transparent)] +pub(crate) struct LockItems(Vec); + +#[derive(Debug, Default, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] +pub(crate) struct LockItem { + lock_id: u64, + owner: u32, + expires: u64, + depth_infinity: bool, + exclusive: bool, + owner_dav: Option, +} + +struct LockCache<'x> { + account_id: u32, + collection: Collection, + lock_archive: LockArchive<'x>, +} + +enum LockArchive<'x> { + Unarchived(&'x ArchivedLockData), + Archived(Archive), +} + +#[derive(Default)] +pub(crate) struct LockCaches<'x> { + caches: Vec>, +} + pub(crate) trait LockRequestHandler: Sync + Send { fn handle_lock_request( &self, access_token: &AccessToken, headers: RequestHeaders<'_>, - lock_info: Option, + lock_info: LockRequest, ) -> impl Future> + Send; fn validate_headers( @@ -57,12 +91,18 @@ pub(crate) trait LockRequestHandler: Sync + Send { ) -> impl Future> + Send; } +pub(crate) enum LockRequest { + Lock(LockInfo), + Unlock, + Refresh, +} + impl LockRequestHandler for Server { async fn handle_lock_request( &self, access_token: &AccessToken, headers: RequestHeaders<'_>, - lock_info: Option, + lock_info: LockRequest, ) -> crate::Result { let resource = self .validate_uri(access_token, headers.uri) @@ -84,6 +124,19 @@ impl LockRequestHandler for Server { ..Default::default() }]; + let is_lock_request = !matches!(lock_info, LockRequest::Unlock); + let if_lock_token = headers + .if_ + .iter() + .flat_map(|if_| if_.list.iter()) + .find_map(|cond| { + if let Condition::StateToken { token, .. } = cond { + Urn::parse(token).and_then(|u| u.try_unwrap_lock()) + } else { + None + } + }) + .unwrap_or_default(); let mut lock_data = if let Some(lock_data) = self .in_memory_store() .key_get::>(resource_hash.as_slice()) @@ -99,26 +152,66 @@ impl LockRequestHandler for Server { &headers, resources, LockCaches::new_shared(account_id, resource.collection, lock_data), - DavMethod::LOCK, + if is_lock_request { + DavMethod::LOCK + } else { + DavMethod::UNLOCK + }, ) .await?; - if lock_info.is_some() { - if let Some((lock_path, lock_item)) = lock_data.can_lock(resource_path) { - if !lock_item.is_lock_owner(access_token) { - return Err(DavErrorCondition::new( - StatusCode::LOCKED, - BaseCondition::LockTokenSubmitted(List(vec![ - headers.format_to_base_uri(lock_path).into(), - ])), - ) - .into()); + if let LockRequest::Lock(lock_info) = &lock_info { + let mut failed_locks = Vec::new(); + let is_exclusive = matches!(lock_info.lock_scope, LockScope::Exclusive); + let is_infinity = matches!(headers.depth, Depth::Infinity); + + for (lock_path, lock_item) in lock_data.find_locks(resource_path, true) { + if if_lock_token != lock_item.lock_id + && (lock_item.exclusive || is_exclusive) + && (lock_path.len() == resource_path.len() + || lock_item.depth_infinity && resource_path.len() > lock_path.len() + || is_infinity && lock_path.len() > resource_path.len()) + { + failed_locks.push(headers.format_to_base_uri(lock_path).into()); } } + + if !failed_locks.is_empty() { + return Err(DavErrorCondition::new( + StatusCode::LOCKED, + BaseCondition::LockTokenSubmitted(List(failed_locks)), + ) + .into()); + } + + // Validate lock_info + if lock_info + .owner + .as_ref() + .is_some_and(|o| o.size() > self.core.dav.dead_property_size.unwrap_or(512)) + { + return Err(DavError::Code(StatusCode::PAYLOAD_TOO_LARGE)); + } + + if self.core.dav.max_locks_per_user > 0 + && lock_data + .locks + .values() + .flat_map(|locks| { + locks + .0 + .iter() + .filter(|lock| lock.owner == access_token.primary_id) + }) + .count() + >= self.core.dav.max_locks_per_user + { + return Err(DavError::Code(StatusCode::TOO_MANY_REQUESTS)); + } } rkyv_deserialize(lock_data).caused_by(trc::location!())? - } else if lock_info.is_some() { + } else if is_lock_request { self.validate_headers( access_token, &headers, @@ -138,30 +231,44 @@ impl LockRequestHandler for Server { }; let now = now(); - let response = if let Some(lock_info) = lock_info { + let response = if is_lock_request { let timeout = if let Timeout::Second(seconds) = headers.timeout { std::cmp::min(seconds, self.core.dav.max_lock_timeout) } else { self.core.dav.max_lock_timeout }; + let expires = now + timeout; - let lock_item = LockItem { - owner: access_token.primary_id, - depth_infinity: matches!(headers.depth, Depth::Infinity), - owner_dav: lock_info.owner, - exclusive: matches!(lock_info.lock_scope, LockScope::Exclusive), - lock_id: store::rand::random(), - expires: now + timeout, + let lock_item = if if_lock_token > 0 { + if let Some(lock_item) = lock_data + .locks + .values_mut() + .flat_map(|locks| locks.0.iter_mut()) + .find(|lock| lock.lock_id == if_lock_token) + { + lock_item + } else { + return Err(DavError::Code(StatusCode::PRECONDITION_FAILED)); + } + } else { + let locks = lock_data + .locks + .entry(resource_path.to_string()) + .or_insert_with(Default::default); + locks.0.push(LockItem::default()); + locks.0.last_mut().unwrap() }; - if lock_item - .owner_dav - .as_ref() - .is_some_and(|o| o.size() > self.core.dav.dead_property_size.unwrap_or(512)) - { - return Err(DavError::Code(StatusCode::PAYLOAD_TOO_LARGE)); + + lock_item.expires = expires; + if let LockRequest::Lock(lock_info) = lock_info { + lock_item.lock_id = store::rand::random::() ^ expires; + lock_item.owner = access_token.primary_id; + lock_item.depth_infinity = matches!(headers.depth, Depth::Infinity); + lock_item.owner_dav = lock_info.owner; + lock_item.exclusive = matches!(lock_info.lock_scope, LockScope::Exclusive); } + let active_lock = lock_item.to_active_lock(headers.format_to_base_uri(resource_path)); - lock_data.locks.insert(resource_path.to_string(), lock_item); HttpResponse::new(StatusCode::CREATED) .with_lock_token(&active_lock.lock_token.as_ref().unwrap().0) @@ -173,25 +280,13 @@ impl LockRequestHandler for Server { .to_string(), ) } else { - let (lock_expires, lock_id) = headers + let lock_id = headers .lock_token .and_then(Urn::parse) .and_then(|urn| urn.try_unwrap_lock()) .ok_or(DavError::Code(StatusCode::BAD_REQUEST))?; - let mut found_path = None; - for (lock_path, lock_item) in lock_data.locks.iter() { - if lock_item.expires == lock_expires && lock_item.lock_id == lock_id { - if lock_item.is_lock_owner(access_token) { - found_path = Some(lock_path.to_string()); - break; - } else { - return Err(DavError::Code(StatusCode::FORBIDDEN)); - } - } - } - if let Some(found_path) = found_path { - lock_data.locks.remove(&found_path); + if lock_data.remove_lock(lock_id) { HttpResponse::new(StatusCode::NO_CONTENT) } else { return Err(DavErrorCondition::new( @@ -203,17 +298,8 @@ impl LockRequestHandler for Server { }; // Remove expired locks - let mut max_expire = 0; - lock_data.locks.retain(|_, lock| { - if lock.expires > now { - max_expire = std::cmp::max(max_expire, lock.expires); - true - } else { - false - } - }); - - if !lock_data.locks.is_empty() { + let max_expire = lock_data.remove_expired(); + if max_expire > 0 { self.in_memory_store() .key_set( KeyValue::new( @@ -275,27 +361,48 @@ impl LockRequestHandler for Server { let mut locks = locks_.to_unarchived().caused_by(trc::location!())?; // Validate locks for write operations - if !matches!(method, DavMethod::GET | DavMethod::HEAD) { - for resource in &resources { + let mut lock_response = Ok(()); + if !matches!( + method, + DavMethod::GET | DavMethod::HEAD | DavMethod::LOCK | DavMethod::UNLOCK + ) { + 'outer: for (pos, resource) in resources.iter().enumerate() { + if pos == 0 && matches!(method, DavMethod::COPY) { + continue; + } + if let Some(idx) = locks.find_cache_pos(self, resource).await? { - if let Some((lock_path, lock_item)) = locks.find_lock_by_pos(idx, resource)? { - if !lock_item.is_lock_owner(access_token) { - return Err(DavErrorCondition::new( - StatusCode::LOCKED, - BaseCondition::LockTokenSubmitted(List(vec![ - headers.format_to_base_uri(lock_path).into(), - ])), - ) - .into()); + let mut failed_locks = Vec::new(); + + for (lock_path, lock_item) in locks.find_locks_by_pos(idx, resource, true)? { + let lock_token = lock_item.urn().to_string(); + if headers.if_.iter().any(|if_| { + if_.resource + .is_none_or(|r| { + r.trim_end_matches('/').ends_with(lock_path)}) + && if_.list.iter().any(|cond| matches!(cond, Condition::StateToken { token, .. } if token == &lock_token)) + }) { + break 'outer; + } else { + failed_locks.push(headers.format_to_base_uri(lock_path).into()); } } + + if !failed_locks.is_empty() { + lock_response = Err(DavErrorCondition::new( + StatusCode::LOCKED, + BaseCondition::LockTokenSubmitted(List(failed_locks)), + ) + .into()); + break; + } } } } // There are no If headers, so we can return early if no_if_headers { - return Ok(()); + return lock_response; } let mut resource_not_found = ResourceState { @@ -344,7 +451,7 @@ impl LockRequestHandler for Server { // Fill missing data for resource if resource_state.collection != Collection::None && (resource_state.etag.is_none() - || resource_state.lock_token.is_none() + || resource_state.lock_tokens.is_empty() || resource_state.sync_token.is_none()) { let mut needs_lock_token = false; @@ -354,15 +461,10 @@ impl LockRequestHandler for Server { for cond in &if_.list { match cond { Condition::StateToken { token, .. } => { - match Urn::parse(token) - .ok_or(DavError::Code(StatusCode::BAD_REQUEST))? - { - Urn::Lock { .. } => { - needs_lock_token = true; - } - Urn::Sync { .. } => { - needs_sync_token = true; - } + if token.starts_with("urn:stalwart:davsync:") { + needs_sync_token = true; + } else { + needs_lock_token = true; } } Condition::ETag { .. } | Condition::Exists { .. } => { @@ -413,11 +515,14 @@ impl LockRequestHandler for Server { } // Fetch lock token - if needs_lock_token && resource_state.lock_token.is_none() { + if needs_lock_token && resource_state.lock_tokens.is_empty() { if let Some(idx) = locks.find_cache_pos(self, resource_state).await? { - if let Some((_, lock)) = locks.find_lock_by_pos(idx, resource_state)? { - resource_state.lock_token = Some(lock.urn().to_string()); - } + 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; } } @@ -428,29 +533,13 @@ impl LockRequestHandler for Server { .get_last_change_id(resource_state.account_id, resource_state.collection) .await .caused_by(trc::location!())?; - resource_state.sync_token = Some( - Urn::Sync { - id: change_id.unwrap_or_default(), - } - .to_string(), - ); + resource_state.sync_token = + Some(Urn::Sync(change_id.unwrap_or_default()).to_string()); } } for cond in &if_.list { match cond { - Condition::StateToken { is_not, token } - if token.starts_with("urn:stalwart:davlock:") => - { - if !((resource_state - .lock_token - .as_ref() - .is_some_and(|lock_token| lock_token == token)) - ^ is_not) - { - continue 'outer; - } - } Condition::StateToken { is_not, token } if token.starts_with("urn:stalwart:davsync:") => { @@ -463,6 +552,11 @@ impl LockRequestHandler for Server { continue 'outer; } } + Condition::StateToken { is_not, token } => { + if !((resource_state.lock_tokens.iter().any(|t| t == token)) ^ is_not) { + continue 'outer; + } + } Condition::ETag { is_not, tag } => { if !((resource_state.etag.as_ref().is_some_and(|etag| etag == tag)) ^ is_not) @@ -475,33 +569,70 @@ impl LockRequestHandler for Server { continue 'outer; } } - _ => { - return Err(DavError::Code(StatusCode::BAD_REQUEST)); - } } } - return Ok(()); + return lock_response; } Err(DavError::Code(StatusCode::PRECONDITION_FAILED)) } } -struct LockCache<'x> { - account_id: u32, - collection: Collection, - lock_archive: LockArchive<'x>, -} +/*impl LockItems { + pub fn insert_or_refresh_lock(&mut self, item: LockItem, href: String) -> ActiveLock { + if let Some(idx) = self.0.iter().position(|i| i.lock_id == item.lock_id) { + let update = &mut self.0[idx]; + update.expires = item.expires; + update.depth_infinity = item.depth_infinity; + update.owner_dav = item.owner_dav; + update.exclusive = item.exclusive; + update.to_active_lock(href) + } else { + let active_lock = item.to_active_lock(href); + self.0.push(item); + active_lock + } + } +}*/ -enum LockArchive<'x> { - Unarchived(&'x ArchivedLockData), - Archived(Archive), -} +impl LockData { + pub fn remove_lock(&mut self, lock_id: u64) -> bool { + for (lock_path, lock_items) in self.locks.iter_mut() { + for (idx, lock_item) in lock_items.0.iter().enumerate() { + if lock_item.lock_id == lock_id { + lock_items.0.swap_remove(idx); + if lock_items.0.is_empty() { + let lock_path = lock_path.clone(); + self.locks.remove(&lock_path); + } + return true; + } + } + } -#[derive(Default)] -pub(crate) struct LockCaches<'x> { - caches: Vec>, + false + } + + pub fn remove_expired(&mut self) -> u64 { + let mut max_expire = 0; + let now = now(); + + self.locks.retain(|_, locks| { + locks.0.retain(|lock| { + if lock.expires > now { + max_expire = std::cmp::max(max_expire, lock.expires); + true + } else { + false + } + }); + + !locks.0.is_empty() + }); + + max_expire + } } impl<'x> LockArchive<'x> { @@ -574,15 +705,16 @@ impl<'x> LockCaches<'x> { } } - fn find_lock_by_pos<'y>( + fn find_locks_by_pos( &'x self, pos: usize, - resource_state: &'y ResourceState<'_>, - ) -> trc::Result> { + resource_state: &'x ResourceState<'_>, + include_children: bool, + ) -> trc::Result> { self.caches[pos] .lock_archive .unarchive() - .map(|l| l.find_lock(resource_state.path)) + .map(|l| l.find_locks(resource_state.path, include_children)) } async fn insert_lock_data( @@ -609,21 +741,6 @@ impl<'x> LockCaches<'x> { } } -#[derive(Debug, Default, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] -pub(crate) struct LockData { - locks: HashMap, -} - -#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)] -pub(crate) struct LockItem { - lock_id: u64, - owner: u32, - expires: u64, - depth_infinity: bool, - exclusive: bool, - owner_dav: Option, -} - impl SerializedVersion for LockData { fn serialize_version() -> u8 { SERIALIZE_OBJ_02_V1 @@ -631,11 +748,6 @@ impl SerializedVersion for LockData { } impl LockItem { - #[inline] - pub fn is_lock_owner(&self, access_token: &AccessToken) -> bool { - self.owner == access_token.primary_id - } - pub fn to_active_lock(&self, href: String) -> ActiveLock { ActiveLock::new( href, @@ -656,60 +768,60 @@ impl LockItem { } pub fn urn(&self) -> Urn { - Urn::Lock { - expires: self.expires, - id: self.lock_id, - } + Urn::Lock(self.lock_id) } } impl ArchivedLockData { - pub fn find_lock<'x, 'y>( + pub fn find_locks<'x: 'y, 'y>( &'x self, resource: &'y str, - ) -> Option<(&'y str, &'x ArchivedLockItem)> { + include_children: bool, + ) -> Vec<(&'y str, &'x ArchivedLockItem)> { let now = now(); let mut resource_part = resource; + let mut found_locks = Vec::new(); + loop { - if let Some(lock) = self.locks.get(resource_part).filter(|lock| { - lock.expires > now && (resource == resource_part || lock.depth_infinity) - }) { - return Some((resource_part, lock)); - } else if let Some((resource_part_, _)) = resource_part.rsplit_once('/') { + if let Some(locks) = self.locks.get(resource_part) { + found_locks.extend( + locks + .0 + .iter() + .filter(|lock| { + lock.expires > now && (resource == resource_part || lock.depth_infinity) + }) + .map(|lock| (resource_part, lock)), + ); + } + + if let Some((resource_part_, _)) = resource_part.rsplit_once('/') { resource_part = resource_part_; } else { - return None; + break; } } - } - pub fn can_lock<'x>(&'x self, resource: &'x str) -> Option<(&'x str, &'x ArchivedLockItem)> { - if let Some(lock) = self.find_lock(resource) { - Some(lock) - } else { - let now = now(); - self.locks.iter().find_map(|(resource_part, lock)| { - if lock.depth_infinity - && lock.expires > now - && resource_part - .strip_prefix(resource) - .is_some_and(|v| v.starts_with('/')) - { - Some((resource_part.as_str(), lock)) - } else { - None + if include_children { + let prefix = format!("{}/", resource); + for (resource_part, locks) in self.locks.iter() { + if resource_part.starts_with(&prefix) { + found_locks.extend( + locks + .0 + .iter() + .filter(|lock| lock.expires > now) + .map(|lock| (resource_part.as_str(), lock)), + ); } - }) + } } + + found_locks } } impl ArchivedLockItem { - #[inline] - pub fn is_lock_owner(&self, access_token: &AccessToken) -> bool { - self.owner == access_token.primary_id - } - pub fn to_active_lock(&self, href: String) -> ActiveLock { ActiveLock::new( href, @@ -730,10 +842,7 @@ impl ArchivedLockItem { } pub fn urn(&self) -> Urn { - Urn::Lock { - expires: self.expires.into(), - id: self.lock_id.into(), - } + Urn::Lock(self.lock_id.into()) } } diff --git a/crates/dav/src/common/uri.rs b/crates/dav/src/common/uri.rs index 9c3246f8..d2dc79be 100644 --- a/crates/dav/src/common/uri.rs +++ b/crates/dav/src/common/uri.rs @@ -23,8 +23,8 @@ pub(crate) struct UriResource { } pub(crate) enum Urn { - Lock { expires: u64, id: u64 }, - Sync { id: u64 }, + Lock(u64), + Sync(u64), } pub(crate) type UnresolvedUri<'x> = UriResource, Option<&'x str>>; @@ -134,25 +134,22 @@ impl Urn { let inbox = input.strip_prefix("urn:stalwart:")?; let (kind, id) = inbox.split_once(':')?; match kind { - "davlock" => u128::from_str_radix(id, 16).ok().map(|id| Urn::Lock { - expires: (id >> 64) as u64, - id: id as u64, - }), - "davsync" => u64::from_str_radix(id, 16).ok().map(|id| Urn::Sync { id }), + "davlock" => u64::from_str_radix(id, 16).ok().map(Urn::Lock), + "davsync" => u64::from_str_radix(id, 16).ok().map(Urn::Sync), _ => None, } } - pub fn try_unwrap_lock(&self) -> Option<(u64, u64)> { + pub fn try_unwrap_lock(&self) -> Option { match self { - Urn::Lock { expires, id } => Some((*expires, *id)), + Urn::Lock(id) => Some(*id), _ => None, } } pub fn try_unwrap_sync(&self) -> Option { match self { - Urn::Sync { id } => Some(*id), + Urn::Sync(id) => Some(*id), _ => None, } } @@ -161,12 +158,8 @@ impl Urn { impl Display for Urn { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Urn::Lock { expires, id } => write!( - f, - "urn:stalwart:davlock:{:x}", - (u128::from(*expires) << 64) | u128::from(*id) - ), - Urn::Sync { id } => write!(f, "urn:stalwart:davsync:{:x}", id), + Urn::Lock(id) => write!(f, "urn:stalwart:davlock:{id:x}",), + Urn::Sync(id) => write!(f, "urn:stalwart:davsync:{id:x}"), } } } diff --git a/crates/dav/src/file/copy_move.rs b/crates/dav/src/file/copy_move.rs index 7a008439..9b09989b 100644 --- a/crates/dav/src/file/copy_move.rs +++ b/crates/dav/src/file/copy_move.rs @@ -31,7 +31,7 @@ use crate::{ file::{DavFileResource, FileItemId, insert_file_node, update_file_node}, }; -use super::{FromFileItem, delete_file_node}; +use super::{FromFileItem, delete::delete_files, delete_file_node}; pub(crate) trait FileCopyMoveRequestHandler: Sync + Send { fn handle_file_copy_move_request( @@ -119,32 +119,36 @@ impl FileCopyMoveRequestHandler for Server { }; // Map file item - let mut destination_resource_name = ""; - let mut destination = if let Some(resource) = destination.resource { - destination_resource_name = resource; - - // Check if the resource exists - if let Some(destination) = to_files + let destination_resource_name = destination + .resource + .ok_or(DavError::Code(StatusCode::BAD_GATEWAY))?; + let mut delete_destination = None; + // Check if the resource exists + let mut destination = if let Some((destination, new_name)) = + to_files.map_parent::(destination_resource_name) + { + if let Some(mut existing_destination) = to_files .files - .by_name(resource) + .by_name(destination_resource_name) .map(Destination::from_file_item) { - destination - } else if let Some((destination, new_name)) = - to_files.map_parent::(resource) - { - let mut destination = destination.unwrap_or_default(); - destination.new_name = Some(new_name.into_owned()); - destination - } else { - return Err(DavError::Code(StatusCode::BAD_GATEWAY)); + if !headers.overwrite_fail { + existing_destination.account_id = to_account_id; + delete_destination = Some(existing_destination); + } else { + return Ok(HttpResponse::new(StatusCode::PRECONDITION_FAILED)); + } } + + let mut destination = destination.unwrap_or_default(); + destination.new_name = Some(new_name.to_string()); + destination } else { - Destination::default() + return Err(DavError::Code(StatusCode::CONFLICT)); }; destination.account_id = to_account_id; - if from_account_id == destination.account_id { + if from_account_id == destination.account_id && delete_destination.is_none() { if Some(from_resource.resource.document_id) == destination.document_id { // Move or copy to the same location return Ok(HttpResponse::new(StatusCode::BAD_GATEWAY)); @@ -176,6 +180,19 @@ impl FileCopyMoveRequestHandler for Server { child_acl.insert(Acl::Modify); } + if let Some(delete_destination) = &delete_destination { + self.validate_child_or_parent_acl( + access_token, + to_account_id, + Collection::FileNode, + delete_destination.document_id.unwrap(), + delete_destination.parent_id, + Acl::Delete, + Acl::RemoveItems, + ) + .await?; + } + self.validate_child_or_parent_acl( access_token, to_account_id, @@ -211,7 +228,11 @@ impl FileCopyMoveRequestHandler for Server { }, ], Default::default(), - DavMethod::MOVE, + if is_move { + DavMethod::MOVE + } else { + DavMethod::COPY + }, ) .await?; @@ -232,12 +253,28 @@ impl FileCopyMoveRequestHandler for Server { .await?; } - match ( - from_resource.resource.is_container, - destination.is_container, - is_move, - ) { - (true, true, true) => { + // Delete collection + let is_overwrite = delete_destination + .as_ref() + .is_some_and(|d| d.is_container || from_resource.resource.is_container); + if is_overwrite { + delete_destination = None; + // Find ids to delete + let mut ids = to_files + .subtree(destination_resource_name) + .collect::>(); + if !ids.is_empty() { + ids.sort_unstable_by(|a, b| b.hierarchy_sequence.cmp(&a.hierarchy_sequence)); + let mut sorted_ids = Vec::with_capacity(ids.len()); + sorted_ids.extend(ids.into_iter().map(|a| a.document_id)); + delete_files(self, access_token, destination.account_id, sorted_ids) + .await + .caused_by(trc::location!())?; + } + } + + match (from_resource.resource.is_container, is_move) { + (true, true) => { move_container( self, access_token, @@ -249,7 +286,7 @@ impl FileCopyMoveRequestHandler for Server { ) .await } - (true, true, false) => { + (true, false) => { copy_container( self, access_token, @@ -261,19 +298,34 @@ impl FileCopyMoveRequestHandler for Server { ) .await } - (false, false, true) => { - overwrite_and_delete_item(self, access_token, from_resource, destination).await + (false, true) => { + if let Some(delete_destination) = delete_destination { + overwrite_and_delete_item(self, access_token, from_resource, delete_destination) + .await + } else { + move_item(self, access_token, from_resource, destination).await + } } - (false, false, false) => { - overwrite_item(self, access_token, from_resource, destination).await + + (false, false) => { + if let Some(delete_destination) = delete_destination { + overwrite_item(self, access_token, from_resource, delete_destination).await + } else { + copy_item(self, access_token, from_resource, destination).await + } } - (false, true, true) => move_item(self, access_token, from_resource, destination).await, - (false, true, false) => copy_item(self, access_token, from_resource, destination).await, - _ => Err(DavError::Code(StatusCode::BAD_GATEWAY)), } + .map(|r| { + if is_overwrite && r.status() == StatusCode::CREATED { + r.with_status_code(StatusCode::NO_CONTENT) + } else { + r + } + }) } } +#[derive(Debug)] pub(crate) struct Destination { pub account_id: u32, pub new_name: Option, @@ -583,7 +635,7 @@ async fn overwrite_and_delete_item( .await .caused_by(trc::location!())?; - Ok(HttpResponse::new(StatusCode::CREATED).with_etag_opt(etag)) + Ok(HttpResponse::new(StatusCode::NO_CONTENT).with_etag_opt(etag)) } // Overwrites the contents of one file with another @@ -644,7 +696,7 @@ async fn overwrite_item( .await .caused_by(trc::location!())?; - Ok(HttpResponse::new(StatusCode::CREATED).with_etag_opt(etag)) + Ok(HttpResponse::new(StatusCode::NO_CONTENT).with_etag_opt(etag)) } // Moves an item under an existing container diff --git a/crates/dav/src/file/delete.rs b/crates/dav/src/file/delete.rs index c3cca3df..7f4c5d5d 100644 --- a/crates/dav/src/file/delete.rs +++ b/crates/dav/src/file/delete.rs @@ -103,51 +103,67 @@ impl FileDeleteRequestHandler for Server { ) .await?; - // Process deletions - let mut changes = ChangeLogBuilder::new(); - for document_id in sorted_ids { - if let Some(node) = self - .get_property::>( - account_id, - Collection::FileNode, - document_id, - Property::Value, - ) - .await? - { - // Delete record - let mut batch = BatchBuilder::new(); - batch - .with_account_id(account_id) - .with_collection(Collection::FileNode) - .delete_document(document_id) - .custom( - ObjectIndexBuilder::<_, ()>::new() - .with_tenant_id(access_token) - .with_current( - node.to_unarchived::() - .caused_by(trc::location!())?, - ), - ) - .caused_by(trc::location!())?; - self.store() - .write(batch) - .await - .caused_by(trc::location!())?; - changes.log_delete(Collection::FileNode, document_id); - } - } + let c = println!("DELETE files: {:?}", sorted_ids); - // Write changes - if !changes.is_empty() { - let change_id = self - .commit_changes(account_id, changes) - .await - .caused_by(trc::location!())?; - self.broadcast_single_state_change(account_id, change_id, DataType::FileNode) - .await; - } + delete_files(self, access_token, account_id, sorted_ids).await?; Ok(HttpResponse::new(StatusCode::NO_CONTENT)) } } + +pub(crate) async fn delete_files( + server: &Server, + access_token: &AccessToken, + account_id: u32, + ids: Vec, +) -> trc::Result<()> { + // Process deletions + let mut changes = ChangeLogBuilder::new(); + + for document_id in ids { + if let Some(node) = server + .get_property::>( + account_id, + Collection::FileNode, + document_id, + Property::Value, + ) + .await? + { + // Delete record + let mut batch = BatchBuilder::new(); + batch + .with_account_id(account_id) + .with_collection(Collection::FileNode) + .delete_document(document_id) + .custom( + ObjectIndexBuilder::<_, ()>::new() + .with_tenant_id(access_token) + .with_current( + node.to_unarchived::() + .caused_by(trc::location!())?, + ), + ) + .caused_by(trc::location!())?; + server + .store() + .write(batch) + .await + .caused_by(trc::location!())?; + changes.log_delete(Collection::FileNode, document_id); + } + } + + // Write changes + if !changes.is_empty() { + let change_id = server + .commit_changes(account_id, changes) + .await + .caused_by(trc::location!())?; + server + .broadcast_single_state_change(account_id, change_id, DataType::FileNode) + .await; + } + + Ok(()) +} diff --git a/crates/dav/src/file/mkcol.rs b/crates/dav/src/file/mkcol.rs index c256774c..98e1a692 100644 --- a/crates/dav/src/file/mkcol.rs +++ b/crates/dav/src/file/mkcol.rs @@ -88,7 +88,7 @@ impl FileMkColRequestHandler for Server { let now = now(); let mut node = FileNode { parent_id, - name: resource.resource.1.into_owned(), + name: resource.resource.1.to_string(), display_name: None, file: None, created: now as i64, diff --git a/crates/dav/src/file/mod.rs b/crates/dav/src/file/mod.rs index 2b685d2e..18d2dbf3 100644 --- a/crates/dav/src/file/mod.rs +++ b/crates/dav/src/file/mod.rs @@ -4,8 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use std::borrow::Cow; - use common::{FileItem, Files, Server, auth::AccessToken, storage::index::ObjectIndexBuilder}; use groupware::file::FileNode; use hyper::StatusCode; @@ -49,16 +47,13 @@ pub(crate) trait DavFileResource { resource: &OwnedUri<'_>, ) -> crate::Result>; - fn map_parent<'x, T: FromFileItem>( - &self, - resource: &'x str, - ) -> Option<(Option, Cow<'x, str>)>; + fn map_parent<'x, T: FromFileItem>(&self, resource: &'x str) -> Option<(Option, &'x str)>; #[allow(clippy::type_complexity)] fn map_parent_resource<'x, T: FromFileItem>( &self, resource: &OwnedUri<'x>, - ) -> crate::Result, Cow<'x, str>)>>; + ) -> crate::Result, &'x str)>>; } impl DavFileResource for Files { @@ -77,10 +72,7 @@ impl DavFileResource for Files { .ok_or(DavError::Code(StatusCode::NOT_FOUND)) } - fn map_parent<'x, T: FromFileItem>( - &self, - resource: &'x str, - ) -> Option<(Option, Cow<'x, str>)> { + fn map_parent<'x, T: FromFileItem>(&self, resource: &'x str) -> Option<(Option, &'x str)> { let (parent, child) = if let Some((parent, child)) = resource.rsplit_once('/') { ( Some(self.files.by_name(parent).map(T::from_file_item)?), @@ -90,18 +82,13 @@ impl DavFileResource for Files { (None, resource) }; - Some(( - parent, - percent_encoding::percent_decode_str(child) - .decode_utf8() - .unwrap_or_else(|_| child.into()), - )) + Some((parent, child)) } fn map_parent_resource<'x, T: FromFileItem>( &self, resource: &OwnedUri<'x>, - ) -> crate::Result, Cow<'x, str>)>> { + ) -> crate::Result, &'x str)>> { if let Some(r) = resource.resource { if self.files.by_name(r).is_none() { self.map_parent(r) @@ -110,7 +97,7 @@ impl DavFileResource for Files { account_id: resource.account_id, resource: r, }) - .ok_or(DavError::Code(StatusCode::NOT_FOUND)) + .ok_or(DavError::Code(StatusCode::CONFLICT)) } else { Err(DavError::Code(StatusCode::METHOD_NOT_ALLOWED)) } @@ -226,7 +213,7 @@ pub(crate) async fn delete_file_node( .with_change_id(change_id) .with_account_id(account_id) .with_collection(Collection::FileNode) - .create_document() + .delete_document(document_id) .log(Changes::delete([document_id])) .custom( ObjectIndexBuilder::<_, ()>::new() diff --git a/crates/dav/src/file/propfind.rs b/crates/dav/src/file/propfind.rs index 8efb5fd5..5c4b92bb 100644 --- a/crates/dav/src/file/propfind.rs +++ b/crates/dav/src/file/propfind.rs @@ -89,12 +89,7 @@ impl HandleFilePropFindRequest for Server { self.core.dav.max_changes, ); if changelog.to_change_id != 0 { - sync_token = Some( - Urn::Sync { - id: changelog.to_change_id, - } - .to_string(), - ); + sync_token = Some(Urn::Sync(changelog.to_change_id).to_string()); } let mut changes = RoaringBitmap::from_iter(changelog.changes.iter().map(|change| change.id() as u32)); @@ -199,7 +194,7 @@ impl HandleFilePropFindRequest for Server { .await .caused_by(trc::location!())? .unwrap_or_default(); - sync_token = Some(Urn::Sync { id }.to_string()) + sync_token = Some(Urn::Sync(id).to_string()) } // Add sync token @@ -359,12 +354,16 @@ impl HandleFilePropFindRequest for Server { } } WebDavProperty::LockDiscovery => { - if let Some((path, lock)) = - locks.as_ref().and_then(|locks| locks.find_lock(&item.name)) - { + if let Some(locks) = locks.as_ref() { fields.push(DavPropertyValue::new( property.clone(), - vec![lock.to_active_lock(query.format_to_base_uri(path))], + locks + .find_locks(&item.name, false) + .iter() + .map(|(path, lock)| { + lock.to_active_lock(query.format_to_base_uri(path)) + }) + .collect::>(), )); } else { fields.push(DavPropertyValue::empty(property.clone())); diff --git a/crates/dav/src/file/proppatch.rs b/crates/dav/src/file/proppatch.rs index 32a66ef8..8c01e607 100644 --- a/crates/dav/src/file/proppatch.rs +++ b/crates/dav/src/file/proppatch.rs @@ -54,7 +54,7 @@ impl FilePropPatchRequestHandler for Server { &self, access_token: &AccessToken, headers: RequestHeaders<'_>, - request: PropertyUpdate, + mut request: PropertyUpdate, ) -> crate::Result { // Validate URI let resource_ = self @@ -117,41 +117,22 @@ impl FilePropPatchRequestHandler for Server { // Remove properties let mut items = Vec::with_capacity(request.remove.len() + request.set.len()); - for property in request.remove { - match property { - DavProperty::WebDav(WebDavProperty::DisplayName) => { - new_node.display_name = None; - items.push( - PropStat::new(DavProperty::WebDav(WebDavProperty::DisplayName)) - .with_status(StatusCode::OK), - ); - } - DavProperty::WebDav(WebDavProperty::GetContentType) if new_node.file.is_some() => { - new_node.file.as_mut().unwrap().media_type = None; - items.push( - PropStat::new(DavProperty::WebDav(WebDavProperty::GetContentType)) - .with_status(StatusCode::OK), - ); - } - DavProperty::DeadProperty(dead) => { - new_node.dead_properties.remove_element(&dead); - items.push( - PropStat::new(DavProperty::DeadProperty(dead)).with_status(StatusCode::OK), - ); - } - property => { - items.push( - PropStat::new(property) - .with_status(StatusCode::CONFLICT) - .with_response_description("Property cannot be modified"), - ); - } - } + if !request.set_first && !request.remove.is_empty() { + remove_file_properties( + &mut new_node, + std::mem::take(&mut request.remove), + &mut items, + ); } // Set properties let is_success = self.apply_file_properties(&mut new_node, true, request.set, &mut items); + // Remove properties + if is_success && !request.remove.is_empty() { + remove_file_properties(&mut new_node, request.remove, &mut items); + } + let etag = if new_node != node.inner { update_file_node( self, @@ -283,3 +264,41 @@ impl FilePropPatchRequestHandler for Server { !has_errors } } + +fn remove_file_properties( + node: &mut FileNode, + properties: Vec, + items: &mut Vec, +) { + for property in properties { + match property { + DavProperty::WebDav(WebDavProperty::DisplayName) => { + node.display_name = None; + items.push( + PropStat::new(DavProperty::WebDav(WebDavProperty::DisplayName)) + .with_status(StatusCode::OK), + ); + } + DavProperty::WebDav(WebDavProperty::GetContentType) if node.file.is_some() => { + node.file.as_mut().unwrap().media_type = None; + items.push( + PropStat::new(DavProperty::WebDav(WebDavProperty::GetContentType)) + .with_status(StatusCode::OK), + ); + } + DavProperty::DeadProperty(dead) => { + node.dead_properties.remove_element(&dead); + items.push( + PropStat::new(DavProperty::DeadProperty(dead)).with_status(StatusCode::OK), + ); + } + property => { + items.push( + PropStat::new(property) + .with_status(StatusCode::CONFLICT) + .with_response_description("Property cannot be modified"), + ); + } + } + } +} diff --git a/crates/dav/src/file/update.rs b/crates/dav/src/file/update.rs index f482dd16..927d1bc4 100644 --- a/crates/dav/src/file/update.rs +++ b/crates/dav/src/file/update.rs @@ -63,7 +63,7 @@ impl FileUpdateRequestHandler for Server { .caused_by(trc::location!())?; let resource_name = resource .resource - .ok_or(DavError::Code(StatusCode::NOT_FOUND))?; + .ok_or(DavError::Code(StatusCode::CONFLICT))?; if let Some(document_id) = files.files.by_name(resource_name).map(|r| r.document_id) { // Update @@ -92,15 +92,6 @@ impl FileUpdateRequestHandler for Server { ) .await?; - // Verify that the node is a file - if let Some(file) = node.file.as_ref() { - if BlobHash::generate(&bytes).as_slice() == file.blob_hash.0.as_slice() { - return Ok(HttpResponse::new(StatusCode::OK)); - } - } else { - return Err(DavError::Code(StatusCode::METHOD_NOT_ALLOWED)); - } - // Validate headers match self .validate_headers( @@ -148,6 +139,15 @@ impl FileUpdateRequestHandler for Server { Err(e) => return Err(e), } + // Verify that the node is a file + if let Some(file) = node.file.as_ref() { + if BlobHash::generate(&bytes).as_slice() == file.blob_hash.0.as_slice() { + return Ok(HttpResponse::new(StatusCode::OK)); + } + } else { + return Err(DavError::Code(StatusCode::METHOD_NOT_ALLOWED)); + } + // Validate quota let extra_bytes = (bytes.len() as u64) .saturating_sub(u32::from(node.file.as_ref().unwrap().size) as u64); @@ -207,7 +207,7 @@ impl FileUpdateRequestHandler for Server { let orig_resource_name = resource_name; let (parent_id, resource_name) = files .map_parent(resource_name) - .ok_or(DavError::Code(StatusCode::NOT_FOUND))?; + .ok_or(DavError::Code(StatusCode::CONFLICT))?; // Validate ACL let parent_id = self @@ -277,7 +277,7 @@ impl FileUpdateRequestHandler for Server { let now = now(); let node = FileNode { parent_id, - name: resource_name.into_owned(), + name: resource_name.to_string(), display_name: None, file: Some(FileProperties { blob_hash, diff --git a/crates/dav/src/principal/propfind.rs b/crates/dav/src/principal/propfind.rs index fe6dfa5c..f7d49621 100644 --- a/crates/dav/src/principal/propfind.rs +++ b/crates/dav/src/principal/propfind.rs @@ -168,7 +168,7 @@ impl PrincipalPropFind for Server { .unwrap_or_default(); fields.push(DavPropertyValue::new( property.clone(), - Urn::Sync { id }.to_string(), + Urn::Sync(id).to_string(), )); } WebDavProperty::AlternateURISet if is_principal => { diff --git a/crates/dav/src/request.rs b/crates/dav/src/request.rs index 9d0cc1f1..c9423db5 100644 --- a/crates/dav/src/request.rs +++ b/crates/dav/src/request.rs @@ -23,7 +23,10 @@ use hyper::{StatusCode, header}; use crate::{ DavError, DavMethod, DavResource, common::{ - DavQuery, lock::LockRequestHandler, propfind::PropFindRequestHandler, uri::DavUriResource, + DavQuery, + lock::{LockRequest, LockRequestHandler}, + propfind::PropFindRequestHandler, + uri::DavUriResource, }, file::{ acl::FileAclRequestHandler, copy_move::FileCopyMoveRequestHandler, @@ -124,19 +127,41 @@ impl DavRequestDispatcher for Server { DavResource::Cal => todo!(), DavResource::Principal => todo!(), DavResource::File => { - self.handle_file_get_request(&access_token, headers, true) + #[cfg(debug_assertions)] + { + // Deal with Litmus bug + self.handle_file_get_request( + &access_token, + headers, + !request.headers().contains_key("x-litmus"), + ) .await + } + + #[cfg(not(debug_assertions))] + { + self.handle_file_get_request(&access_token, headers, true) + .await + } } }, - DavMethod::DELETE => match resource { - DavResource::Card => todo!(), - DavResource::Cal => todo!(), - DavResource::Principal => todo!(), - DavResource::File => { - self.handle_file_delete_request(&access_token, headers) - .await + DavMethod::DELETE => { + // Include any fragments in the URI + if let Some(p) = request.uri().path_and_query() { + // TODO: Access to the fragment part is pending, see https://github.com/hyperium/http/issues/127 + headers.uri = p.as_str(); } - }, + + match resource { + DavResource::Card => todo!(), + DavResource::Cal => todo!(), + DavResource::Principal => todo!(), + DavResource::File => { + self.handle_file_delete_request(&access_token, headers) + .await + } + } + } DavMethod::PUT | DavMethod::POST => match resource { DavResource::Card => todo!(), DavResource::Cal => todo!(), @@ -181,12 +206,19 @@ impl DavRequestDispatcher for Server { self.handle_lock_request( &access_token, headers, - LockInfo::parse(&mut Tokenizer::new(&body))?.into(), + if !body.is_empty() { + LockRequest::Lock(LockInfo::parse(&mut Tokenizer::new(&body))?) + } else { + LockRequest::Refresh + }, ) .await } }, - DavMethod::UNLOCK => self.handle_lock_request(&access_token, headers, None).await, + DavMethod::UNLOCK => { + self.handle_lock_request(&access_token, headers, LockRequest::Unlock) + .await + } DavMethod::ACL => match resource { DavResource::Card => todo!(), DavResource::Cal => todo!(), @@ -278,7 +310,9 @@ impl DavRequestHandler for Server { Vec::new() }; - match self + let std_body = std::str::from_utf8(&body).unwrap_or("[binary]").to_string(); + + let result = match self .dispatch_dav_request(&request, access_token, resource, method, body) .await { @@ -304,7 +338,17 @@ impl DavRequestHandler for Server { _ => HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR), } } - Err(DavError::Parse(err)) => HttpResponse::new(StatusCode::BAD_REQUEST), + Err(DavError::Parse(err)) => { + if request + .headers() + .get(header::CONTENT_TYPE) + .is_some_and(|h| h.to_str().unwrap_or_default().contains("/xml")) + { + HttpResponse::new(StatusCode::BAD_REQUEST) + } else { + HttpResponse::new(StatusCode::UNSUPPORTED_MEDIA_TYPE) + } + } Err(DavError::Condition(condition)) => HttpResponse::new(condition.code) .with_xml_body( ErrorResponse::new(condition.condition) @@ -313,7 +357,24 @@ impl DavRequestHandler for Server { ) .with_no_cache(), Err(DavError::Code(code)) => HttpResponse::new(code), - } + }; + + let c = println!( + "------------------------------------------\n{:?} {} -> {:?}\nHeaders: {:?}\nBody: {}\nResponse headers: {:?}\nResponse: {}", + method, + request.uri().path(), + result.status(), + request.headers(), + std_body, + result.headers().unwrap(), + match &result.body() { + http_proto::HttpResponseBody::Text(t) => t, + http_proto::HttpResponseBody::Empty => "[empty]", + _ => "[binary]", + } + ); + + result } } diff --git a/crates/directory/src/backend/imap/client.rs b/crates/directory/src/backend/imap/client.rs index f3738489..c9def10f 100644 --- a/crates/directory/src/backend/imap/client.rs +++ b/crates/directory/src/backend/imap/client.rs @@ -6,9 +6,9 @@ use mail_send::Credentials; use smtp_proto::{ - request::{parser::Rfc5321Parser, AUTH}, + AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2, IntoString, + request::{AUTH, parser::Rfc5321Parser}, response::generate::BitToString, - IntoString, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2, }; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; diff --git a/crates/directory/src/backend/imap/config.rs b/crates/directory/src/backend/imap/config.rs index 96827ea6..2ad1a704 100644 --- a/crates/directory/src/backend/imap/config.rs +++ b/crates/directory/src/backend/imap/config.rs @@ -7,7 +7,7 @@ use std::time::Duration; use mail_send::smtp::tls::build_tls_connector; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::core::config::build_pool; diff --git a/crates/directory/src/backend/imap/lookup.rs b/crates/directory/src/backend/imap/lookup.rs index b6e33499..b57cbacd 100644 --- a/crates/directory/src/backend/imap/lookup.rs +++ b/crates/directory/src/backend/imap/lookup.rs @@ -7,7 +7,7 @@ use mail_send::Credentials; use smtp_proto::{AUTH_CRAM_MD5, AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2}; -use crate::{backend::RcptType, IntoError, Principal, QueryBy}; +use crate::{IntoError, Principal, QueryBy, backend::RcptType}; use super::{ImapDirectory, ImapError}; diff --git a/crates/directory/src/backend/imap/tls.rs b/crates/directory/src/backend/imap/tls.rs index f2d0b427..27d34cdc 100644 --- a/crates/directory/src/backend/imap/tls.rs +++ b/crates/directory/src/backend/imap/tls.rs @@ -9,7 +9,7 @@ use std::time::Duration; use rustls_pki_types::ServerName; use smtp_proto::IntoString; use tokio::net::{TcpStream, ToSocketAddrs}; -use tokio_rustls::{client::TlsStream, TlsConnector}; +use tokio_rustls::{TlsConnector, client::TlsStream}; use super::{ImapClient, ImapError}; diff --git a/crates/directory/src/backend/internal/lookup.rs b/crates/directory/src/backend/internal/lookup.rs index 783b1ffd..90324737 100644 --- a/crates/directory/src/backend/internal/lookup.rs +++ b/crates/directory/src/backend/internal/lookup.rs @@ -6,14 +6,14 @@ use mail_send::Credentials; use store::{ - write::{DirectoryClass, ValueClass}, Deserialize, IterateParams, Store, ValueKey, + write::{DirectoryClass, ValueClass}, }; use trc::AddContext; -use crate::{backend::RcptType, Principal, QueryBy, Type}; +use crate::{Principal, QueryBy, Type, backend::RcptType}; -use super::{manage::ManageDirectory, PrincipalField, PrincipalInfo}; +use super::{PrincipalField, PrincipalInfo, manage::ManageDirectory}; #[allow(async_fn_in_trait)] pub trait DirectoryStore: Sync + Send { diff --git a/crates/directory/src/backend/ldap/config.rs b/crates/directory/src/backend/ldap/config.rs index 20985189..c6317610 100644 --- a/crates/directory/src/backend/ldap/config.rs +++ b/crates/directory/src/backend/ldap/config.rs @@ -8,7 +8,7 @@ use std::time::Duration; use ldap3::LdapConnSettings; use store::Store; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::core::config::build_pool; diff --git a/crates/directory/src/backend/ldap/lookup.rs b/crates/directory/src/backend/ldap/lookup.rs index d54eff88..6803f8ad 100644 --- a/crates/directory/src/backend/ldap/lookup.rs +++ b/crates/directory/src/backend/ldap/lookup.rs @@ -10,15 +10,15 @@ use store::xxhash_rust; use trc::AddContext; use crate::{ + IntoError, Principal, QueryBy, ROLE_ADMIN, ROLE_USER, Type, backend::{ + RcptType, internal::{ + PrincipalField, lookup::DirectoryStore, manage::{self, ManageDirectory, UpdatePrincipal}, - PrincipalField, }, - RcptType, }, - IntoError, Principal, QueryBy, Type, ROLE_ADMIN, ROLE_USER, }; use super::{LdapDirectory, LdapMappings}; diff --git a/crates/directory/src/backend/ldap/mod.rs b/crates/directory/src/backend/ldap/mod.rs index f085d6cf..1dee4817 100644 --- a/crates/directory/src/backend/ldap/mod.rs +++ b/crates/directory/src/backend/ldap/mod.rs @@ -5,7 +5,7 @@ */ use deadpool::managed::Pool; -use ldap3::{ldap_escape, LdapConnSettings}; +use ldap3::{LdapConnSettings, ldap_escape}; use store::Store; pub mod config; diff --git a/crates/directory/src/backend/ldap/pool.rs b/crates/directory/src/backend/ldap/pool.rs index f5491fd2..8aa97db0 100644 --- a/crates/directory/src/backend/ldap/pool.rs +++ b/crates/directory/src/backend/ldap/pool.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use deadpool::managed; -use ldap3::{exop::WhoAmI, Ldap, LdapConnAsync, LdapError}; +use ldap3::{Ldap, LdapConnAsync, LdapError, exop::WhoAmI}; use super::LdapConnectionManager; diff --git a/crates/directory/src/backend/memory/config.rs b/crates/directory/src/backend/memory/config.rs index 5198ad1c..db3f0c68 100644 --- a/crates/directory/src/backend/memory/config.rs +++ b/crates/directory/src/backend/memory/config.rs @@ -5,11 +5,11 @@ */ use store::Store; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::{ - backend::internal::{manage::ManageDirectory, PrincipalField}, - Principal, Type, ROLE_ADMIN, ROLE_USER, + Principal, ROLE_ADMIN, ROLE_USER, Type, + backend::internal::{PrincipalField, manage::ManageDirectory}, }; use super::{EmailType, MemoryDirectory}; diff --git a/crates/directory/src/backend/memory/lookup.rs b/crates/directory/src/backend/memory/lookup.rs index 3474069a..554d956e 100644 --- a/crates/directory/src/backend/memory/lookup.rs +++ b/crates/directory/src/backend/memory/lookup.rs @@ -7,8 +7,8 @@ use mail_send::Credentials; use crate::{ - backend::{internal::PrincipalField, RcptType}, Principal, QueryBy, + backend::{RcptType, internal::PrincipalField}, }; use super::{EmailType, MemoryDirectory}; diff --git a/crates/directory/src/backend/oidc/config.rs b/crates/directory/src/backend/oidc/config.rs index 583e6205..f1a9bb21 100644 --- a/crates/directory/src/backend/oidc/config.rs +++ b/crates/directory/src/backend/oidc/config.rs @@ -6,9 +6,9 @@ use std::time::Duration; -use base64::{engine::general_purpose, Engine}; +use base64::{Engine, engine::general_purpose}; use store::Store; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use super::{Authentication, EndpointType, OpenIdConfig, OpenIdDirectory}; diff --git a/crates/directory/src/backend/oidc/lookup.rs b/crates/directory/src/backend/oidc/lookup.rs index 49253dd3..42282712 100644 --- a/crates/directory/src/backend/oidc/lookup.rs +++ b/crates/directory/src/backend/oidc/lookup.rs @@ -6,20 +6,20 @@ use ahash::HashMap; use mail_send::Credentials; -use reqwest::{header::AUTHORIZATION, StatusCode}; +use reqwest::{StatusCode, header::AUTHORIZATION}; use trc::{AddContext, AuthEvent}; use crate::{ + Principal, QueryBy, ROLE_USER, Type, backend::{ + RcptType, internal::{ + PrincipalField, lookup::DirectoryStore, manage::{self, ManageDirectory, UpdatePrincipal}, - PrincipalField, }, oidc::{Authentication, EndpointType}, - RcptType, }, - Principal, QueryBy, Type, ROLE_USER, }; use super::{OpenIdConfig, OpenIdDirectory}; diff --git a/crates/directory/src/backend/smtp/config.rs b/crates/directory/src/backend/smtp/config.rs index cdb75575..0b212646 100644 --- a/crates/directory/src/backend/smtp/config.rs +++ b/crates/directory/src/backend/smtp/config.rs @@ -6,8 +6,8 @@ use std::time::Duration; -use mail_send::{smtp::tls::build_tls_connector, SmtpClientBuilder}; -use utils::config::{utils::AsKey, Config}; +use mail_send::{SmtpClientBuilder, smtp::tls::build_tls_connector}; +use utils::config::{Config, utils::AsKey}; use crate::core::config::build_pool; diff --git a/crates/directory/src/backend/smtp/lookup.rs b/crates/directory/src/backend/smtp/lookup.rs index 8bdef979..996a540a 100644 --- a/crates/directory/src/backend/smtp/lookup.rs +++ b/crates/directory/src/backend/smtp/lookup.rs @@ -4,10 +4,10 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use mail_send::{smtp::AssertReply, Credentials}; +use mail_send::{Credentials, smtp::AssertReply}; use smtp_proto::Severity; -use crate::{backend::RcptType, IntoError, Principal, QueryBy}; +use crate::{IntoError, Principal, QueryBy, backend::RcptType}; use super::{SmtpClient, SmtpDirectory}; diff --git a/crates/directory/src/backend/smtp/pool.rs b/crates/directory/src/backend/smtp/pool.rs index 45281e03..1630f9e0 100644 --- a/crates/directory/src/backend/smtp/pool.rs +++ b/crates/directory/src/backend/smtp/pool.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use deadpool::managed; -use mail_send::{smtp::AssertReply, Error}; +use mail_send::{Error, smtp::AssertReply}; use super::{SmtpClient, SmtpConnectionManager}; diff --git a/crates/directory/src/backend/sql/config.rs b/crates/directory/src/backend/sql/config.rs index d1cdbb17..b146f66c 100644 --- a/crates/directory/src/backend/sql/config.rs +++ b/crates/directory/src/backend/sql/config.rs @@ -5,7 +5,7 @@ */ use store::{Store, Stores}; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use super::{SqlDirectory, SqlMappings}; diff --git a/crates/directory/src/core/cache.rs b/crates/directory/src/core/cache.rs index aef1c859..dfb06c7b 100644 --- a/crates/directory/src/core/cache.rs +++ b/crates/directory/src/core/cache.rs @@ -8,7 +8,7 @@ use std::time::Duration; use utils::{ cache::CacheWithTtl, - config::{utils::AsKey, Config}, + config::{Config, utils::AsKey}, }; use crate::backend::RcptType; diff --git a/crates/directory/src/core/config.rs b/crates/directory/src/core/config.rs index dfb7bf9b..2498f54d 100644 --- a/crates/directory/src/core/config.rs +++ b/crates/directory/src/core/config.rs @@ -5,8 +5,8 @@ */ use deadpool::{ - managed::{Manager, Pool}, Runtime, + managed::{Manager, Pool}, }; use std::{sync::Arc, time::Duration}; use store::{Store, Stores}; @@ -15,11 +15,11 @@ use utils::config::Config; use ahash::AHashMap; use crate::{ + Directories, Directory, DirectoryInner, backend::{ imap::ImapDirectory, ldap::LdapDirectory, memory::MemoryDirectory, oidc::OpenIdDirectory, smtp::SmtpDirectory, sql::SqlDirectory, }, - Directories, Directory, DirectoryInner, }; use super::cache::CachedDirectory; diff --git a/crates/directory/src/core/dispatch.rs b/crates/directory/src/core/dispatch.rs index a99e54fe..60bc81dc 100644 --- a/crates/directory/src/core/dispatch.rs +++ b/crates/directory/src/core/dispatch.rs @@ -7,8 +7,8 @@ use trc::AddContext; use crate::{ - backend::{internal::lookup::DirectoryStore, RcptType}, Directory, DirectoryInner, Principal, QueryBy, + backend::{RcptType, internal::lookup::DirectoryStore}, }; impl Directory { diff --git a/crates/directory/src/core/secret.rs b/crates/directory/src/core/secret.rs index ed92772d..4b4f216c 100644 --- a/crates/directory/src/core/secret.rs +++ b/crates/directory/src/core/secret.rs @@ -18,9 +18,9 @@ use sha2::Sha512; use tokio::sync::oneshot; use totp_rs::TOTP; +use crate::Principal; use crate::backend::internal::PrincipalField; use crate::backend::internal::SpecialSecrets; -use crate::Principal; impl Principal { pub async fn verify_secret(&self, mut code: &str) -> trc::Result { diff --git a/crates/email/src/identity/mod.rs b/crates/email/src/identity/mod.rs index 31dbb73e..fc1279ca 100644 --- a/crates/email/src/identity/mod.rs +++ b/crates/email/src/identity/mod.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use store::{SerializedVersion, SERIALIZE_OBJ_03_V1}; +use store::{SERIALIZE_OBJ_03_V1, SerializedVersion}; #[derive( rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, Debug, Default, Clone, PartialEq, Eq, diff --git a/crates/email/src/mailbox/mod.rs b/crates/email/src/mailbox/mod.rs index d0e92af6..24decdd1 100644 --- a/crates/email/src/mailbox/mod.rs +++ b/crates/email/src/mailbox/mod.rs @@ -6,7 +6,7 @@ use common::config::jmap::settings::SpecialUse; use jmap_proto::types::value::AclGrant; -use store::{SerializedVersion, SERIALIZE_OBJ_04_V1}; +use store::{SERIALIZE_OBJ_04_V1, SerializedVersion}; pub mod destroy; pub mod index; diff --git a/crates/email/src/message/crypto.rs b/crates/email/src/message/crypto.rs index 54aef58e..c1792bf7 100644 --- a/crates/email/src/message/crypto.rs +++ b/crates/email/src/message/crypto.rs @@ -26,7 +26,7 @@ use rasn_cms::{ }; use rsa::{Pkcs1v15Encrypt, RsaPublicKey, pkcs1::DecodeRsaPublicKey}; use sequoia_openpgp as openpgp; -use store::{write::Archive, Deserialize, SerializedVersion, SERIALIZE_OBJ_05_V1}; +use store::{Deserialize, SERIALIZE_OBJ_05_V1, SerializedVersion, write::Archive}; const P: openpgp::policy::StandardPolicy<'static> = openpgp::policy::StandardPolicy::new(); diff --git a/crates/email/src/message/metadata.rs b/crates/email/src/message/metadata.rs index b2af3f8f..6b1282f0 100644 --- a/crates/email/src/message/metadata.rs +++ b/crates/email/src/message/metadata.rs @@ -20,7 +20,7 @@ use rkyv::{ string::ArchivedString, vec::ArchivedVec, }; -use store::{SerializedVersion, SERIALIZE_OBJ_06_V1, SERIALIZE_OBJ_07_V1}; +use store::{SERIALIZE_OBJ_06_V1, SERIALIZE_OBJ_07_V1, SerializedVersion}; use utils::BlobHash; use crate::mailbox::{ArchivedUidMailbox, UidMailbox}; diff --git a/crates/email/src/push/mod.rs b/crates/email/src/push/mod.rs index 32b9d49f..add1187e 100644 --- a/crates/email/src/push/mod.rs +++ b/crates/email/src/push/mod.rs @@ -5,7 +5,7 @@ */ use jmap_proto::types::type_state::DataType; -use store::{SerializedVersion, SERIALIZE_OBJ_08_V1}; +use store::{SERIALIZE_OBJ_08_V1, SerializedVersion}; use utils::map::bitmap::Bitmap; #[derive( diff --git a/crates/email/src/sieve/mod.rs b/crates/email/src/sieve/mod.rs index d6a32d70..95b6e1c2 100644 --- a/crates/email/src/sieve/mod.rs +++ b/crates/email/src/sieve/mod.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use common::KV_SIEVE_ID; use sieve::Sieve; -use store::{blake3, SerializedVersion, SERIALIZE_OBJ_09_V1}; +use store::{SERIALIZE_OBJ_09_V1, SerializedVersion, blake3}; use utils::BlobHash; pub mod activate; diff --git a/crates/email/src/submission/mod.rs b/crates/email/src/submission/mod.rs index 61b8d28a..04e73530 100644 --- a/crates/email/src/submission/mod.rs +++ b/crates/email/src/submission/mod.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use store::{SerializedVersion, SERIALIZE_OBJ_10_V1}; +use store::{SERIALIZE_OBJ_10_V1, SerializedVersion}; use utils::map::vec_map::VecMap; pub mod index; diff --git a/crates/groupware/src/calendar/mod.rs b/crates/groupware/src/calendar/mod.rs index 25bdcac3..1a66def0 100644 --- a/crates/groupware/src/calendar/mod.rs +++ b/crates/groupware/src/calendar/mod.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - use calcard::icalendar::ICalendar; +use calcard::icalendar::ICalendar; use jmap_proto::types::{acl::Acl, value::AclGrant}; use utils::map::vec_map::VecMap; diff --git a/crates/groupware/src/file/hierarchy.rs b/crates/groupware/src/file/hierarchy.rs index e6dbb13c..f344c7f6 100644 --- a/crates/groupware/src/file/hierarchy.rs +++ b/crates/groupware/src/file/hierarchy.rs @@ -8,7 +8,6 @@ use std::sync::Arc; use common::{FileItem, Files, Server}; use jmap_proto::types::collection::Collection; -use percent_encoding::NON_ALPHANUMERIC; use trc::AddContext; use utils::bimap::IdBimap; @@ -35,12 +34,30 @@ impl FileHierarchy for Server { .get(&account_id) .filter(|x| x.modseq == change_id) { + let c = println!( + "Hierarchy: {:?}", + files + .files + .iter() + .map(|f| f.name.clone()) + .collect::>() + ); Ok(files) } else { let mut files = build_file_hierarchy(self, account_id).await?; files.modseq = change_id; let files = Arc::new(files); self.inner.cache.files.insert(account_id, files.clone()); + + let c = println!( + "Hierarchy: {:?}", + files + .files + .iter() + .map(|f| f.name.clone()) + .collect::>() + ); + Ok(files) } } @@ -50,10 +67,10 @@ async fn build_file_hierarchy(server: &Server, account_id: u32) -> trc::Result(account_id, Collection::FileNode) .await - .caused_by(trc::location!())? - .format(|f| { - f.name = percent_encoding::utf8_percent_encode(&f.name, NON_ALPHANUMERIC).to_string(); - }); + .caused_by(trc::location!())?; + /*.format(|f| { + f.name = percent_encoding::utf8_percent_encode(&f.name, NON_ALPHANUMERIC).to_string(); + });*/ let mut files = Files { files: IdBimap::with_capacity(list.len()), size: std::mem::size_of::() as u64, diff --git a/crates/groupware/src/file/index.rs b/crates/groupware/src/file/index.rs index 3d73e1d1..d0498cf4 100644 --- a/crates/groupware/src/file/index.rs +++ b/crates/groupware/src/file/index.rs @@ -23,7 +23,11 @@ impl IndexableObject for FileNode { values.extend([ IndexValue::Text { field: Property::Name.into(), - value: self.name.to_lowercase().into(), + value: percent_encoding::percent_decode_str(&self.name) + .decode_utf8() + .unwrap_or_else(|_| self.name.as_str().into()) + .to_lowercase() + .into(), }, IndexValue::U32 { field: Property::ParentId.into(), diff --git a/crates/groupware/src/file/mod.rs b/crates/groupware/src/file/mod.rs index aa35dbe5..5fba656d 100644 --- a/crates/groupware/src/file/mod.rs +++ b/crates/groupware/src/file/mod.rs @@ -9,7 +9,7 @@ pub mod index; use dav_proto::schema::request::DeadProperty; use jmap_proto::types::value::AclGrant; -use store::{SerializedVersion, SERIALIZE_OBJ_11_V1}; +use store::{SERIALIZE_OBJ_11_V1, SerializedVersion}; use utils::BlobHash; #[derive( diff --git a/crates/groupware/src/lib.rs b/crates/groupware/src/lib.rs index 80eaacad..c78849e0 100644 --- a/crates/groupware/src/lib.rs +++ b/crates/groupware/src/lib.rs @@ -4,6 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - pub mod calendar; +pub mod calendar; pub mod contact; pub mod file; diff --git a/crates/http-proto/src/response.rs b/crates/http-proto/src/response.rs index 15b75120..dae7acd7 100644 --- a/crates/http-proto/src/response.rs +++ b/crates/http-proto/src/response.rs @@ -36,6 +36,12 @@ impl HttpResponse { self } + pub fn with_status_code(mut self, status: StatusCode) -> Self { + self.status = status; + self.builder = self.builder.status(status); + self + } + pub fn with_content_length(mut self, content_length: usize) -> Self { self.builder = self.builder.header(header::CONTENT_LENGTH, content_length); self @@ -199,6 +205,10 @@ impl HttpResponse { pub fn status(&self) -> StatusCode { self.status } + + pub fn headers(&self) -> Option<&hyper::HeaderMap> { + self.builder.headers_ref() + } } impl ToHttpResponse for JsonResponse { diff --git a/crates/http/src/lib.rs b/crates/http/src/lib.rs index 6ebce6fc..0bf224ac 100644 --- a/crates/http/src/lib.rs +++ b/crates/http/src/lib.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - pub mod auth; +pub mod auth; pub mod autoconfig; pub mod form; pub mod management; diff --git a/crates/http/src/management/log.rs b/crates/http/src/management/log.rs index 4da11f1c..5fb15c74 100644 --- a/crates/http/src/management/log.rs +++ b/crates/http/src/management/log.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - use std::{ +use std::{ fs::{self, File}, io, path::Path, diff --git a/crates/http/src/management/mod.rs b/crates/http/src/management/mod.rs index ccac3b46..e54d851b 100644 --- a/crates/http/src/management/mod.rs +++ b/crates/http/src/management/mod.rs @@ -28,7 +28,7 @@ use dkim::DkimManagement; use dns::DnsManagement; #[cfg(feature = "enterprise")] use enterprise::telemetry::TelemetryApi; -use hyper::Method; +use hyper::{Method, StatusCode, header}; use jmap::api::{ToJmapHttpResponse, ToRequestError}; use log::LogManagement; use mail_parser::DateTime; @@ -272,7 +272,11 @@ impl ToManageHttpResponse for &trc::Error { } } .into_http_response(), - + trc::EventType::Auth(trc::AuthEvent::Failed) => { + HttpResponse::new(StatusCode::UNAUTHORIZED) + .with_header(header::WWW_AUTHENTICATE, "Bearer realm=\"Stalwart Server\"") + .with_header(header::WWW_AUTHENTICATE, "Basic realm=\"Stalwart Server\"") + } _ => self.to_request_error().into_http_response(), } } diff --git a/crates/imap-proto/src/parser/acl.rs b/crates/imap-proto/src/parser/acl.rs index 83102f80..de4c24bf 100644 --- a/crates/imap-proto/src/parser/acl.rs +++ b/crates/imap-proto/src/parser/acl.rs @@ -5,13 +5,13 @@ */ use crate::{ - protocol::{ - acl::{self, ModRights, ModRightsOp, Rights}, - ProtocolVersion, - }, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ + ProtocolVersion, + acl::{self, ModRights, ModRightsOp, Rights}, + }, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; use super::PushUnique; @@ -129,8 +129,8 @@ mod tests { use crate::{ protocol::{ - acl::{self, ModRights, ModRightsOp, Rights}, ProtocolVersion, + acl::{self, ModRights, ModRightsOp, Rights}, }, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/append.rs b/crates/imap-proto/src/parser/append.rs index 665fe17a..5b2aeb2d 100644 --- a/crates/imap-proto/src/parser/append.rs +++ b/crates/imap-proto/src/parser/append.rs @@ -5,13 +5,13 @@ */ use crate::{ - protocol::{ - append::{self, Message}, - Flag, ProtocolVersion, - }, - receiver::{bad, Request, Token}, - utf7::utf7_maybe_decode, Command, + protocol::{ + Flag, ProtocolVersion, + append::{self, Message}, + }, + receiver::{Request, Token, bad}, + utf7::utf7_maybe_decode, }; use super::parse_datetime; @@ -63,7 +63,7 @@ impl Request { return Err(bad( self.tag.to_string(), "Invalid opening parenthesis found.", - )) + )); } }; } @@ -72,7 +72,7 @@ impl Request { return Err(bad( self.tag.to_string(), "Invalid closing parenthesis found.", - )) + )); } State::Flags => { state = State::None; @@ -147,8 +147,8 @@ mod tests { use crate::{ protocol::{ - append::{self, Message}, Flag, ProtocolVersion, + append::{self, Message}, }, receiver::{Error, Receiver}, }; diff --git a/crates/imap-proto/src/parser/authenticate.rs b/crates/imap-proto/src/parser/authenticate.rs index 5e111126..870a6126 100644 --- a/crates/imap-proto/src/parser/authenticate.rs +++ b/crates/imap-proto/src/parser/authenticate.rs @@ -5,9 +5,9 @@ */ use crate::{ - protocol::authenticate::{self, Mechanism}, - receiver::{bad, Request}, Command, + protocol::authenticate::{self, Mechanism}, + receiver::{Request, bad}, }; impl Request { diff --git a/crates/imap-proto/src/parser/copy_move.rs b/crates/imap-proto/src/parser/copy_move.rs index 892ac707..63dc6208 100644 --- a/crates/imap-proto/src/parser/copy_move.rs +++ b/crates/imap-proto/src/parser/copy_move.rs @@ -5,10 +5,10 @@ */ use crate::{ - protocol::{copy_move, ProtocolVersion}, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ProtocolVersion, copy_move}, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; use super::parse_sequence_set; @@ -45,7 +45,7 @@ impl Request { #[cfg(test)] mod tests { use crate::{ - protocol::{copy_move, ProtocolVersion, Sequence}, + protocol::{ProtocolVersion, Sequence, copy_move}, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/delete.rs b/crates/imap-proto/src/parser/delete.rs index 06019428..e9669d2c 100644 --- a/crates/imap-proto/src/parser/delete.rs +++ b/crates/imap-proto/src/parser/delete.rs @@ -5,10 +5,10 @@ */ use crate::{ - protocol::{delete, ProtocolVersion}, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ProtocolVersion, delete}, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; impl Request { @@ -35,7 +35,7 @@ impl Request { #[cfg(test)] mod tests { use crate::{ - protocol::{delete, ProtocolVersion}, + protocol::{ProtocolVersion, delete}, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/enable.rs b/crates/imap-proto/src/parser/enable.rs index 72c6ece9..124bc6e2 100644 --- a/crates/imap-proto/src/parser/enable.rs +++ b/crates/imap-proto/src/parser/enable.rs @@ -5,9 +5,9 @@ */ use crate::{ - protocol::{capability::Capability, enable}, - receiver::{bad, Request}, Command, + protocol::{capability::Capability, enable}, + receiver::{Request, bad}, }; impl Request { diff --git a/crates/imap-proto/src/parser/login.rs b/crates/imap-proto/src/parser/login.rs index c702c5b2..04ccc99c 100644 --- a/crates/imap-proto/src/parser/login.rs +++ b/crates/imap-proto/src/parser/login.rs @@ -5,9 +5,9 @@ */ use crate::{ - protocol::login, - receiver::{bad, Request}, Command, + protocol::login, + receiver::{Request, bad}, }; impl Request { diff --git a/crates/imap-proto/src/parser/lsub.rs b/crates/imap-proto/src/parser/lsub.rs index d0342a88..ebc566ce 100644 --- a/crates/imap-proto/src/parser/lsub.rs +++ b/crates/imap-proto/src/parser/lsub.rs @@ -5,13 +5,13 @@ */ use crate::{ - protocol::{ - list::{self, SelectionOption}, - ProtocolVersion, - }, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ + ProtocolVersion, + list::{self, SelectionOption}, + }, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; impl Request { diff --git a/crates/imap-proto/src/parser/quota.rs b/crates/imap-proto/src/parser/quota.rs index 8bd50884..a469fcd5 100644 --- a/crates/imap-proto/src/parser/quota.rs +++ b/crates/imap-proto/src/parser/quota.rs @@ -5,10 +5,10 @@ */ use crate::{ - protocol::{quota, ProtocolVersion}, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ProtocolVersion, quota}, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; impl Request { @@ -52,7 +52,7 @@ impl Request { #[cfg(test)] mod tests { use crate::{ - protocol::{quota, ProtocolVersion}, + protocol::{ProtocolVersion, quota}, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/rename.rs b/crates/imap-proto/src/parser/rename.rs index bcd0c030..67eb5eb6 100644 --- a/crates/imap-proto/src/parser/rename.rs +++ b/crates/imap-proto/src/parser/rename.rs @@ -5,10 +5,10 @@ */ use crate::{ - protocol::{rename, ProtocolVersion}, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ProtocolVersion, rename}, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; impl Request { @@ -46,7 +46,7 @@ impl Request { #[cfg(test)] mod tests { use crate::{ - protocol::{rename, ProtocolVersion}, + protocol::{ProtocolVersion, rename}, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/store.rs b/crates/imap-proto/src/parser/store.rs index b07dfc42..6afc6fd2 100644 --- a/crates/imap-proto/src/parser/store.rs +++ b/crates/imap-proto/src/parser/store.rs @@ -5,12 +5,12 @@ */ use crate::{ - protocol::{ - store::{self, Operation}, - Flag, - }, - receiver::{bad, Request, Token}, Command, + protocol::{ + Flag, + store::{self, Operation}, + }, + receiver::{Request, Token, bad}, }; use super::{parse_number, parse_sequence_set}; @@ -133,8 +133,8 @@ mod tests { use crate::{ protocol::{ - store::{self, Operation}, Flag, Sequence, + store::{self, Operation}, }, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/subscribe.rs b/crates/imap-proto/src/parser/subscribe.rs index 54466d65..fb0a7d83 100644 --- a/crates/imap-proto/src/parser/subscribe.rs +++ b/crates/imap-proto/src/parser/subscribe.rs @@ -5,10 +5,10 @@ */ use crate::{ - protocol::{subscribe, ProtocolVersion}, - receiver::{bad, Request}, - utf7::utf7_maybe_decode, Command, + protocol::{ProtocolVersion, subscribe}, + receiver::{Request, bad}, + utf7::utf7_maybe_decode, }; impl Request { @@ -35,7 +35,7 @@ impl Request { #[cfg(test)] mod tests { use crate::{ - protocol::{subscribe, ProtocolVersion}, + protocol::{ProtocolVersion, subscribe}, receiver::Receiver, }; diff --git a/crates/imap-proto/src/parser/thread.rs b/crates/imap-proto/src/parser/thread.rs index 8325c397..25140a81 100644 --- a/crates/imap-proto/src/parser/thread.rs +++ b/crates/imap-proto/src/parser/thread.rs @@ -7,9 +7,9 @@ use mail_parser::decoders::charsets::map::charset_decoder; use crate::{ - protocol::thread::{self, Algorithm}, - receiver::{bad, Request}, Command, + protocol::thread::{self, Algorithm}, + receiver::{Request, bad}, }; use super::search::parse_filters; diff --git a/crates/imap-proto/src/protocol/enable.rs b/crates/imap-proto/src/protocol/enable.rs index b6f79fc1..eec6b1b0 100644 --- a/crates/imap-proto/src/protocol/enable.rs +++ b/crates/imap-proto/src/protocol/enable.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{capability::Capability, ImapResponse}; +use super::{ImapResponse, capability::Capability}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Arguments { diff --git a/crates/imap-proto/src/protocol/fetch.rs b/crates/imap-proto/src/protocol/fetch.rs index 22a74e72..09d6a687 100644 --- a/crates/imap-proto/src/protocol/fetch.rs +++ b/crates/imap-proto/src/protocol/fetch.rs @@ -9,8 +9,8 @@ use std::borrow::Cow; use mail_parser::DateTime; use super::{ - literal_string, quoted_or_literal_string, quoted_or_literal_string_or_nil, - quoted_rfc2822_or_nil, quoted_timestamp, Flag, ImapResponse, Sequence, + Flag, ImapResponse, Sequence, literal_string, quoted_or_literal_string, + quoted_or_literal_string_or_nil, quoted_rfc2822_or_nil, quoted_timestamp, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/imap-proto/src/protocol/namespace.rs b/crates/imap-proto/src/protocol/namespace.rs index b0502412..25d76bfb 100644 --- a/crates/imap-proto/src/protocol/namespace.rs +++ b/crates/imap-proto/src/protocol/namespace.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{quoted_string, ImapResponse}; +use super::{ImapResponse, quoted_string}; pub struct Response { pub shared_prefix: Option, diff --git a/crates/imap-proto/src/protocol/quota.rs b/crates/imap-proto/src/protocol/quota.rs index 33021b86..c0fceec6 100644 --- a/crates/imap-proto/src/protocol/quota.rs +++ b/crates/imap-proto/src/protocol/quota.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{capability::QuotaResourceName, quoted_string, ImapResponse}; +use super::{ImapResponse, capability::QuotaResourceName, quoted_string}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Arguments { @@ -79,7 +79,7 @@ impl ImapResponse for Response { #[cfg(test)] mod tests { - use crate::protocol::{capability::QuotaResourceName, ImapResponse}; + use crate::protocol::{ImapResponse, capability::QuotaResourceName}; use super::{QuotaItem, QuotaResource}; diff --git a/crates/imap-proto/src/protocol/search.rs b/crates/imap-proto/src/protocol/search.rs index 2a2b0026..7658c4f5 100644 --- a/crates/imap-proto/src/protocol/search.rs +++ b/crates/imap-proto/src/protocol/search.rs @@ -6,7 +6,7 @@ use store::fts::{FilterItem, FilterType}; -use super::{quoted_string, serialize_sequence, Flag, Sequence}; +use super::{Flag, Sequence, quoted_string, serialize_sequence}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Arguments { diff --git a/crates/imap-proto/src/protocol/store.rs b/crates/imap-proto/src/protocol/store.rs index e4977056..eddc4458 100644 --- a/crates/imap-proto/src/protocol/store.rs +++ b/crates/imap-proto/src/protocol/store.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{fetch::FetchItem, Flag, ImapResponse, Sequence}; +use super::{Flag, ImapResponse, Sequence, fetch::FetchItem}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Arguments { diff --git a/crates/imap-proto/src/protocol/thread.rs b/crates/imap-proto/src/protocol/thread.rs index d7822858..33c36197 100644 --- a/crates/imap-proto/src/protocol/thread.rs +++ b/crates/imap-proto/src/protocol/thread.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use super::{search::Filter, ImapResponse}; +use super::{ImapResponse, search::Filter}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Arguments { diff --git a/crates/imap/src/core/client.rs b/crates/imap/src/core/client.rs index 10f4ad86..4f1ff5cf 100644 --- a/crates/imap/src/core/client.rs +++ b/crates/imap/src/core/client.rs @@ -7,12 +7,12 @@ use std::{iter::Peekable, sync::Arc, vec::IntoIter}; use common::{ - listener::{SessionResult, SessionStream}, KV_RATE_LIMIT_IMAP, + listener::{SessionResult, SessionStream}, }; use imap_proto::{ - receiver::{self, Request}, Command, ResponseType, StatusResponse, + receiver::{self, Request}, }; use trc::SecurityEvent; @@ -72,9 +72,10 @@ impl Session { } Ok(false) => {} Err(err) => { - trc::error!(err - .span_id(self.session_id) - .details("Failed to check for fail2ban")); + trc::error!( + err.span_id(self.session_id) + .details("Failed to check for fail2ban") + ); } } } diff --git a/crates/imap/src/core/mod.rs b/crates/imap/src/core/mod.rs index d20fe879..54163390 100644 --- a/crates/imap/src/core/mod.rs +++ b/crates/imap/src/core/mod.rs @@ -6,15 +6,15 @@ use std::{ net::IpAddr, - sync::{atomic::AtomicU32, Arc}, + sync::{Arc, atomic::AtomicU32}, }; use common::{ - auth::AccessToken, - listener::{limiter::InFlight, ServerInstance, SessionStream}, Account, ImapId, Inner, MailboxId, MailboxState, Server, + auth::AccessToken, + listener::{ServerInstance, SessionStream, limiter::InFlight}, }; -use imap_proto::{protocol::ProtocolVersion, receiver::Receiver, Command}; +use imap_proto::{Command, protocol::ProtocolVersion, receiver::Receiver}; use tokio::{ io::{ReadHalf, WriteHalf}, sync::watch, diff --git a/crates/imap/src/core/session.rs b/crates/imap/src/core/session.rs index 9f2bc75e..6e060422 100644 --- a/crates/imap/src/core/session.rs +++ b/crates/imap/src/core/session.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use common::{ core::BuildServer, - listener::{stream::NullIo, SessionData, SessionManager, SessionResult, SessionStream}, + listener::{SessionData, SessionManager, SessionResult, SessionStream, stream::NullIo}, }; use imap_proto::{ protocol::{ProtocolVersion, SerializeResponse}, @@ -17,7 +17,7 @@ use imap_proto::{ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_rustls::server::TlsStream; -use crate::{GREETING_WITHOUT_TLS, GREETING_WITH_TLS}; +use crate::{GREETING_WITH_TLS, GREETING_WITHOUT_TLS}; use super::{ImapSessionManager, Session, State}; diff --git a/crates/imap/src/lib.rs b/crates/imap/src/lib.rs index f6df61e0..c1b73b57 100644 --- a/crates/imap/src/lib.rs +++ b/crates/imap/src/lib.rs @@ -6,7 +6,7 @@ use std::sync::LazyLock; -use imap_proto::{protocol::capability::Capability, ResponseCode, StatusResponse}; +use imap_proto::{ResponseCode, StatusResponse, protocol::capability::Capability}; pub mod core; pub mod op; diff --git a/crates/imap/src/op/authenticate.rs b/crates/imap/src/op/authenticate.rs index c1d15165..0d069fd2 100644 --- a/crates/imap/src/op/authenticate.rs +++ b/crates/imap/src/op/authenticate.rs @@ -6,16 +6,16 @@ use common::{ auth::{ - sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, AuthRequest, + sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, }, - listener::{limiter::LimiterResult, SessionStream}, + listener::{SessionStream, limiter::LimiterResult}, }; use directory::Permission; use imap_proto::{ + Command, ResponseCode, StatusResponse, protocol::{authenticate::Mechanism, capability::Capability}, receiver::{self, Request}, - Command, ResponseCode, StatusResponse, }; use mail_parser::decoders::base64::base64_decode; use mail_send::Credentials; @@ -110,7 +110,7 @@ impl Session { LimiterResult::Forbidden => { return Err(trc::LimitEvent::ConcurrentRequest .into_err() - .id(tag.clone())) + .id(tag.clone())); } LimiterResult::Disabled => None, }; diff --git a/crates/imap/src/op/capability.rs b/crates/imap/src/op/capability.rs index deebbb76..a811ecee 100644 --- a/crates/imap/src/op/capability.rs +++ b/crates/imap/src/op/capability.rs @@ -10,12 +10,12 @@ use crate::core::Session; use common::listener::SessionStream; use directory::Permission; use imap_proto::{ + Command, StatusResponse, protocol::{ - capability::{Capability, Response}, ImapResponse, + capability::{Capability, Response}, }, receiver::Request, - Command, StatusResponse, }; impl Session { diff --git a/crates/imap/src/op/close.rs b/crates/imap/src/op/close.rs index 88f690a3..85cfe62b 100644 --- a/crates/imap/src/op/close.rs +++ b/crates/imap/src/op/close.rs @@ -8,7 +8,7 @@ use std::time::Instant; use crate::core::{Session, State}; use common::listener::SessionStream; -use imap_proto::{receiver::Request, Command, StatusResponse}; +use imap_proto::{Command, StatusResponse, receiver::Request}; use trc::AddContext; impl Session { diff --git a/crates/imap/src/op/enable.rs b/crates/imap/src/op/enable.rs index e5dde55c..8aeb53c1 100644 --- a/crates/imap/src/op/enable.rs +++ b/crates/imap/src/op/enable.rs @@ -10,9 +10,9 @@ use crate::core::Session; use common::listener::SessionStream; use directory::Permission; use imap_proto::{ - protocol::{capability::Capability, enable, ImapResponse, ProtocolVersion}, - receiver::Request, Command, StatusResponse, + protocol::{ImapResponse, ProtocolVersion, capability::Capability, enable}, + receiver::Request, }; impl Session { diff --git a/crates/imap/src/op/login.rs b/crates/imap/src/op/login.rs index 12e08018..2312a56b 100644 --- a/crates/imap/src/op/login.rs +++ b/crates/imap/src/op/login.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use imap_proto::{receiver::Request, Command}; +use imap_proto::{Command, receiver::Request}; use crate::core::Session; use common::listener::SessionStream; diff --git a/crates/imap/src/op/logout.rs b/crates/imap/src/op/logout.rs index 9d16b095..9193b20c 100644 --- a/crates/imap/src/op/logout.rs +++ b/crates/imap/src/op/logout.rs @@ -8,7 +8,7 @@ use std::time::Instant; use crate::core::Session; use common::listener::SessionStream; -use imap_proto::{receiver::Request, Command, StatusResponse}; +use imap_proto::{Command, StatusResponse, receiver::Request}; impl Session { pub async fn handle_logout(&mut self, request: Request) -> trc::Result<()> { diff --git a/crates/imap/src/op/namespace.rs b/crates/imap/src/op/namespace.rs index 10f0ea00..465c4990 100644 --- a/crates/imap/src/op/namespace.rs +++ b/crates/imap/src/op/namespace.rs @@ -8,9 +8,9 @@ use crate::core::Session; use common::listener::SessionStream; use directory::Permission; use imap_proto::{ - protocol::{namespace::Response, ImapResponse}, - receiver::Request, Command, StatusResponse, + protocol::{ImapResponse, namespace::Response}, + receiver::Request, }; impl Session { diff --git a/crates/imap/src/op/noop.rs b/crates/imap/src/op/noop.rs index a13a342f..e3d8598d 100644 --- a/crates/imap/src/op/noop.rs +++ b/crates/imap/src/op/noop.rs @@ -8,7 +8,7 @@ use std::time::Instant; use crate::core::{Session, State}; use common::listener::SessionStream; -use imap_proto::{receiver::Request, Command, StatusResponse}; +use imap_proto::{Command, StatusResponse, receiver::Request}; impl Session { pub async fn handle_noop(&mut self, request: Request) -> trc::Result<()> { diff --git a/crates/imap/src/op/quota.rs b/crates/imap/src/op/quota.rs index 7a48a077..af2187b5 100644 --- a/crates/imap/src/op/quota.rs +++ b/crates/imap/src/op/quota.rs @@ -20,13 +20,13 @@ use crate::{ use common::listener::SessionStream; use directory::Permission; use imap_proto::{ + Command, ResponseCode, StatusResponse, protocol::{ + ImapResponse, capability::QuotaResourceName, quota::{Arguments, QuotaItem, QuotaResource, Response}, - ImapResponse, }, receiver::Request, - Command, ResponseCode, StatusResponse, }; impl Session { diff --git a/crates/imap/src/op/select.rs b/crates/imap/src/op/select.rs index 25a0879e..ff468691 100644 --- a/crates/imap/src/op/select.rs +++ b/crates/imap/src/op/select.rs @@ -8,14 +8,13 @@ use std::{sync::Arc, time::Instant}; use directory::Permission; use imap_proto::{ + Command, ResponseCode, StatusResponse, protocol::{ - fetch, + ImapResponse, Sequence, fetch, list::ListItem, select::{HighestModSeq, Response}, - ImapResponse, Sequence, }, receiver::Request, - Command, ResponseCode, StatusResponse, }; use crate::core::{SavedSearch, SelectedMailbox, Session, State}; diff --git a/crates/jmap-proto/src/error/method.rs b/crates/jmap-proto/src/error/method.rs index 749cad93..965804e7 100644 --- a/crates/jmap-proto/src/error/method.rs +++ b/crates/jmap-proto/src/error/method.rs @@ -6,8 +6,8 @@ use std::fmt::Display; -use serde::ser::SerializeMap; use serde::Serialize; +use serde::ser::SerializeMap; #[derive(Debug)] pub enum MethodError { diff --git a/crates/jmap-proto/src/method/changes.rs b/crates/jmap-proto/src/method/changes.rs index 2c6e32a2..82f8b740 100644 --- a/crates/jmap-proto/src/method/changes.rs +++ b/crates/jmap-proto/src/method/changes.rs @@ -5,8 +5,8 @@ */ use crate::{ - parser::{json::Parser, Ignore, JsonObjectParser, Token}, - request::{method::MethodObject, RequestProperty}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, + request::{RequestProperty, method::MethodObject}, types::{id::Id, property::Property, state::State}, }; @@ -69,7 +69,7 @@ impl JsonObjectParser for ChangesRequest { _ => { return Err(trc::JmapEvent::UnknownMethod .into_err() - .details(format!("{}/changes", parser.ctx))) + .details(format!("{}/changes", parser.ctx))); } }, account_id: Id::default(), diff --git a/crates/jmap-proto/src/method/lookup.rs b/crates/jmap-proto/src/method/lookup.rs index 3148d984..ec45ba2c 100644 --- a/crates/jmap-proto/src/method/lookup.rs +++ b/crates/jmap-proto/src/method/lookup.rs @@ -7,9 +7,9 @@ use utils::map::vec_map::VecMap; use crate::{ - parser::{json::Parser, JsonObjectParser, Token}, + parser::{JsonObjectParser, Token, json::Parser}, request::RequestProperty, - types::{blob::BlobId, id::Id, type_state::DataType, MaybeUnparsable}, + types::{MaybeUnparsable, blob::BlobId, id::Id, type_state::DataType}, }; #[derive(Debug, Clone)] diff --git a/crates/jmap-proto/src/method/query.rs b/crates/jmap-proto/src/method/query.rs index aaffeb77..b89a2228 100644 --- a/crates/jmap-proto/src/method/query.rs +++ b/crates/jmap-proto/src/method/query.rs @@ -10,8 +10,8 @@ use store::fts::{FilterItem, FilterType, FtsFilter}; use crate::{ object::{email, mailbox}, - parser::{json::Parser, Ignore, JsonObjectParser, Token}, - request::{method::MethodObject, RequestProperty, RequestPropertyParser}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, + request::{RequestProperty, RequestPropertyParser, method::MethodObject}, types::{date::UTCDate, id::Id, keyword::Keyword, state::State}, }; @@ -165,7 +165,7 @@ impl JsonObjectParser for QueryRequest { _ => { return Err(trc::JmapEvent::UnknownMethod .into_err() - .details(format!("{}/query", parser.ctx))) + .details(format!("{}/query", parser.ctx))); } }, filter: vec![], diff --git a/crates/jmap-proto/src/method/query_changes.rs b/crates/jmap-proto/src/method/query_changes.rs index 8df92b9e..7f311e6f 100644 --- a/crates/jmap-proto/src/method/query_changes.rs +++ b/crates/jmap-proto/src/method/query_changes.rs @@ -5,12 +5,12 @@ */ use crate::{ - parser::{json::Parser, Ignore, JsonObjectParser, Token}, - request::{method::MethodObject, RequestProperty, RequestPropertyParser}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, + request::{RequestProperty, RequestPropertyParser, method::MethodObject}, types::{id::Id, state::State}, }; -use super::query::{parse_filter, parse_sort, Comparator, Filter, RequestArguments}; +use super::query::{Comparator, Filter, RequestArguments, parse_filter, parse_sort}; #[derive(Debug, Clone)] pub struct QueryChangesRequest { @@ -72,7 +72,7 @@ impl JsonObjectParser for QueryChangesRequest { _ => { return Err(trc::JmapEvent::UnknownMethod .into_err() - .details(format!("{}/queryChanges", parser.ctx))) + .details(format!("{}/queryChanges", parser.ctx))); } }, filter: vec![], diff --git a/crates/jmap-proto/src/method/search_snippet.rs b/crates/jmap-proto/src/method/search_snippet.rs index 203ad226..5dd2b193 100644 --- a/crates/jmap-proto/src/method/search_snippet.rs +++ b/crates/jmap-proto/src/method/search_snippet.rs @@ -5,15 +5,15 @@ */ use crate::{ - parser::{json::Parser, Ignore, JsonObjectParser, Token}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, request::{ - reference::{MaybeReference, ResultReference}, RequestProperty, + reference::{MaybeReference, ResultReference}, }, types::id::Id, }; -use super::query::{parse_filter, Filter}; +use super::query::{Filter, parse_filter}; #[derive(Debug, Clone)] pub struct GetSearchSnippetRequest { diff --git a/crates/jmap-proto/src/method/upload.rs b/crates/jmap-proto/src/method/upload.rs index e8be489d..b406ff80 100644 --- a/crates/jmap-proto/src/method/upload.rs +++ b/crates/jmap-proto/src/method/upload.rs @@ -10,8 +10,8 @@ use utils::map::vec_map::VecMap; use crate::{ error::set::SetError, - parser::{json::Parser, Ignore, JsonObjectParser, Token}, - request::{reference::MaybeReference, RequestProperty}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, + request::{RequestProperty, reference::MaybeReference}, response::Response, types::{blob::BlobId, id::Id}, }; diff --git a/crates/jmap-proto/src/method/validate.rs b/crates/jmap-proto/src/method/validate.rs index 19d05ea8..6e36d15c 100644 --- a/crates/jmap-proto/src/method/validate.rs +++ b/crates/jmap-proto/src/method/validate.rs @@ -8,7 +8,7 @@ use serde::Serialize; use crate::{ error::set::SetError, - parser::{json::Parser, JsonObjectParser, Token}, + parser::{JsonObjectParser, Token, json::Parser}, request::RequestProperty, types::{blob::BlobId, id::Id}, }; diff --git a/crates/jmap-proto/src/object/blob.rs b/crates/jmap-proto/src/object/blob.rs index 999f57cf..d5b15e2a 100644 --- a/crates/jmap-proto/src/object/blob.rs +++ b/crates/jmap-proto/src/object/blob.rs @@ -5,7 +5,7 @@ */ use crate::{ - parser::{json::Parser, Ignore}, + parser::{Ignore, json::Parser}, request::{RequestProperty, RequestPropertyParser}, }; diff --git a/crates/jmap-proto/src/object/email.rs b/crates/jmap-proto/src/object/email.rs index 66d02319..b85a2f7d 100644 --- a/crates/jmap-proto/src/object/email.rs +++ b/crates/jmap-proto/src/object/email.rs @@ -5,7 +5,7 @@ */ use crate::{ - parser::{json::Parser, Ignore, JsonObjectParser}, + parser::{Ignore, JsonObjectParser, json::Parser}, request::{RequestProperty, RequestPropertyParser}, types::property::Property, }; diff --git a/crates/jmap-proto/src/object/mailbox.rs b/crates/jmap-proto/src/object/mailbox.rs index 5cc3225a..614abd7c 100644 --- a/crates/jmap-proto/src/object/mailbox.rs +++ b/crates/jmap-proto/src/object/mailbox.rs @@ -5,7 +5,7 @@ */ use crate::{ - parser::{json::Parser, Ignore}, + parser::{Ignore, json::Parser}, request::{RequestProperty, RequestPropertyParser}, }; diff --git a/crates/jmap-proto/src/object/sieve.rs b/crates/jmap-proto/src/object/sieve.rs index 8d92774d..658bd768 100644 --- a/crates/jmap-proto/src/object/sieve.rs +++ b/crates/jmap-proto/src/object/sieve.rs @@ -6,7 +6,7 @@ use crate::{ parser::json::Parser, - request::{reference::MaybeReference, RequestProperty, RequestPropertyParser}, + request::{RequestProperty, RequestPropertyParser, reference::MaybeReference}, types::id::Id, }; diff --git a/crates/jmap-proto/src/parser/json.rs b/crates/jmap-proto/src/parser/json.rs index 8492fdb9..207751a8 100644 --- a/crates/jmap-proto/src/parser/json.rs +++ b/crates/jmap-proto/src/parser/json.rs @@ -281,7 +281,7 @@ impl<'x> Parser<'x> { Token::Comma => (), Token::DictEnd => return Ok(None), token => { - return Err(self.error(&format!("Expected object property, found {}", token))) + return Err(self.error(&format!("Expected object property, found {}", token))); } } } diff --git a/crates/jmap-proto/src/request/capability.rs b/crates/jmap-proto/src/request/capability.rs index 8a1b8685..8a7ff660 100644 --- a/crates/jmap-proto/src/request/capability.rs +++ b/crates/jmap-proto/src/request/capability.rs @@ -7,7 +7,7 @@ use utils::map::vec_map::VecMap; use crate::{ - parser::{json::Parser, JsonObjectParser}, + parser::{JsonObjectParser, json::Parser}, response::serialize::serialize_hex, types::{id::Id, type_state::DataType}, }; diff --git a/crates/jmap-proto/src/request/echo.rs b/crates/jmap-proto/src/request/echo.rs index 561bf088..9896eecf 100644 --- a/crates/jmap-proto/src/request/echo.rs +++ b/crates/jmap-proto/src/request/echo.rs @@ -7,7 +7,7 @@ use serde_json::value::RawValue; use std::fmt::Write; -use crate::parser::{json::Parser, JsonObjectParser, Token}; +use crate::parser::{JsonObjectParser, Token, json::Parser}; #[derive(Debug, serde::Serialize)] pub struct Echo { diff --git a/crates/jmap-proto/src/request/method.rs b/crates/jmap-proto/src/request/method.rs index be2f4f84..410f70e9 100644 --- a/crates/jmap-proto/src/request/method.rs +++ b/crates/jmap-proto/src/request/method.rs @@ -6,7 +6,7 @@ use std::fmt::Display; -use crate::parser::{json::Parser, JsonObjectParser}; +use crate::parser::{JsonObjectParser, json::Parser}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MethodName { diff --git a/crates/jmap-proto/src/request/mod.rs b/crates/jmap-proto/src/request/mod.rs index 6e12d42a..e939b5c1 100644 --- a/crates/jmap-proto/src/request/mod.rs +++ b/crates/jmap-proto/src/request/mod.rs @@ -31,7 +31,7 @@ use crate::{ upload::BlobUploadRequest, validate::ValidateSieveScriptRequest, }, - parser::{json::Parser, JsonObjectParser}, + parser::{JsonObjectParser, json::Parser}, types::any_id::AnyId, }; diff --git a/crates/jmap-proto/src/request/parser.rs b/crates/jmap-proto/src/request/parser.rs index 13649df5..c330b08c 100644 --- a/crates/jmap-proto/src/request/parser.rs +++ b/crates/jmap-proto/src/request/parser.rs @@ -21,15 +21,15 @@ use crate::{ upload::BlobUploadRequest, validate::ValidateSieveScriptRequest, }, - parser::{json::Parser, Ignore, JsonObjectParser, Token}, + parser::{Ignore, JsonObjectParser, Token, json::Parser}, types::any_id::AnyId, }; use super::{ + Call, Request, RequestMethod, capability::Capability, echo::Echo, method::{MethodFunction, MethodName, MethodObject}, - Call, Request, RequestMethod, }; impl Request { diff --git a/crates/jmap-proto/src/request/reference.rs b/crates/jmap-proto/src/request/reference.rs index ddab1d3d..0dcc9405 100644 --- a/crates/jmap-proto/src/request/reference.rs +++ b/crates/jmap-proto/src/request/reference.rs @@ -7,7 +7,7 @@ use std::fmt::Display; use crate::{ - parser::{json::Parser, JsonObjectParser, Token}, + parser::{JsonObjectParser, Token, json::Parser}, types::{id::Id, pointer::JSONPointer}, }; diff --git a/crates/jmap-proto/src/request/websocket.rs b/crates/jmap-proto/src/request/websocket.rs index 97028348..b75446a8 100644 --- a/crates/jmap-proto/src/request/websocket.rs +++ b/crates/jmap-proto/src/request/websocket.rs @@ -8,9 +8,9 @@ use std::{borrow::Cow, collections::HashMap}; use crate::{ error::request::{RequestError, RequestErrorType, RequestLimitError}, - parser::{json::Parser, JsonObjectParser, Token}, + parser::{JsonObjectParser, Token, json::Parser}, request::Call, - response::{serialize::serialize_hex, Response, ResponseMethod}, + response::{Response, ResponseMethod, serialize::serialize_hex}, types::{any_id::AnyId, id::Id, state::State, type_state::DataType}, }; use utils::map::vec_map::VecMap; diff --git a/crates/jmap-proto/src/response/serialize.rs b/crates/jmap-proto/src/response/serialize.rs index e457a15b..da7926a7 100644 --- a/crates/jmap-proto/src/response/serialize.rs +++ b/crates/jmap-proto/src/response/serialize.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use serde::{ser::SerializeSeq, Serialize}; +use serde::{Serialize, ser::SerializeSeq}; use crate::request::Call; diff --git a/crates/jmap-proto/src/types/any_id.rs b/crates/jmap-proto/src/types/any_id.rs index 3adb36f0..cbce16b1 100644 --- a/crates/jmap-proto/src/types/any_id.rs +++ b/crates/jmap-proto/src/types/any_id.rs @@ -5,7 +5,7 @@ */ use crate::{ - parser::{json::Parser, JsonObjectParser}, + parser::{JsonObjectParser, json::Parser}, request::reference::MaybeReference, }; diff --git a/crates/jmap-proto/src/types/mod.rs b/crates/jmap-proto/src/types/mod.rs index 199bc8ac..0fdf97e3 100644 --- a/crates/jmap-proto/src/types/mod.rs +++ b/crates/jmap-proto/src/types/mod.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use crate::parser::{json::Parser, JsonObjectParser}; +use crate::parser::{JsonObjectParser, json::Parser}; pub mod acl; pub mod any_id; diff --git a/crates/jmap-proto/src/types/pointer.rs b/crates/jmap-proto/src/types/pointer.rs index 2062e6f5..7325b317 100644 --- a/crates/jmap-proto/src/types/pointer.rs +++ b/crates/jmap-proto/src/types/pointer.rs @@ -6,7 +6,7 @@ use std::fmt::Display; -use crate::parser::{json::Parser, JsonObjectParser}; +use crate::parser::{JsonObjectParser, json::Parser}; #[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize)] pub enum JSONPointer { diff --git a/crates/jmap-proto/src/types/state.rs b/crates/jmap-proto/src/types/state.rs index 422c0e97..3788d447 100644 --- a/crates/jmap-proto/src/types/state.rs +++ b/crates/jmap-proto/src/types/state.rs @@ -9,9 +9,9 @@ use utils::codec::{ leb128::{Leb128Iterator, Leb128Writer}, }; -use crate::parser::{base32::JsonBase32Reader, json::Parser, JsonObjectParser}; +use crate::parser::{JsonObjectParser, base32::JsonBase32Reader, json::Parser}; -use super::{type_state::DataType, ChangeId}; +use super::{ChangeId, type_state::DataType}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct JMAPIntermediateState { diff --git a/crates/jmap/src/changes/query.rs b/crates/jmap/src/changes/query.rs index bcaa76a7..fed0c3e5 100644 --- a/crates/jmap/src/changes/query.rs +++ b/crates/jmap/src/changes/query.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::{auth::AccessToken, Server}; +use common::{Server, auth::AccessToken}; use jmap_proto::method::{ changes::{self, ChangesRequest}, query::{self, QueryRequest}, @@ -50,7 +50,7 @@ impl QueryChanges for Server { _ => { return Err(trc::JmapEvent::UnknownMethod .into_err() - .details("Unknown method")) + .details("Unknown method")); } }, }, diff --git a/crates/jmap/src/email/snippet.rs b/crates/jmap/src/email/snippet.rs index 7f65a4aa..5b99d4a5 100644 --- a/crates/jmap/src/email/snippet.rs +++ b/crates/jmap/src/email/snippet.rs @@ -18,7 +18,10 @@ use jmap_proto::{ }; use mail_parser::decoders::html::html_to_text; use nlp::language::{Language, search_snippet::generate_snippet, stemmer::Stemmer}; -use store::{backend::MAX_TOKEN_LENGTH, write::{AlignedBytes, Archive}}; +use store::{ + backend::MAX_TOKEN_LENGTH, + write::{AlignedBytes, Archive}, +}; use trc::AddContext; use utils::BlobHash; diff --git a/crates/jmap/src/identity/get.rs b/crates/jmap/src/identity/get.rs index af11dbb2..05fb10f6 100644 --- a/crates/jmap/src/identity/get.rs +++ b/crates/jmap/src/identity/get.rs @@ -16,7 +16,10 @@ use jmap_proto::{ }, }; use store::{ - rkyv::{option::ArchivedOption, vec::ArchivedVec}, roaring::RoaringBitmap, write::{AlignedBytes, Archive, Archiver, BatchBuilder}, Serialize + Serialize, + rkyv::{option::ArchivedOption, vec::ArchivedVec}, + roaring::RoaringBitmap, + write::{AlignedBytes, Archive, Archiver, BatchBuilder}, }; use trc::AddContext; use utils::sanitize_email; diff --git a/crates/jmap/src/identity/set.rs b/crates/jmap/src/identity/set.rs index 850d793b..97ac1b72 100644 --- a/crates/jmap/src/identity/set.rs +++ b/crates/jmap/src/identity/set.rs @@ -18,7 +18,7 @@ use jmap_proto::{ }, }; use std::future::Future; -use store::write::{log::ChangeLogBuilder, AlignedBytes, Archive, BatchBuilder}; +use store::write::{AlignedBytes, Archive, BatchBuilder, log::ChangeLogBuilder}; use store::{Serialize, write::Archiver}; use trc::AddContext; use utils::sanitize_email; diff --git a/crates/jmap/src/push/get.rs b/crates/jmap/src/push/get.rs index d0c8c4f2..b86555be 100644 --- a/crates/jmap/src/push/get.rs +++ b/crates/jmap/src/push/get.rs @@ -19,7 +19,8 @@ use jmap_proto::{ }, }; use store::{ - write::{now, AlignedBytes, Archive, ValueClass}, BitmapKey, ValueKey + BitmapKey, ValueKey, + write::{AlignedBytes, Archive, ValueClass, now}, }; use trc::{AddContext, ServerEvent}; use utils::map::bitmap::Bitmap; diff --git a/crates/jmap/src/push/set.rs b/crates/jmap/src/push/set.rs index 8267fe98..dd85b343 100644 --- a/crates/jmap/src/push/set.rs +++ b/crates/jmap/src/push/set.rs @@ -22,7 +22,9 @@ use jmap_proto::{ use rand::distr::Alphanumeric; use std::future::Future; use store::{ - rand::{rng, Rng}, write::{now, AlignedBytes, Archive, Archiver, BatchBuilder}, Serialize + Serialize, + rand::{Rng, rng}, + write::{AlignedBytes, Archive, Archiver, BatchBuilder, now}, }; use trc::AddContext; use utils::map::bitmap::Bitmap; diff --git a/crates/jmap/src/quota/query.rs b/crates/jmap/src/quota/query.rs index dae4ce1e..52886490 100644 --- a/crates/jmap/src/quota/query.rs +++ b/crates/jmap/src/quota/query.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::{auth::AccessToken, Server}; +use common::{Server, auth::AccessToken}; use jmap_proto::{ method::query::{QueryRequest, QueryResponse, RequestArguments}, types::{id::Id, state::State}, diff --git a/crates/jmap/src/sieve/get.rs b/crates/jmap/src/sieve/get.rs index 30cd00dc..f597d9df 100644 --- a/crates/jmap/src/sieve/get.rs +++ b/crates/jmap/src/sieve/get.rs @@ -15,7 +15,10 @@ use jmap_proto::{ value::{Object, Value}, }, }; -use store::{write::{AlignedBytes, Archive}, BlobClass}; +use store::{ + BlobClass, + write::{AlignedBytes, Archive}, +}; use trc::AddContext; use crate::changes::state::StateManager; diff --git a/crates/jmap/src/sieve/validate.rs b/crates/jmap/src/sieve/validate.rs index 81b19fbb..7ffd431a 100644 --- a/crates/jmap/src/sieve/validate.rs +++ b/crates/jmap/src/sieve/validate.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::{auth::AccessToken, Server}; +use common::{Server, auth::AccessToken}; use jmap_proto::{ error::set::{SetError, SetErrorType}, method::validate::{ValidateSieveScriptRequest, ValidateSieveScriptResponse}, diff --git a/crates/jmap/src/submission/get.rs b/crates/jmap/src/submission/get.rs index bccee47f..a8995828 100644 --- a/crates/jmap/src/submission/get.rs +++ b/crates/jmap/src/submission/get.rs @@ -21,7 +21,10 @@ use jmap_proto::{ use smtp::queue::{ArchivedStatus, Message, spool::SmtpSpool}; use smtp_proto::ArchivedResponse; use std::future::Future; -use store::{rkyv::option::ArchivedOption, write::{AlignedBytes, Archive}}; +use store::{ + rkyv::option::ArchivedOption, + write::{AlignedBytes, Archive}, +}; use trc::AddContext; use utils::map::vec_map::VecMap; diff --git a/crates/jmap/src/submission/set.rs b/crates/jmap/src/submission/set.rs index 341af58f..a1975cb7 100644 --- a/crates/jmap/src/submission/set.rs +++ b/crates/jmap/src/submission/set.rs @@ -38,7 +38,7 @@ use smtp::{ queue::spool::SmtpSpool, }; use smtp_proto::{MailFrom, RcptTo, request::parser::Rfc5321Parser}; -use store::write::{log::ChangeLogBuilder, now, AlignedBytes, Archive, BatchBuilder}; +use store::write::{AlignedBytes, Archive, BatchBuilder, log::ChangeLogBuilder, now}; use trc::AddContext; use utils::{BlobHash, map::vec_map::VecMap, sanitize_email}; diff --git a/crates/managesieve/src/core/mod.rs b/crates/managesieve/src/core/mod.rs index 20f41ab4..5fa53aae 100644 --- a/crates/managesieve/src/core/mod.rs +++ b/crates/managesieve/src/core/mod.rs @@ -10,9 +10,9 @@ pub mod session; use std::{borrow::Cow, net::IpAddr, sync::Arc}; use common::{ - auth::AccessToken, - listener::{limiter::InFlight, ServerInstance}, Inner, Server, + auth::AccessToken, + listener::{ServerInstance, limiter::InFlight}, }; use imap_proto::receiver::{CommandParser, Receiver}; use tokio::io::{AsyncRead, AsyncWrite}; diff --git a/crates/managesieve/src/op/authenticate.rs b/crates/managesieve/src/op/authenticate.rs index 887e7ac3..fc63053f 100644 --- a/crates/managesieve/src/op/authenticate.rs +++ b/crates/managesieve/src/op/authenticate.rs @@ -6,10 +6,10 @@ use common::{ auth::{ - sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, AuthRequest, + sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, }, - listener::{limiter::LimiterResult, SessionStream}, + listener::{SessionStream, limiter::LimiterResult}, }; use directory::Permission; use imap_proto::{ @@ -64,7 +64,7 @@ impl Session { _ => { return Err(trc::AuthEvent::Error .into_err() - .details("Authentication mechanism not supported.")) + .details("Authentication mechanism not supported.")); } }; diff --git a/crates/nlp/src/bayes/classify.rs b/crates/nlp/src/bayes/classify.rs index c18c367f..78f3addc 100644 --- a/crates/nlp/src/bayes/classify.rs +++ b/crates/nlp/src/bayes/classify.rs @@ -130,11 +130,7 @@ fn inv_chi_square(value: f64, freedom_deg: u32) -> f64 { * confidence that inv-chi-square is close to zero */ - if value < 0.0 { - 0.0 - } else { - 1.0 - } + if value < 0.0 { 0.0 } else { 1.0 } } } diff --git a/crates/nlp/src/bayes/tokenize.rs b/crates/nlp/src/bayes/tokenize.rs index 52f3cec8..eb2bb1aa 100644 --- a/crates/nlp/src/bayes/tokenize.rs +++ b/crates/nlp/src/bayes/tokenize.rs @@ -8,10 +8,10 @@ use std::borrow::Cow; use crate::{ language::{ + Language, detect::{LanguageDetector, MIN_LANGUAGE_SCORE}, stemmer::STEMMER_MAP, - stopwords::{StopwordFnc, STOP_WORDS}, - Language, + stopwords::{STOP_WORDS, StopwordFnc}, }, tokenizers::{chinese::JIEBA, japanese}, }; @@ -7875,7 +7875,7 @@ pub mod tests { tokenizers::types::{TokenType, TypesTokenizer}, }; - use super::{symbols, BayesInputToken}; + use super::{BayesInputToken, symbols}; pub trait ToBayesToken { fn to_bayes_token(&self) -> Option; diff --git a/crates/nlp/src/language/detect.rs b/crates/nlp/src/language/detect.rs index 0312f0d8..bef69d59 100644 --- a/crates/nlp/src/language/detect.rs +++ b/crates/nlp/src/language/detect.rs @@ -5,7 +5,7 @@ */ use ahash::AHashMap; -use whatlang::{detect, Lang}; +use whatlang::{Lang, detect}; use super::Language; diff --git a/crates/nlp/src/language/mod.rs b/crates/nlp/src/language/mod.rs index 6218bd4a..39e92ec0 100644 --- a/crates/nlp/src/language/mod.rs +++ b/crates/nlp/src/language/mod.rs @@ -12,7 +12,7 @@ pub mod stopwords; use std::borrow::Cow; use crate::tokenizers::{ - chinese::ChineseTokenizer, japanese::JapaneseTokenizer, word::WordTokenizer, Token, + Token, chinese::ChineseTokenizer, japanese::JapaneseTokenizer, word::WordTokenizer, }; use self::detect::LanguageDetector; diff --git a/crates/nlp/src/language/search_snippet.rs b/crates/nlp/src/language/search_snippet.rs index 4da899a3..00ba8520 100644 --- a/crates/nlp/src/language/search_snippet.rs +++ b/crates/nlp/src/language/search_snippet.rs @@ -157,95 +157,96 @@ pub fn generate_snippet( #[cfg(test)] mod tests { - use crate::language::{search_snippet::generate_snippet, Language}; + use crate::language::{Language, search_snippet::generate_snippet}; #[test] fn search_snippets() { let inputs = [ - (vec![ - "Help a friend from Abidjan Côte d'Ivoire", - concat!( - "When my mother died when she was given birth to me, my father took me so ", - "special because I am motherless. Before the death of my late father on 22nd June ", - "2013 in a private hospital here in Abidjan Côte d'Ivoire. He secretly called me on his ", - "bedside and told me that he has a sum of $7.5M (Seven Million five Hundred ", - "Thousand Dollars) left in a suspense account in a local bank here in Abidjan Côte ", - "d'Ivoire, that he used my name as his only daughter for the next of kin in deposit of ", - "the fund. ", - "I am 24year old. Dear I am honorably seeking your assistance in the following ways. ", - "1) To provide any bank account where this money would be transferred into. ", - "2) To serve as the guardian of this fund. ", - "3) To make arrangement for me to come over to your country to further my ", - "education and to secure a residential permit for me in your country. ", - "Moreover, I am willing to offer you 30 percent of the total sum as compensation for ", - "your effort input after the successful transfer of this fund to your nominated ", - "account overseas." - )], + ( + vec![ + "Help a friend from Abidjan Côte d'Ivoire", + concat!( + "When my mother died when she was given birth to me, my father took me so ", + "special because I am motherless. Before the death of my late father on 22nd June ", + "2013 in a private hospital here in Abidjan Côte d'Ivoire. He secretly called me on his ", + "bedside and told me that he has a sum of $7.5M (Seven Million five Hundred ", + "Thousand Dollars) left in a suspense account in a local bank here in Abidjan Côte ", + "d'Ivoire, that he used my name as his only daughter for the next of kin in deposit of ", + "the fund. ", + "I am 24year old. Dear I am honorably seeking your assistance in the following ways. ", + "1) To provide any bank account where this money would be transferred into. ", + "2) To serve as the guardian of this fund. ", + "3) To make arrangement for me to come over to your country to further my ", + "education and to secure a residential permit for me in your country. ", + "Moreover, I am willing to offer you 30 percent of the total sum as compensation for ", + "your effort input after the successful transfer of this fund to your nominated ", + "account overseas." + ), + ], vec![ ( - vec!["côte"], + vec!["côte"], vec![ - "Help a friend from Abidjan Côte d'Ivoire", + "Help a friend from Abidjan Côte d'Ivoire", concat!( - "in Abidjan Côte d'Ivoire. He secretly called me on his bedside ", - "and told me that he has a sum of $7.5M (Seven Million five Hundred Thousand ", - "Dollars) left in a suspense account in a local bank here in Abidjan ", - "Côte d'Ivoire, that ") - ] + "in Abidjan Côte d'Ivoire. He secretly called me on his bedside ", + "and told me that he has a sum of $7.5M (Seven Million five Hundred Thousand ", + "Dollars) left in a suspense account in a local bank here in Abidjan ", + "Côte d'Ivoire, that " + ), + ], ), ( - vec!["your", "country"], - vec![ - concat!( - "honorably seeking your assistance in the following ways. ", + vec!["your", "country"], + vec![concat!( + "honorably seeking your assistance in the following ways. ", "1) To provide any bank account where this money would be transferred into. 2) ", "To serve as the guardian of this fund. 3) To make arrangement for me to come ", "over to your " - )] + )], ), ( - vec!["overseas"], - vec![ - "nominated account overseas." - ] + vec!["overseas"], + vec!["nominated account overseas."], ), - ], ), - (vec![ - "孫子兵法", - concat!( - "<\"孫子兵法:\">", - "孫子曰:兵者,國之大事,死生之地,存亡之道,不可不察也。", - "孫子曰:凡用兵之法,馳車千駟,革車千乘,帶甲十萬;千里饋糧,則內外之費賓客之用,膠漆之材,", - "車甲之奉,日費千金,然後十萬之師舉矣。", - "孫子曰:凡用兵之法,全國為上,破國次之;全旅為上,破旅次之;全卒為上,破卒次之;全伍為上,破伍次之。", - "是故百戰百勝,非善之善者也;不戰而屈人之兵,善之善者也。", - "孫子曰:昔之善戰者,先為不可勝,以待敵之可勝,不可勝在己,可勝在敵。故善戰者,能為不可勝,不能使敵必可勝。", - "故曰:勝可知,而不可為。", - "兵者,詭道也。故能而示之不能,用而示之不用,近而示之遠,遠而示之近。利而誘之,亂而取之,實而備之,強而避之,", - "怒而撓之,卑而驕之,佚而勞之,親而離之。攻其無備,出其不意,此兵家之勝,不可先傳也。", - "夫未戰而廟算勝者,得算多也;未戰而廟算不勝者,得算少也;多算勝,少算不勝,而況於無算乎?吾以此觀之,勝負見矣。", - "孫子曰:凡治眾如治寡,分數是也。鬥眾如鬥寡,形名是也。三軍之眾,可使必受敵而無敗者,奇正是也。兵之所加,", - "如以碬投卵者,虛實是也。", - )], + ( + vec![ + "孫子兵法", + concat!( + "<\"孫子兵法:\">", + "孫子曰:兵者,國之大事,死生之地,存亡之道,不可不察也。", + "孫子曰:凡用兵之法,馳車千駟,革車千乘,帶甲十萬;千里饋糧,則內外之費賓客之用,膠漆之材,", + "車甲之奉,日費千金,然後十萬之師舉矣。", + "孫子曰:凡用兵之法,全國為上,破國次之;全旅為上,破旅次之;全卒為上,破卒次之;全伍為上,破伍次之。", + "是故百戰百勝,非善之善者也;不戰而屈人之兵,善之善者也。", + "孫子曰:昔之善戰者,先為不可勝,以待敵之可勝,不可勝在己,可勝在敵。故善戰者,能為不可勝,不能使敵必可勝。", + "故曰:勝可知,而不可為。", + "兵者,詭道也。故能而示之不能,用而示之不用,近而示之遠,遠而示之近。利而誘之,亂而取之,實而備之,強而避之,", + "怒而撓之,卑而驕之,佚而勞之,親而離之。攻其無備,出其不意,此兵家之勝,不可先傳也。", + "夫未戰而廟算勝者,得算多也;未戰而廟算不勝者,得算少也;多算勝,少算不勝,而況於無算乎?吾以此觀之,勝負見矣。", + "孫子曰:凡治眾如治寡,分數是也。鬥眾如鬥寡,形名是也。三軍之眾,可使必受敵而無敗者,奇正是也。兵之所加,", + "如以碬投卵者,虛實是也。", + ), + ], vec![ ( - vec!["孫子兵法"], + vec!["孫子兵法"], vec![ - "孫子兵法", + "孫子兵法", concat!( - "<"孫子兵法:">孫子曰:兵者,國之大事,死生之地,存亡之道,", - "不可不察也。孫子曰:凡用兵之法,馳車千駟,革車千乘,帶甲十萬;千里饋糧,則內外之費賓客之用,膠"), - ] + "<"孫子兵法:">孫子曰:兵者,國之大事,死生之地,存亡之道,", + "不可不察也。孫子曰:凡用兵之法,馳車千駟,革車千乘,帶甲十萬;千里饋糧,則內外之費賓客之用,膠" + ), + ], ), ( - vec!["孫子曰"], - vec![ - concat!( - "<"孫子兵法:">孫子曰:兵者,國之大事,死生之地,存亡之道,", + vec!["孫子曰"], + vec![concat!( + "<"孫子兵法:">孫子曰:兵者,國之大事,死生之地,存亡之道,", "不可不察也。孫子曰:凡用兵之法,馳車千駟,革車千乘,帶甲十萬;千里饋糧,則內外之費賓", - )] + )], ), ], ), diff --git a/crates/nlp/src/lib.rs b/crates/nlp/src/lib.rs index 659721b0..b304f9f6 100644 --- a/crates/nlp/src/lib.rs +++ b/crates/nlp/src/lib.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - pub mod bayes; +pub mod bayes; pub mod language; pub mod tokenizers; @@ -14,8 +14,8 @@ mod test { use crate::{ bayes::{ - tokenize::{tests::ToBayesToken, BayesTokenizer}, BayesClassifier, BayesModel, + tokenize::{BayesTokenizer, tests::ToBayesToken}, }, tokenizers::{ osb::{OsbToken, OsbTokenizer}, diff --git a/crates/nlp/src/tokenizers/chinese.rs b/crates/nlp/src/tokenizers/chinese.rs index c6057f2e..6eb4d9ac 100644 --- a/crates/nlp/src/tokenizers/chinese.rs +++ b/crates/nlp/src/tokenizers/chinese.rs @@ -95,7 +95,7 @@ where #[cfg(test)] mod tests { - use crate::tokenizers::{chinese::ChineseTokenizer, word::WordTokenizer, Token}; + use crate::tokenizers::{Token, chinese::ChineseTokenizer, word::WordTokenizer}; #[test] fn chinese_tokenizer() { diff --git a/crates/nlp/src/tokenizers/japanese.rs b/crates/nlp/src/tokenizers/japanese.rs index 5f9fc15d..effe42e0 100644 --- a/crates/nlp/src/tokenizers/japanese.rs +++ b/crates/nlp/src/tokenizers/japanese.rs @@ -315,7 +315,7 @@ static UW6: LazyLock> = LazyLock::new(|| { #[cfg(test)] mod tests { - use crate::tokenizers::{japanese::JapaneseTokenizer, word::WordTokenizer, Token}; + use crate::tokenizers::{Token, japanese::JapaneseTokenizer, word::WordTokenizer}; #[test] fn japanese_tokenizer() { diff --git a/crates/pop3/src/client.rs b/crates/pop3/src/client.rs index ad866f57..91c92766 100644 --- a/crates/pop3/src/client.rs +++ b/crates/pop3/src/client.rs @@ -5,15 +5,15 @@ */ use common::{ - listener::{SessionResult, SessionStream}, KV_RATE_LIMIT_IMAP, + listener::{SessionResult, SessionStream}, }; use mail_send::Credentials; use trc::{AddContext, SecurityEvent}; use crate::{ - protocol::{request::Error, Command, Mechanism}, Session, State, + protocol::{Command, Mechanism, request::Error}, }; impl Session { @@ -67,9 +67,10 @@ impl Session { } Ok(false) => {} Err(err) => { - trc::error!(err - .span_id(self.session_id) - .details("Failed to check for fail2ban")); + trc::error!( + err.span_id(self.session_id) + .details("Failed to check for fail2ban") + ); } } } diff --git a/crates/pop3/src/lib.rs b/crates/pop3/src/lib.rs index a7429338..3d0571f9 100644 --- a/crates/pop3/src/lib.rs +++ b/crates/pop3/src/lib.rs @@ -7,9 +7,9 @@ use std::{net::IpAddr, sync::Arc}; use common::{ - auth::AccessToken, - listener::{limiter::InFlight, ServerInstance, SessionStream}, Inner, Server, + auth::AccessToken, + listener::{ServerInstance, SessionStream, limiter::InFlight}, }; use mailbox::Mailbox; use protocol::request::Parser; diff --git a/crates/pop3/src/op/authenticate.rs b/crates/pop3/src/op/authenticate.rs index 665247bc..7cc04c3f 100644 --- a/crates/pop3/src/op/authenticate.rs +++ b/crates/pop3/src/op/authenticate.rs @@ -6,18 +6,18 @@ use common::{ auth::{ - sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, AuthRequest, + sasl::{sasl_decode_challenge_oauth, sasl_decode_challenge_plain}, }, - listener::{limiter::LimiterResult, SessionStream}, + listener::{SessionStream, limiter::LimiterResult}, }; use directory::Permission; use mail_parser::decoders::base64::base64_decode; use mail_send::Credentials; use crate::{ - protocol::{request, Command, Mechanism}, Session, State, + protocol::{Command, Mechanism, request}, }; impl Session { diff --git a/crates/pop3/src/op/list.rs b/crates/pop3/src/op/list.rs index 0c004ce0..2036d473 100644 --- a/crates/pop3/src/op/list.rs +++ b/crates/pop3/src/op/list.rs @@ -9,7 +9,7 @@ use std::time::Instant; use common::listener::SessionStream; use directory::Permission; -use crate::{protocol::response::Response, Session}; +use crate::{Session, protocol::response::Response}; impl Session { pub async fn handle_list(&mut self, msg: Option) -> trc::Result<()> { diff --git a/crates/pop3/src/op/mod.rs b/crates/pop3/src/op/mod.rs index bfc1db7d..26d4de4a 100644 --- a/crates/pop3/src/op/mod.rs +++ b/crates/pop3/src/op/mod.rs @@ -7,8 +7,8 @@ use common::listener::SessionStream; use crate::{ - protocol::{response::Response, Mechanism}, Session, + protocol::{Mechanism, response::Response}, }; pub mod authenticate; diff --git a/crates/pop3/src/protocol/request.rs b/crates/pop3/src/protocol/request.rs index 829f9f36..e0336cb9 100644 --- a/crates/pop3/src/protocol/request.rs +++ b/crates/pop3/src/protocol/request.rs @@ -323,7 +323,7 @@ impl Mechanism { #[cfg(test)] mod tests { - use crate::protocol::{request::Error, Command, Mechanism}; + use crate::protocol::{Command, Mechanism, request::Error}; use super::Parser; diff --git a/crates/pop3/src/session.rs b/crates/pop3/src/session.rs index d016170a..2bbde5d5 100644 --- a/crates/pop3/src/session.rs +++ b/crates/pop3/src/session.rs @@ -13,11 +13,11 @@ use common::{ use tokio_rustls::server::TlsStream; use crate::{ + Pop3SessionManager, SERVER_GREETING, Session, State, protocol::{ request::Parser, response::{Response, SerializeResponse}, }, - Pop3SessionManager, Session, State, SERVER_GREETING, }; use tokio::io::{AsyncReadExt, AsyncWriteExt}; diff --git a/crates/services/src/gossip/heartbeat.rs b/crates/services/src/gossip/heartbeat.rs index 10132e1f..01772908 100644 --- a/crates/services/src/gossip/heartbeat.rs +++ b/crates/services/src/gossip/heartbeat.rs @@ -6,7 +6,7 @@ use trc::ClusterEvent; -use super::{Peer, State, HEARTBEAT_WINDOW, HEARTBEAT_WINDOW_MASK}; +use super::{HEARTBEAT_WINDOW, HEARTBEAT_WINDOW_MASK, Peer, State}; use std::time::Instant; // Phi Accrual Failure Detector defaults diff --git a/crates/services/src/gossip/peer.rs b/crates/services/src/gossip/peer.rs index 65203e12..66dd41af 100644 --- a/crates/services/src/gossip/peer.rs +++ b/crates/services/src/gossip/peer.rs @@ -6,7 +6,7 @@ use std::{fmt::Display, net::IpAddr, time::Instant}; -use super::{Gossiper, Peer, PeerStatus, State, HEARTBEAT_WINDOW}; +use super::{Gossiper, HEARTBEAT_WINDOW, Peer, PeerStatus, State}; impl Peer { pub fn new_seed(addr: IpAddr) -> Self { diff --git a/crates/services/src/gossip/ping.rs b/crates/services/src/gossip/ping.rs index 419f67cb..5764f7bc 100644 --- a/crates/services/src/gossip/ping.rs +++ b/crates/services/src/gossip/ping.rs @@ -10,7 +10,7 @@ use common::{ }; use trc::ClusterEvent; -use super::{request::Request, Gossiper, PeerStatus}; +use super::{Gossiper, PeerStatus, request::Request}; impl Gossiper { pub async fn ping_peers(&mut self) { @@ -194,9 +194,10 @@ impl Gossiper { } } Err(err) => { - trc::error!(err - .details("Failed to reload settings") - .caused_by(trc::location!())); + trc::error!( + err.details("Failed to reload settings") + .caused_by(trc::location!()) + ); } } }); diff --git a/crates/services/src/gossip/spawn.rs b/crates/services/src/gossip/spawn.rs index 15a1f9a8..cbc2eac1 100644 --- a/crates/services/src/gossip/spawn.rs +++ b/crates/services/src/gossip/spawn.rs @@ -7,7 +7,7 @@ use super::request::Request; use super::{Gossiper, Peer, UDP_MAX_PAYLOAD}; use common::auth::oauth::crypto::SymmetricEncrypt; -use common::{Inner, IPC_CHANNEL_BUFFER}; +use common::{IPC_CHANNEL_BUFFER, Inner}; use std::net::IpAddr; use std::time::{Duration, Instant}; use std::{net::SocketAddr, sync::Arc}; diff --git a/crates/smtp/src/core/throttle.rs b/crates/smtp/src/core/throttle.rs index 0dea9808..21ac1515 100644 --- a/crates/smtp/src/core/throttle.rs +++ b/crates/smtp/src/core/throttle.rs @@ -5,10 +5,10 @@ */ use common::{ + KV_RATE_LIMIT_SMTP, ThrottleKey, config::smtp::*, expr::{functions::ResolveVariable, *}, listener::SessionStream, - ThrottleKey, KV_RATE_LIMIT_SMTP, }; use queue::QueueQuota; use trc::SmtpEvent; @@ -196,9 +196,10 @@ impl Session { return false; } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!())); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + ); } _ => (), } @@ -231,9 +232,10 @@ impl Session { Ok(None) => true, Ok(Some(_)) => false, Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!())); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + ); true } } diff --git a/crates/smtp/src/inbound/auth.rs b/crates/smtp/src/inbound/auth.rs index 343afccc..8b4409ae 100644 --- a/crates/smtp/src/inbound/auth.rs +++ b/crates/smtp/src/inbound/auth.rs @@ -6,17 +6,17 @@ use common::{ auth::{ + AuthRequest, sasl::{ sasl_decode_challenge_oauth, sasl_decode_challenge_plain, sasl_decode_challenge_xoauth, }, - AuthRequest, }, listener::SessionStream, }; use directory::Permission; use mail_parser::decoders::base64::base64_decode; use mail_send::Credentials; -use smtp_proto::{IntoString, AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2}; +use smtp_proto::{AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2, IntoString}; use trc::{AuthEvent, SmtpEvent}; use crate::core::Session; diff --git a/crates/smtp/src/inbound/ehlo.rs b/crates/smtp/src/inbound/ehlo.rs index 91a674c6..c24ef63a 100644 --- a/crates/smtp/src/inbound/ehlo.rs +++ b/crates/smtp/src/inbound/ehlo.rs @@ -12,8 +12,8 @@ use common::{ listener::SessionStream, }; use mail_auth::{ - spf::verify::{HasValidLabels, SpfParameters}, SpfResult, + spf::verify::{HasValidLabels, SpfParameters}, }; use smtp_proto::*; use trc::SmtpEvent; diff --git a/crates/smtp/src/inbound/hooks/message.rs b/crates/smtp/src/inbound/hooks/message.rs index 8b8c06c9..2f03eee7 100644 --- a/crates/smtp/src/inbound/hooks/message.rs +++ b/crates/smtp/src/inbound/hooks/message.rs @@ -8,9 +8,9 @@ use std::time::Instant; use ahash::AHashMap; use common::{ + DAEMON_NAME, config::smtp::session::{MTAHook, Stage}, listener::SessionStream, - DAEMON_NAME, }; use mail_auth::AuthenticatedMessage; use trc::MtaHookEvent; @@ -18,16 +18,16 @@ use trc::MtaHookEvent; use crate::{ core::Session, inbound::{ + FilterResponse, hooks::{ Address, Client, Context, Envelope, Message, Protocol, Request, Sasl, Server, Tls, }, milter::Modification, - FilterResponse, }, queue::QueueId, }; -use super::{client::send_mta_hook_request, Action, Queue, Response}; +use super::{Action, Queue, Response, client::send_mta_hook_request}; impl Session { pub async fn run_mta_hooks( diff --git a/crates/smtp/src/inbound/milter/client.rs b/crates/smtp/src/inbound/milter/client.rs index 1e641a29..57e1c8e9 100644 --- a/crates/smtp/src/inbound/milter/client.rs +++ b/crates/smtp/src/inbound/milter/client.rs @@ -10,7 +10,7 @@ use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, net::TcpStream, }; -use tokio_rustls::{client::TlsStream, TlsConnector}; +use tokio_rustls::{TlsConnector, client::TlsStream}; use trc::MilterEvent; use super::{ diff --git a/crates/smtp/src/inbound/milter/message.rs b/crates/smtp/src/inbound/milter/message.rs index 5eebaf6c..64f08a1e 100644 --- a/crates/smtp/src/inbound/milter/message.rs +++ b/crates/smtp/src/inbound/milter/message.rs @@ -7,18 +7,18 @@ use std::{borrow::Cow, time::Instant}; use common::{ + DAEMON_NAME, config::smtp::session::{Milter, Stage}, listener::SessionStream, - DAEMON_NAME, }; use mail_auth::AuthenticatedMessage; -use smtp_proto::{request::parser::Rfc5321Parser, IntoString}; +use smtp_proto::{IntoString, request::parser::Rfc5321Parser}; use tokio::io::{AsyncRead, AsyncWrite}; use trc::MilterEvent; use crate::{ core::{Session, SessionAddress, SessionData}, - inbound::{milter::MilterClient, FilterResponse}, + inbound::{FilterResponse, milter::MilterClient}, queue::DomainPart, }; diff --git a/crates/smtp/src/inbound/mod.rs b/crates/smtp/src/inbound/mod.rs index cdf9762b..3cc1b0c9 100644 --- a/crates/smtp/src/inbound/mod.rs +++ b/crates/smtp/src/inbound/mod.rs @@ -8,8 +8,8 @@ use std::borrow::Cow; use common::config::smtp::auth::{ArcSealer, DkimSigner}; use mail_auth::{ - arc::ArcSet, dkim::Signature, dmarc::Policy, ArcOutput, AuthenticatedMessage, - AuthenticationResults, DkimResult, DmarcResult, IprevResult, SpfResult, + ArcOutput, AuthenticatedMessage, AuthenticationResults, DkimResult, DmarcResult, IprevResult, + SpfResult, arc::ArcSet, dkim::Signature, dmarc::Policy, }; pub mod auth; diff --git a/crates/smtp/src/inbound/rcpt.rs b/crates/smtp/src/inbound/rcpt.rs index 17978d13..6cd1e60a 100644 --- a/crates/smtp/src/inbound/rcpt.rs +++ b/crates/smtp/src/inbound/rcpt.rs @@ -5,11 +5,11 @@ */ use common::{ - config::smtp::session::Stage, listener::SessionStream, scripts::ScriptModification, KV_GREYLIST, + KV_GREYLIST, config::smtp::session::Stage, listener::SessionStream, scripts::ScriptModification, }; use directory::backend::RcptType; use smtp_proto::{ - RcptTo, RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_NEVER, RCPT_NOTIFY_SUCCESS, + RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_NEVER, RCPT_NOTIFY_SUCCESS, RcptTo, }; use store::dispatch::lookup::KeyValue; use trc::{SecurityEvent, SmtpEvent}; @@ -231,10 +231,11 @@ impl Session { .await; } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!()) - .details("Failed to verify address.")); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + .details("Failed to verify address.") + ); self.data.rcpt_to.pop(); return self @@ -267,10 +268,11 @@ impl Session { } } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!()) - .details("Failed to verify address.")); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + .details("Failed to verify address.") + ); self.data.rcpt_to.pop(); return self @@ -352,18 +354,20 @@ impl Session { .await; } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!()) - .details("Failed to set greylist.")); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + .details("Failed to set greylist.") + ); } } } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!()) - .details("Failed to check greylist.")); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + .details("Failed to check greylist.") + ); } } } @@ -435,10 +439,11 @@ impl Session { } } Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .caused_by(trc::location!()) - .details("Failed to check if IP should be banned.")); + trc::error!( + err.span_id(self.data.session_id) + .caused_by(trc::location!()) + .details("Failed to check if IP should be banned.") + ); } } diff --git a/crates/smtp/src/inbound/session.rs b/crates/smtp/src/inbound/session.rs index 9099a0db..a6ae4f4d 100644 --- a/crates/smtp/src/inbound/session.rs +++ b/crates/smtp/src/inbound/session.rs @@ -255,9 +255,10 @@ impl Session { } Ok(false) => {} Err(err) => { - trc::error!(err - .span_id(self.data.session_id) - .details("Failed to check for fail2ban")); + trc::error!( + err.span_id(self.data.session_id) + .details("Failed to check for fail2ban") + ); } } } diff --git a/crates/smtp/src/inbound/spam.rs b/crates/smtp/src/inbound/spam.rs index 66e8312b..81080108 100644 --- a/crates/smtp/src/inbound/spam.rs +++ b/crates/smtp/src/inbound/spam.rs @@ -5,14 +5,14 @@ */ use common::{config::spamfilter::SpamFilterAction, listener::SessionStream}; -use mail_auth::{dmarc::Policy, ArcOutput, DkimOutput, DmarcResult}; +use mail_auth::{ArcOutput, DkimOutput, DmarcResult, dmarc::Policy}; use mail_parser::Message; use spam_filter::{ + SpamFilterInput, analysis::{ init::SpamFilterInit, score::SpamFilterAnalyzeScore, trusted_reply::SpamFilterAnalyzeTrustedReply, }, - SpamFilterInput, }; use crate::core::Session; diff --git a/crates/smtp/src/lib.rs b/crates/smtp/src/lib.rs index 0713f9bb..e98fa060 100644 --- a/crates/smtp/src/lib.rs +++ b/crates/smtp/src/lib.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use common::{ - manager::boot::{BootManager, IpcReceivers}, Inner, + manager::boot::{BootManager, IpcReceivers}, }; use queue::manager::SpawnQueue; use reporting::scheduler::SpawnReport; diff --git a/crates/smtp/src/outbound/client.rs b/crates/smtp/src/outbound/client.rs index d615a06c..af4dbad4 100644 --- a/crates/smtp/src/outbound/client.rs +++ b/crates/smtp/src/outbound/client.rs @@ -9,22 +9,22 @@ use std::{ time::Duration, }; -use mail_send::{smtp::AssertReply, Credentials}; +use mail_send::{Credentials, smtp::AssertReply}; use rustls::ClientConnection; use rustls_pki_types::ServerName; use smtp_proto::{ + AUTH_CRAM_MD5, AUTH_DIGEST_MD5, AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2, + EXT_START_TLS, EhloResponse, Response, response::{ generate::BitToString, - parser::{ResponseReceiver, MAX_RESPONSE_LENGTH}, + parser::{MAX_RESPONSE_LENGTH, ResponseReceiver}, }, - EhloResponse, Response, AUTH_CRAM_MD5, AUTH_DIGEST_MD5, AUTH_LOGIN, AUTH_OAUTHBEARER, - AUTH_PLAIN, AUTH_XOAUTH2, EXT_START_TLS, }; use tokio::{ io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, net::{TcpSocket, TcpStream}, }; -use tokio_rustls::{client::TlsStream, TlsConnector}; +use tokio_rustls::{TlsConnector, client::TlsStream}; use trc::DeliveryEvent; use crate::queue::{Error, Message, Status}; @@ -225,10 +225,11 @@ impl SmtpClient { ))) } Err(err) => { - trc::error!(err - .span_id(message.span_id) - .details("Failed to fetch blobId") - .caused_by(trc::location!())); + trc::error!( + err.span_id(message.span_id) + .details("Failed to fetch blobId") + .caused_by(trc::location!()) + ); Err(Status::TemporaryFailure(Error::Io( "Queue system error.".to_string(), diff --git a/crates/smtp/src/outbound/dane/dnssec.rs b/crates/smtp/src/outbound/dane/dnssec.rs index 6ec1cf70..da10231f 100644 --- a/crates/smtp/src/outbound/dane/dnssec.rs +++ b/crates/smtp/src/outbound/dane/dnssec.rs @@ -5,18 +5,18 @@ */ use common::{ - config::smtp::resolver::{Tlsa, TlsaEntry}, Server, + config::smtp::resolver::{Tlsa, TlsaEntry}, }; use mail_auth::{ common::resolver::IntoFqdn, hickory_resolver::{ + Name, error::ResolveErrorKind, proto::{ error::ProtoErrorKind, rr::rdata::tlsa::{CertUsage, Matching, Selector}, }, - Name, }, }; use std::{future::Future, sync::Arc}; diff --git a/crates/smtp/src/outbound/mta_sts/lookup.rs b/crates/smtp/src/outbound/mta_sts/lookup.rs index 03c5d251..c8b279c2 100644 --- a/crates/smtp/src/outbound/mta_sts/lookup.rs +++ b/crates/smtp/src/outbound/mta_sts/lookup.rs @@ -9,10 +9,10 @@ use std::{fmt::Display, sync::Arc, time::Duration}; #[cfg(feature = "test_mode")] pub static STS_TEST_POLICY: parking_lot::Mutex> = parking_lot::Mutex::new(Vec::new()); -use common::{config::smtp::resolver::Policy, Server}; +use common::{Server, config::smtp::resolver::Policy}; use mail_auth::{mta_sts::MtaSts, report::tlsrpt::ResultType}; -use super::{parse::ParsePolicy, Error}; +use super::{Error, parse::ParsePolicy}; #[cfg(not(feature = "test_mode"))] use utils::HttpLimitResponse; diff --git a/crates/smtp/src/outbound/session.rs b/crates/smtp/src/outbound/session.rs index 41bf98b6..d8b3a02c 100644 --- a/crates/smtp/src/outbound/session.rs +++ b/crates/smtp/src/outbound/session.rs @@ -4,13 +4,13 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::config::smtp::queue::RequireOptional; use common::Server; +use common::config::smtp::queue::RequireOptional; use mail_send::Credentials; use smtp_proto::{ - EhloResponse, Severity, EXT_CHUNKING, EXT_DSN, EXT_REQUIRE_TLS, EXT_SIZE, EXT_SMTP_UTF8, - MAIL_REQUIRETLS, MAIL_RET_FULL, MAIL_RET_HDRS, MAIL_SMTPUTF8, RCPT_NOTIFY_DELAY, - RCPT_NOTIFY_FAILURE, RCPT_NOTIFY_NEVER, RCPT_NOTIFY_SUCCESS, + EXT_CHUNKING, EXT_DSN, EXT_REQUIRE_TLS, EXT_SIZE, EXT_SMTP_UTF8, EhloResponse, MAIL_REQUIRETLS, + MAIL_RET_FULL, MAIL_RET_HDRS, MAIL_SMTPUTF8, RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, + RCPT_NOTIFY_NEVER, RCPT_NOTIFY_SUCCESS, Severity, }; use std::time::Duration; use std::{fmt::Write, time::Instant}; @@ -22,7 +22,7 @@ use crate::queue::{ErrorDetails, HostResponse, RCPT_STATUS_CHANGED}; use crate::queue::{Error, Message, Recipient, Status}; -use super::{client::SmtpClient, TlsStrategy}; +use super::{TlsStrategy, client::SmtpClient}; pub struct SessionParams<'x> { pub server: &'x Server, diff --git a/crates/smtp/src/queue/throttle.rs b/crates/smtp/src/queue/throttle.rs index 9a4dba30..26cd7fc9 100644 --- a/crates/smtp/src/queue/throttle.rs +++ b/crates/smtp/src/queue/throttle.rs @@ -7,7 +7,7 @@ use std::future::Future; use common::{ - config::smtp::QueueRateLimiter, expr::functions::ResolveVariable, Server, KV_RATE_LIMIT_SMTP, + KV_RATE_LIMIT_SMTP, Server, config::smtp::QueueRateLimiter, expr::functions::ResolveVariable, }; use store::write::now; diff --git a/crates/smtp/src/reporting/dkim.rs b/crates/smtp/src/reporting/dkim.rs index f0b4d682..4aa2489c 100644 --- a/crates/smtp/src/reporting/dkim.rs +++ b/crates/smtp/src/reporting/dkim.rs @@ -6,7 +6,7 @@ use common::listener::SessionStream; use mail_auth::{ - common::verify::VerifySignature, AuthenticatedMessage, AuthenticationResults, DkimOutput, + AuthenticatedMessage, AuthenticationResults, DkimOutput, common::verify::VerifySignature, }; use trc::OutgoingReportEvent; use utils::config::Rate; diff --git a/crates/smtp/src/reporting/mod.rs b/crates/smtp/src/reporting/mod.rs index 4160286d..ddaa79eb 100644 --- a/crates/smtp/src/reporting/mod.rs +++ b/crates/smtp/src/reporting/mod.rs @@ -7,10 +7,10 @@ use std::{future::Future, io, time::SystemTime}; use common::{ + Server, USER_AGENT, config::smtp::report::{AddressMatch, AggregateFrequency}, expr::if_block::IfBlock, ipc::ReportingEvent, - Server, USER_AGENT, }; use mail_auth::{ common::headers::HeaderWriter, @@ -18,13 +18,13 @@ use mail_auth::{ }; use mail_parser::DateTime; -use store::write::{key::KeySerializer, ReportEvent}; +use store::write::{ReportEvent, key::KeySerializer}; use tokio::io::{AsyncRead, AsyncWrite}; use crate::{ core::Session, inbound::DkimSign, - queue::{spool::SmtpSpool, DomainPart, Message, MessageSource}, + queue::{DomainPart, Message, MessageSource, spool::SmtpSpool}, }; pub mod analysis; @@ -58,10 +58,10 @@ impl Session { for addr in &self.data.rcpt_to { match addr_match { AddressMatch::StartsWith(prefix) if addr.address_lcase.starts_with(prefix) => { - return true + return true; } AddressMatch::EndsWith(suffix) if addr.address_lcase.ends_with(suffix) => { - return true + return true; } AddressMatch::Equals(value) if addr.address_lcase.eq(value) => return true, _ => (), @@ -230,10 +230,12 @@ impl SmtpReporting for Server { signature.write_header(&mut headers); } Err(err) => { - trc::error!(trc::Error::from(err) - .span_id(message.span_id) - .details("Failed to sign message") - .caused_by(trc::location!())); + trc::error!( + trc::Error::from(err) + .span_id(message.span_id) + .details("Failed to sign message") + .caused_by(trc::location!()) + ); } } } diff --git a/crates/smtp/src/reporting/scheduler.rs b/crates/smtp/src/reporting/scheduler.rs index 3ecfec47..dd474b36 100644 --- a/crates/smtp/src/reporting/scheduler.rs +++ b/crates/smtp/src/reporting/scheduler.rs @@ -5,7 +5,7 @@ */ use ahash::AHashMap; -use common::{core::BuildServer, ipc::ReportingEvent, Inner, Server, KV_LOCK_QUEUE_REPORT}; +use common::{Inner, KV_LOCK_QUEUE_REPORT, Server, core::BuildServer, ipc::ReportingEvent}; use std::{ future::Future, @@ -13,14 +13,14 @@ use std::{ time::{Duration, SystemTime}, }; use store::{ - write::{now, BatchBuilder, QueueClass, ReportEvent, ValueClass}, Deserialize, IterateParams, Store, ValueKey, + write::{BatchBuilder, QueueClass, ReportEvent, ValueClass, now}, }; use tokio::sync::mpsc; use crate::queue::spool::LOCK_EXPIRY; -use super::{dmarc::DmarcReporting, tls::TlsReporting, AggregateTimestamp, ReportLock}; +use super::{AggregateTimestamp, ReportLock, dmarc::DmarcReporting, tls::TlsReporting}; pub const REPORT_REFRESH: Duration = Duration::from_secs(86400); @@ -171,16 +171,18 @@ async fn next_report_event(store: &Store) -> Vec { batch.clear(ValueClass::Queue(event)); } if let Err(err) = store.write(batch.build()).await { - trc::error!(err - .caused_by(trc::location!()) - .details("Failed to remove old report events")); + trc::error!( + err.caused_by(trc::location!()) + .details("Failed to remove old report events") + ); } } if let Err(err) = result { - trc::error!(err - .caused_by(trc::location!()) - .details("Failed to read from store")); + trc::error!( + err.caused_by(trc::location!()) + .details("Failed to read from store") + ); } events @@ -210,9 +212,10 @@ impl LockReport for Server { result } Err(err) => { - trc::error!(err - .details("Failed to lock report.") - .caused_by(trc::location!())); + trc::error!( + err.details("Failed to lock report.") + .caused_by(trc::location!()) + ); false } } @@ -224,9 +227,10 @@ impl LockReport for Server { .remove_lock(KV_LOCK_QUEUE_REPORT, key) .await { - trc::error!(err - .details("Failed to unlock event.") - .caused_by(trc::location!())); + trc::error!( + err.details("Failed to unlock event.") + .caused_by(trc::location!()) + ); } } } diff --git a/crates/smtp/src/reporting/spf.rs b/crates/smtp/src/reporting/spf.rs index 8b7c82b7..c152586d 100644 --- a/crates/smtp/src/reporting/spf.rs +++ b/crates/smtp/src/reporting/spf.rs @@ -5,7 +5,7 @@ */ use common::listener::SessionStream; -use mail_auth::{report::AuthFailureType, AuthenticationResults, SpfOutput}; +use mail_auth::{AuthenticationResults, SpfOutput, report::AuthFailureType}; use trc::OutgoingReportEvent; use utils::config::Rate; diff --git a/crates/smtp/src/scripts/event_loop.rs b/crates/smtp/src/scripts/event_loop.rs index bd2c856b..b14e6aa6 100644 --- a/crates/smtp/src/scripts/event_loop.rs +++ b/crates/smtp/src/scripts/event_loop.rs @@ -6,12 +6,12 @@ use std::{borrow::Cow, future::Future, sync::Arc, time::Instant}; -use common::{scripts::plugins::PluginContext, Server}; +use common::{Server, scripts::plugins::PluginContext}; use mail_auth::common::headers::HeaderWriter; use mail_parser::{Encoding, Message, MessagePart, PartType}; use sieve::{ - compiler::grammar::actions::action_redirect::{ByMode, ByTime, Notify, NotifyItem, Ret}, Event, Input, MatchAs, Recipient, Sieve, + compiler::grammar::actions::action_redirect::{ByMode, ByTime, Notify, NotifyItem, Ret}, }; use smtp_proto::{ MAIL_BY_TRACE, MAIL_RET_FULL, MAIL_RET_HDRS, RCPT_NOTIFY_DELAY, RCPT_NOTIFY_FAILURE, @@ -21,7 +21,7 @@ use trc::SieveEvent; use crate::{ inbound::DkimSign, - queue::{quota::HasQueueQuota, spool::SmtpSpool, DomainPart, MessageSource}, + queue::{DomainPart, MessageSource, quota::HasQueueQuota, spool::SmtpSpool}, }; use super::{ScriptModification, ScriptParameters, ScriptResult}; @@ -289,10 +289,12 @@ impl RunScript for Server { signature.write_header(&mut headers); } Err(err) => { - trc::error!(trc::Error::from(err) - .span_id(session_id) - .caused_by(trc::location!()) - .details("DKIM sign failed")); + trc::error!( + trc::Error::from(err) + .span_id(session_id) + .caused_by(trc::location!()) + .details("DKIM sign failed") + ); } } } diff --git a/crates/smtp/src/scripts/exec.rs b/crates/smtp/src/scripts/exec.rs index 9e679939..cf60f716 100644 --- a/crates/smtp/src/scripts/exec.rs +++ b/crates/smtp/src/scripts/exec.rs @@ -8,12 +8,12 @@ use std::{sync::Arc, time::SystemTime}; use common::listener::SessionStream; use mail_auth::common::resolver::ToReverseName; -use sieve::{runtime::Variable, Envelope, Sieve}; +use sieve::{Envelope, Sieve, runtime::Variable}; use smtp_proto::*; use crate::{core::Session, inbound::AuthResult}; -use super::{event_loop::RunScript, ScriptParameters, ScriptResult}; +use super::{ScriptParameters, ScriptResult, event_loop::RunScript}; impl Session { pub fn build_script_parameters(&self, stage: &'static str) -> ScriptParameters<'_> { diff --git a/crates/smtp/src/scripts/mod.rs b/crates/smtp/src/scripts/mod.rs index 543d6116..1d17f4a0 100644 --- a/crates/smtp/src/scripts/mod.rs +++ b/crates/smtp/src/scripts/mod.rs @@ -8,10 +8,10 @@ use std::borrow::Cow; use ahash::AHashMap; use common::{ - auth::AccessToken, expr::functions::ResolveVariable, scripts::ScriptModification, Server, + Server, auth::AccessToken, expr::functions::ResolveVariable, scripts::ScriptModification, }; use mail_parser::Message; -use sieve::{runtime::Variable, Envelope}; +use sieve::{Envelope, runtime::Variable}; pub mod envelope; pub mod event_loop; diff --git a/crates/spam-filter/src/analysis/bayes.rs b/crates/spam-filter/src/analysis/bayes.rs index a2a82798..cf856d7a 100644 --- a/crates/spam-filter/src/analysis/bayes.rs +++ b/crates/spam-filter/src/analysis/bayes.rs @@ -8,7 +8,7 @@ use std::future::Future; use common::Server; -use crate::{modules::bayes::BayesClassifier, SpamFilterContext}; +use crate::{SpamFilterContext, modules::bayes::BayesClassifier}; pub trait SpamFilterAnalyzeBayes: Sync + Send { fn spam_filter_analyze_bayes_classify( diff --git a/crates/spam-filter/src/analysis/dmarc.rs b/crates/spam-filter/src/analysis/dmarc.rs index 0b54b3cb..82adce98 100644 --- a/crates/spam-filter/src/analysis/dmarc.rs +++ b/crates/spam-filter/src/analysis/dmarc.rs @@ -7,7 +7,7 @@ use std::future::Future; use common::Server; -use mail_auth::{dmarc::Policy, DkimResult, DmarcResult, SpfResult}; +use mail_auth::{DkimResult, DmarcResult, SpfResult, dmarc::Policy}; use crate::SpamFilterContext; diff --git a/crates/spam-filter/src/analysis/domain.rs b/crates/spam-filter/src/analysis/domain.rs index eae40eea..11b3b827 100644 --- a/crates/spam-filter/src/analysis/domain.rs +++ b/crates/spam-filter/src/analysis/domain.rs @@ -7,23 +7,23 @@ use std::{collections::HashSet, future::Future}; use common::{ - config::spamfilter::{Element, Location}, Server, + config::spamfilter::{Element, Location}, }; use mail_auth::DkimResult; -use mail_parser::{parsers::MessageStream, HeaderName, HeaderValue, Host}; +use mail_parser::{HeaderName, HeaderValue, Host, parsers::MessageStream}; use nlp::tokenizers::types::TokenType; use crate::{ + Email, Hostname, Recipient, SpamFilterContext, TextPart, modules::{ dnsbl::check_dnsbl, expression::StringResolver, - html::{HtmlToken, A, HREF}, + html::{A, HREF, HtmlToken}, }, - Email, Hostname, Recipient, SpamFilterContext, TextPart, }; -use super::{is_trusted_domain, ElementLocation}; +use super::{ElementLocation, is_trusted_domain}; pub trait SpamFilterAnalyzeDomain: Sync + Send { fn spam_filter_analyze_domain( @@ -72,11 +72,7 @@ impl SpamFilterAnalyzeDomain for Server { .and_then(|s| s.rsplit_once('@')) .and_then(|(_, d)| { let host = Hostname::new(d); - if host.sld.is_some() { - Some(host) - } else { - None - } + if host.sld.is_some() { Some(host) } else { None } }) { domains.insert(ElementLocation::new(mid_domain.fqdn, Location::HeaderMid)); diff --git a/crates/spam-filter/src/analysis/html.rs b/crates/spam-filter/src/analysis/html.rs index 54576966..4104d2c1 100644 --- a/crates/spam-filter/src/analysis/html.rs +++ b/crates/spam-filter/src/analysis/html.rs @@ -11,7 +11,7 @@ use hyper::Uri; use mail_parser::MimeHeaders; use nlp::tokenizers::types::{TokenType, TypesTokenizer}; -use crate::{modules::html::*, Hostname, SpamFilterContext, TextPart}; +use crate::{Hostname, SpamFilterContext, TextPart, modules::html::*}; pub trait SpamFilterAnalyzeHtml: Sync + Send { fn spam_filter_analyze_html( diff --git a/crates/spam-filter/src/analysis/init.rs b/crates/spam-filter/src/analysis/init.rs index f51229ba..34965d26 100644 --- a/crates/spam-filter/src/analysis/init.rs +++ b/crates/spam-filter/src/analysis/init.rs @@ -5,13 +5,13 @@ */ use common::Server; -use mail_parser::{parsers::fields::thread::thread_name, HeaderName, PartType}; +use mail_parser::{HeaderName, PartType, parsers::fields::thread::thread_name}; use nlp::tokenizers::types::{TokenType, TypesTokenizer}; use crate::{ - modules::html::{html_to_tokens, HtmlToken, HEAD}, Email, Hostname, IpParts, Recipient, SpamFilterContext, SpamFilterInput, SpamFilterOutput, SpamFilterResult, TextPart, + modules::html::{HEAD, HtmlToken, html_to_tokens}, }; use super::url::UrlParts; diff --git a/crates/spam-filter/src/analysis/ip.rs b/crates/spam-filter/src/analysis/ip.rs index 291d6a30..6ec7c678 100644 --- a/crates/spam-filter/src/analysis/ip.rs +++ b/crates/spam-filter/src/analysis/ip.rs @@ -7,15 +7,15 @@ use std::{borrow::Cow, future::Future}; use common::{ - config::spamfilter::{Element, IpResolver, Location}, Server, + config::spamfilter::{Element, IpResolver, Location}, }; use mail_auth::IprevResult; use mail_parser::{HeaderName, HeaderValue, Host}; use nlp::tokenizers::types::TokenType; use store::ahash::AHashSet; -use crate::{modules::dnsbl::check_dnsbl, IpParts, SpamFilterContext, TextPart}; +use crate::{IpParts, SpamFilterContext, TextPart, modules::dnsbl::check_dnsbl}; use super::ElementLocation; diff --git a/crates/spam-filter/src/analysis/mod.rs b/crates/spam-filter/src/analysis/mod.rs index 08750158..9dcff6e0 100644 --- a/crates/spam-filter/src/analysis/mod.rs +++ b/crates/spam-filter/src/analysis/mod.rs @@ -9,8 +9,8 @@ use std::{ hash::{Hash, Hasher}, }; -use common::{config::spamfilter::Location, Server}; -use mail_parser::{parsers::MessageStream, Header}; +use common::{Server, config::spamfilter::Location}; +use mail_parser::{Header, parsers::MessageStream}; use crate::{ Recipient, SpamFilterContext, SpamFilterInput, SpamFilterOutput, SpamFilterResult, TextPart, diff --git a/crates/spam-filter/src/analysis/pyzor.rs b/crates/spam-filter/src/analysis/pyzor.rs index f9f756ad..81745c29 100644 --- a/crates/spam-filter/src/analysis/pyzor.rs +++ b/crates/spam-filter/src/analysis/pyzor.rs @@ -8,7 +8,7 @@ use std::{future::Future, time::Instant}; use common::Server; -use crate::{modules::pyzor::pyzor_check, SpamFilterContext}; +use crate::{SpamFilterContext, modules::pyzor::pyzor_check}; pub trait SpamFilterAnalyzePyzor: Sync + Send { fn spam_filter_analyze_pyzor( @@ -44,9 +44,10 @@ impl SpamFilterAnalyzePyzor for Server { } Ok(None) => {} Err(err) => { - trc::error!(err - .span_id(ctx.input.span_id) - .ctx(trc::Key::Elapsed, time.elapsed())); + trc::error!( + err.span_id(ctx.input.span_id) + .ctx(trc::Key::Elapsed, time.elapsed()) + ); } } } diff --git a/crates/spam-filter/src/analysis/rules.rs b/crates/spam-filter/src/analysis/rules.rs index 0c59278e..e80478a3 100644 --- a/crates/spam-filter/src/analysis/rules.rs +++ b/crates/spam-filter/src/analysis/rules.rs @@ -7,13 +7,13 @@ use std::future::Future; use common::{ - config::spamfilter::{IpResolver, Location}, Server, + config::spamfilter::{IpResolver, Location}, }; use crate::{ - modules::expression::{EmailHeader, SpamFilterResolver, StringResolver}, SpamFilterContext, TextPart, + modules::expression::{EmailHeader, SpamFilterResolver, StringResolver}, }; pub trait SpamFilterAnalyzeRules: Sync + Send { diff --git a/crates/spam-filter/src/analysis/score.rs b/crates/spam-filter/src/analysis/score.rs index f7daca69..30c88630 100644 --- a/crates/spam-filter/src/analysis/score.rs +++ b/crates/spam-filter/src/analysis/score.rs @@ -4,10 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use common::{config::spamfilter::SpamFilterAction, Server}; +use common::{Server, config::spamfilter::SpamFilterAction}; use std::{fmt::Write, future::Future, vec}; use crate::{ + SpamFilterContext, analysis::{ bayes::SpamFilterAnalyzeBayes, date::SpamFilterAnalyzeDate, dmarc::SpamFilterAnalyzeDmarc, domain::SpamFilterAnalyzeDomain, ehlo::SpamFilterAnalyzeEhlo, from::SpamFilterAnalyzeFrom, @@ -20,7 +21,6 @@ use crate::{ url::SpamFilterAnalyzeUrl, }, modules::bayes::BayesClassifier, - SpamFilterContext, }; #[cfg(feature = "enterprise")] diff --git a/crates/spam-filter/src/analysis/trusted_reply.rs b/crates/spam-filter/src/analysis/trusted_reply.rs index 41eca22c..8cabb194 100644 --- a/crates/spam-filter/src/analysis/trusted_reply.rs +++ b/crates/spam-filter/src/analysis/trusted_reply.rs @@ -6,11 +6,11 @@ use std::future::Future; -use common::{Server, KV_TRUSTED_REPLY}; +use common::{KV_TRUSTED_REPLY, Server}; use mail_parser::{HeaderName, HeaderValue}; use store::dispatch::lookup::KeyValue; -use crate::{modules::bayes::BayesClassifier, SpamFilterContext}; +use crate::{SpamFilterContext, modules::bayes::BayesClassifier}; pub trait SpamFilterAnalyzeTrustedReply: Sync + Send { fn spam_filter_analyze_reply_in( @@ -48,9 +48,9 @@ impl SpamFilterAnalyzeTrustedReply for Server { return; } Err(err) => { - trc::error!(err - .span_id(ctx.input.span_id) - .caused_by(trc::location!())); + trc::error!( + err.span_id(ctx.input.span_id).caused_by(trc::location!()) + ); } _ => {} } diff --git a/crates/spam-filter/src/analysis/url.rs b/crates/spam-filter/src/analysis/url.rs index c3d5f828..a9636e34 100644 --- a/crates/spam-filter/src/analysis/url.rs +++ b/crates/spam-filter/src/analysis/url.rs @@ -8,11 +8,11 @@ use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::{borrow::Cow, future::Future, time::Duration}; -use common::config::spamfilter::{Element, IpResolver, Location}; -use common::scripts::functions::unicode::CharUtils; -use common::scripts::IsMixedCharset; use common::Server; -use hyper::{header::LOCATION, Uri}; +use common::config::spamfilter::{Element, IpResolver, Location}; +use common::scripts::IsMixedCharset; +use common::scripts::functions::unicode::CharUtils; +use hyper::{Uri, header::LOCATION}; use nlp::tokenizers::types::TokenType; use reqwest::redirect::Policy; @@ -20,11 +20,11 @@ use crate::modules::dnsbl::check_dnsbl; use crate::modules::expression::StringResolver; use crate::modules::html::SRC; use crate::{ - modules::html::{HtmlToken, A, HREF}, Hostname, SpamFilterContext, TextPart, + modules::html::{A, HREF, HtmlToken}, }; -use super::{is_trusted_domain, is_url_redirector, ElementLocation}; +use super::{ElementLocation, is_trusted_domain, is_url_redirector}; pub trait SpamFilterAnalyzeUrl: Sync + Send { fn spam_filter_analyze_url( diff --git a/crates/spam-filter/src/lib.rs b/crates/spam-filter/src/lib.rs index 79552c48..62b30caa 100644 --- a/crates/spam-filter/src/lib.rs +++ b/crates/spam-filter/src/lib.rs @@ -12,9 +12,9 @@ use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::net::{IpAddr, Ipv4Addr}; -use analysis::url::UrlParts; use analysis::ElementLocation; -use mail_auth::{dmarc::Policy, ArcOutput, DkimOutput, DmarcResult, IprevOutput, SpfOutput}; +use analysis::url::UrlParts; +use mail_auth::{ArcOutput, DkimOutput, DmarcResult, IprevOutput, SpfOutput, dmarc::Policy}; use mail_parser::Message; use modules::html::HtmlToken; use nlp::tokenizers::types::TokenType; diff --git a/crates/spam-filter/src/modules/dnsbl.rs b/crates/spam-filter/src/modules/dnsbl.rs index 4412a284..b7da585e 100644 --- a/crates/spam-filter/src/modules/dnsbl.rs +++ b/crates/spam-filter/src/modules/dnsbl.rs @@ -11,11 +11,11 @@ use std::{ }; use common::{ + Server, config::spamfilter::{DnsBlServer, Element, IpResolver, Location}, expr::functions::ResolveVariable, - Server, }; -use mail_auth::{common::resolver::IntoFqdn, Error}; +use mail_auth::{Error, common::resolver::IntoFqdn}; use trc::SpamEvent; use crate::SpamFilterContext; diff --git a/crates/spam-filter/src/modules/expression.rs b/crates/spam-filter/src/modules/expression.rs index df6aacfa..57fbf2eb 100644 --- a/crates/spam-filter/src/modules/expression.rs +++ b/crates/spam-filter/src/modules/expression.rs @@ -6,12 +6,12 @@ use common::{ config::spamfilter::*, - expr::{functions::ResolveVariable, Variable}, + expr::{Variable, functions::ResolveVariable}, }; use mail_parser::{Header, HeaderValue}; use nlp::tokenizers::types::TokenType; -use crate::{analysis::url::UrlParts, Recipient, SpamFilterContext, TextPart}; +use crate::{Recipient, SpamFilterContext, TextPart, analysis::url::UrlParts}; pub(crate) struct SpamFilterResolver<'x, T: ResolveVariable> { pub ctx: &'x SpamFilterContext<'x>, diff --git a/crates/spam-filter/src/modules/mod.rs b/crates/spam-filter/src/modules/mod.rs index 00bf61b3..deeaa09e 100644 --- a/crates/spam-filter/src/modules/mod.rs +++ b/crates/spam-filter/src/modules/mod.rs @@ -6,8 +6,8 @@ use common::Server; use store::{ - dispatch::lookup::{KeyValue, LookupKey}, Deserialize, Value, + dispatch::lookup::{KeyValue, LookupKey}, }; pub mod bayes; diff --git a/crates/spam-filter/src/modules/pyzor.rs b/crates/spam-filter/src/modules/pyzor.rs index 2e26be0c..e37dd61b 100644 --- a/crates/spam-filter/src/modules/pyzor.rs +++ b/crates/spam-filter/src/modules/pyzor.rs @@ -12,7 +12,7 @@ use std::{ }; use common::config::spamfilter::PyzorConfig; -use mail_parser::{decoders::html::add_html_token, Message, PartType}; +use mail_parser::{Message, PartType, decoders::html::add_html_token}; use nlp::tokenizers::types::{TokenType, TypesTokenizer}; use sha1::{Digest, Sha1}; use tokio::net::UdpSocket; @@ -424,7 +424,7 @@ mod test { use super::pyzor_create_message; use super::pyzor_send_message; - use super::{html_to_text, pyzor_digest, PyzorDigest}; + use super::{PyzorDigest, html_to_text, pyzor_digest}; use super::PyzorResponse; @@ -767,7 +767,9 @@ email. Clicking on may send users to phishing web sites or sites that are hosting malware."#; - const HTML_RAW_STRIPED : &str = concat!("Email spam Email spam , also known as junk email or unsolicited bulk email ( UBE )," , - " is a subset of electronic spam involving nearly identical messages sent to numerous recipients by email" , - " . Clicking on links in spam email may send users to phishing web sites or sites that are hosting malware ."); + const HTML_RAW_STRIPED: &str = concat!( + "Email spam Email spam , also known as junk email or unsolicited bulk email ( UBE ),", + " is a subset of electronic spam involving nearly identical messages sent to numerous recipients by email", + " . Clicking on links in spam email may send users to phishing web sites or sites that are hosting malware ." + ); } diff --git a/crates/store/src/backend/azure/mod.rs b/crates/store/src/backend/azure/mod.rs index 3b6d5be4..e154a1ab 100644 --- a/crates/store/src/backend/azure/mod.rs +++ b/crates/store/src/backend/azure/mod.rs @@ -14,7 +14,7 @@ use futures::stream::StreamExt; use std::sync::Arc; use utils::{ codec::base32_custom::Base32Writer, - config::{utils::AsKey, Config}, + config::{Config, utils::AsKey}, }; pub struct AzureStore { diff --git a/crates/store/src/backend/composite/read_replica.rs b/crates/store/src/backend/composite/read_replica.rs index d80ecf69..356c0eaa 100644 --- a/crates/store/src/backend/composite/read_replica.rs +++ b/crates/store/src/backend/composite/read_replica.rs @@ -15,11 +15,11 @@ use std::{ }; use roaring::RoaringBitmap; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::{ - write::{AssignedIds, Batch, BitmapClass, ValueClass}, BitmapKey, Deserialize, IterateParams, Key, Store, Stores, ValueKey, + write::{AssignedIds, Batch, BitmapClass, ValueClass}, }; pub struct SQLReadReplica { diff --git a/crates/store/src/backend/composite/sharded_blob.rs b/crates/store/src/backend/composite/sharded_blob.rs index 99088f4b..ebcbb9ba 100644 --- a/crates/store/src/backend/composite/sharded_blob.rs +++ b/crates/store/src/backend/composite/sharded_blob.rs @@ -10,7 +10,7 @@ use std::ops::Range; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::{BlobBackend, Store, Stores}; diff --git a/crates/store/src/backend/composite/sharded_lookup.rs b/crates/store/src/backend/composite/sharded_lookup.rs index fcbb1e37..8c02e310 100644 --- a/crates/store/src/backend/composite/sharded_lookup.rs +++ b/crates/store/src/backend/composite/sharded_lookup.rs @@ -8,11 +8,11 @@ * */ -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::{ - dispatch::lookup::{KeyValue, LookupKey}, Deserialize, InMemoryStore, Stores, Value, + dispatch::lookup::{KeyValue, LookupKey}, }; #[derive(Debug)] @@ -119,7 +119,7 @@ impl ShardedInMemory { match store { InMemoryStore::Redis(store) => store.key_delete_prefix(prefix).await?, InMemoryStore::Static(_) => { - return Err(trc::StoreEvent::NotSupported.into_err()) + return Err(trc::StoreEvent::NotSupported.into_err()); } _ => return Err(trc::StoreEvent::NotSupported.into_err()), } diff --git a/crates/store/src/backend/elastic/index.rs b/crates/store/src/backend/elastic/index.rs index 538af1fb..cce75544 100644 --- a/crates/store/src/backend/elastic/index.rs +++ b/crates/store/src/backend/elastic/index.rs @@ -13,10 +13,10 @@ use serde_json::json; use crate::{ backend::elastic::INDEX_NAMES, dispatch::DocumentSet, - fts::{index::FtsDocument, Field}, + fts::{Field, index::FtsDocument}, }; -use super::{assert_success, ElasticSearchStore}; +use super::{ElasticSearchStore, assert_success}; #[derive(Serialize, Deserialize, Default)] struct Document<'x> { diff --git a/crates/store/src/backend/elastic/mod.rs b/crates/store/src/backend/elastic/mod.rs index 3ba3b7fc..f8ec9421 100644 --- a/crates/store/src/backend/elastic/mod.rs +++ b/crates/store/src/backend/elastic/mod.rs @@ -5,18 +5,18 @@ */ use elasticsearch::{ + Elasticsearch, Error, auth::Credentials, cert::CertificateValidation, http::{ + StatusCode, Url, response::Response, transport::{SingleNodeConnectionPool, Transport, TransportBuilder}, - StatusCode, Url, }, indices::{IndicesCreateParts, IndicesExistsParts}, - Elasticsearch, Error, }; use serde_json::json; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; pub mod index; pub mod query; diff --git a/crates/store/src/backend/elastic/query.rs b/crates/store/src/backend/elastic/query.rs index b9e3c0a5..a5feaa7d 100644 --- a/crates/store/src/backend/elastic/query.rs +++ b/crates/store/src/backend/elastic/query.rs @@ -8,11 +8,11 @@ use std::{borrow::Cow, fmt::Display}; use elasticsearch::SearchParts; use roaring::RoaringBitmap; -use serde_json::{json, Value}; +use serde_json::{Value, json}; use crate::fts::{Field, FtsFilter}; -use super::{assert_success, ElasticSearchStore, INDEX_NAMES}; +use super::{ElasticSearchStore, INDEX_NAMES, assert_success}; impl ElasticSearchStore { pub async fn fts_query + Display + Clone + std::fmt::Debug>( diff --git a/crates/store/src/backend/foundationdb/blob.rs b/crates/store/src/backend/foundationdb/blob.rs index ab4659f0..7333f47f 100644 --- a/crates/store/src/backend/foundationdb/blob.rs +++ b/crates/store/src/backend/foundationdb/blob.rs @@ -6,11 +6,11 @@ use std::ops::Range; -use foundationdb::{options::StreamingMode, KeySelector, RangeOption}; +use foundationdb::{KeySelector, RangeOption, options::StreamingMode}; use futures::TryStreamExt; use utils::BLOB_HASH_LEN; -use crate::{backend::foundationdb::into_error, write::key::KeySerializer, SUBSPACE_BLOBS}; +use crate::{SUBSPACE_BLOBS, backend::foundationdb::into_error, write::key::KeySerializer}; use super::{FdbStore, MAX_VALUE_SIZE}; diff --git a/crates/store/src/backend/foundationdb/main.rs b/crates/store/src/backend/foundationdb/main.rs index 2f130b48..269d703b 100644 --- a/crates/store/src/backend/foundationdb/main.rs +++ b/crates/store/src/backend/foundationdb/main.rs @@ -6,8 +6,8 @@ use std::time::Duration; -use foundationdb::{api, options::DatabaseOption, Database}; -use utils::config::{utils::AsKey, Config}; +use foundationdb::{Database, api, options::DatabaseOption}; +use utils::config::{Config, utils::AsKey}; use super::FdbStore; diff --git a/crates/store/src/backend/foundationdb/mod.rs b/crates/store/src/backend/foundationdb/mod.rs index 585def96..0416ebdd 100644 --- a/crates/store/src/backend/foundationdb/mod.rs +++ b/crates/store/src/backend/foundationdb/mod.rs @@ -6,7 +6,7 @@ use std::time::{Duration, Instant}; -use foundationdb::{api::NetworkAutoStop, Database, FdbError, Transaction}; +use foundationdb::{Database, FdbError, Transaction, api::NetworkAutoStop}; pub mod blob; pub mod main; diff --git a/crates/store/src/backend/mysql/blob.rs b/crates/store/src/backend/mysql/blob.rs index 39bb8bb1..85838870 100644 --- a/crates/store/src/backend/mysql/blob.rs +++ b/crates/store/src/backend/mysql/blob.rs @@ -8,7 +8,7 @@ use std::ops::Range; use mysql_async::prelude::Queryable; -use super::{into_error, MysqlStore}; +use super::{MysqlStore, into_error}; impl MysqlStore { pub(crate) async fn get_blob( diff --git a/crates/store/src/backend/mysql/lookup.rs b/crates/store/src/backend/mysql/lookup.rs index 8dd8d3dd..30be6251 100644 --- a/crates/store/src/backend/mysql/lookup.rs +++ b/crates/store/src/backend/mysql/lookup.rs @@ -4,11 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use mysql_async::{prelude::Queryable, Params, Row}; +use mysql_async::{Params, Row, prelude::Queryable}; use crate::{IntoRows, QueryResult, QueryType, Value}; -use super::{into_error, MysqlStore}; +use super::{MysqlStore, into_error}; impl MysqlStore { pub(crate) async fn query( diff --git a/crates/store/src/backend/mysql/main.rs b/crates/store/src/backend/mysql/main.rs index 6c3a780a..e7483bb1 100644 --- a/crates/store/src/backend/mysql/main.rs +++ b/crates/store/src/backend/mysql/main.rs @@ -6,12 +6,12 @@ use std::time::Duration; -use mysql_async::{prelude::Queryable, OptsBuilder, Pool, PoolConstraints, PoolOpts, SslOpts}; -use utils::config::{utils::AsKey, Config}; +use mysql_async::{OptsBuilder, Pool, PoolConstraints, PoolOpts, SslOpts, prelude::Queryable}; +use utils::config::{Config, utils::AsKey}; use crate::*; -use super::{into_error, MysqlStore}; +use super::{MysqlStore, into_error}; impl MysqlStore { pub async fn open( diff --git a/crates/store/src/backend/postgres/blob.rs b/crates/store/src/backend/postgres/blob.rs index 4a91e383..51227ae5 100644 --- a/crates/store/src/backend/postgres/blob.rs +++ b/crates/store/src/backend/postgres/blob.rs @@ -6,7 +6,7 @@ use std::ops::Range; -use super::{into_error, PostgresStore}; +use super::{PostgresStore, into_error}; impl PostgresStore { pub(crate) async fn get_blob( diff --git a/crates/store/src/backend/postgres/lookup.rs b/crates/store/src/backend/postgres/lookup.rs index 4b01e955..9c8b3de6 100644 --- a/crates/store/src/backend/postgres/lookup.rs +++ b/crates/store/src/backend/postgres/lookup.rs @@ -7,12 +7,12 @@ use crate::{QueryResult, QueryType}; use bytes::BytesMut; -use futures::{pin_mut, TryStreamExt}; +use futures::{TryStreamExt, pin_mut}; use tokio_postgres::types::{FromSql, ToSql, Type}; use crate::IntoRows; -use super::{into_error, PostgresStore}; +use super::{PostgresStore, into_error}; impl PostgresStore { pub(crate) async fn query( diff --git a/crates/store/src/backend/postgres/main.rs b/crates/store/src/backend/postgres/main.rs index 23656abb..406b9e56 100644 --- a/crates/store/src/backend/postgres/main.rs +++ b/crates/store/src/backend/postgres/main.rs @@ -8,7 +8,7 @@ use std::time::Duration; use crate::{backend::postgres::tls::MakeRustlsConnect, *}; -use super::{into_error, PostgresStore}; +use super::{PostgresStore, into_error}; use deadpool_postgres::{Config, ManagerConfig, PoolConfig, RecyclingMethod, Runtime}; use tokio_postgres::NoTls; diff --git a/crates/store/src/backend/postgres/tls.rs b/crates/store/src/backend/postgres/tls.rs index c09267bf..883b0d06 100644 --- a/crates/store/src/backend/postgres/tls.rs +++ b/crates/store/src/backend/postgres/tls.rs @@ -21,7 +21,7 @@ use rustls::ClientConfig; use rustls_pki_types::ServerName; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio_postgres::tls::{ChannelBinding, MakeTlsConnect, TlsConnect}; -use tokio_rustls::{client::TlsStream, TlsConnector}; +use tokio_rustls::{TlsConnector, client::TlsStream}; #[derive(Clone)] pub struct MakeRustlsConnect { diff --git a/crates/store/src/backend/postgres/write.rs b/crates/store/src/backend/postgres/write.rs index b840eaf3..869a6f55 100644 --- a/crates/store/src/backend/postgres/write.rs +++ b/crates/store/src/backend/postgres/write.rs @@ -8,19 +8,21 @@ use std::time::{Duration, Instant}; use ahash::AHashMap; use deadpool_postgres::Object; -use futures::{pin_mut, TryStreamExt}; +use futures::{TryStreamExt, pin_mut}; use rand::Rng; use roaring::RoaringBitmap; -use tokio_postgres::{error::SqlState, IsolationLevel}; +use tokio_postgres::{IsolationLevel, error::SqlState}; use crate::{ + BitmapKey, IndexKey, Key, LogKey, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER, SUBSPACE_QUOTA, + U32_LEN, write::{ - key::DeserializeBigEndian, AssignedIds, Batch, BitmapClass, Operation, RandomAvailableId, - ValueOp, MAX_COMMIT_ATTEMPTS, MAX_COMMIT_TIME, - }, BitmapKey, IndexKey, Key, LogKey, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER, SUBSPACE_QUOTA, U32_LEN + AssignedIds, Batch, BitmapClass, MAX_COMMIT_ATTEMPTS, MAX_COMMIT_TIME, Operation, + RandomAvailableId, ValueOp, key::DeserializeBigEndian, + }, }; -use super::{into_error, PostgresStore}; +use super::{PostgresStore, into_error}; #[derive(Debug)] enum CommitError { diff --git a/crates/store/src/backend/redis/mod.rs b/crates/store/src/backend/redis/mod.rs index 0f06e65b..4faca371 100644 --- a/crates/store/src/backend/redis/mod.rs +++ b/crates/store/src/backend/redis/mod.rs @@ -7,14 +7,14 @@ use std::{fmt::Display, time::Duration}; use deadpool::{ - managed::{Manager, Pool}, Runtime, + managed::{Manager, Pool}, }; use redis::{ - cluster::{ClusterClient, ClusterClientBuilder}, Client, + cluster::{ClusterClient, ClusterClientBuilder}, }; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; pub mod lookup; pub mod pool; diff --git a/crates/store/src/backend/redis/pool.rs b/crates/store/src/backend/redis/pool.rs index f8f31da9..0822cb38 100644 --- a/crates/store/src/backend/redis/pool.rs +++ b/crates/store/src/backend/redis/pool.rs @@ -10,7 +10,7 @@ use redis::{ cluster_async::ClusterConnection, }; -use super::{into_error, RedisClusterConnectionManager, RedisConnectionManager}; +use super::{RedisClusterConnectionManager, RedisConnectionManager, into_error}; impl managed::Manager for RedisConnectionManager { type Type = MultiplexedConnection; diff --git a/crates/store/src/backend/rocksdb/blob.rs b/crates/store/src/backend/rocksdb/blob.rs index b3b38842..8d110d42 100644 --- a/crates/store/src/backend/rocksdb/blob.rs +++ b/crates/store/src/backend/rocksdb/blob.rs @@ -6,7 +6,7 @@ use std::ops::Range; -use super::{into_error, RocksDbStore, CF_BLOBS}; +use super::{CF_BLOBS, RocksDbStore, into_error}; impl RocksDbStore { pub(crate) async fn get_blob( diff --git a/crates/store/src/backend/rocksdb/main.rs b/crates/store/src/backend/rocksdb/main.rs index 9efa1e39..9010a228 100644 --- a/crates/store/src/backend/rocksdb/main.rs +++ b/crates/store/src/backend/rocksdb/main.rs @@ -9,11 +9,11 @@ use std::path::PathBuf; use rocksdb::{ColumnFamilyDescriptor, MergeOperands, OptimisticTransactionDB, Options}; use tokio::sync::oneshot; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::*; -use super::{RocksDbStore, CF_BLOBS}; +use super::{CF_BLOBS, RocksDbStore}; impl RocksDbStore { pub async fn open(config: &mut Config, prefix: impl AsKey) -> Option { diff --git a/crates/store/src/backend/s3/mod.rs b/crates/store/src/backend/s3/mod.rs index 76bd9ac9..bdf66892 100644 --- a/crates/store/src/backend/s3/mod.rs +++ b/crates/store/src/backend/s3/mod.rs @@ -6,10 +6,10 @@ use std::{fmt::Display, io::Write, ops::Range, time::Duration}; -use s3::{creds::Credentials, Bucket, Region}; +use s3::{Bucket, Region, creds::Credentials}; use utils::{ codec::base32_custom::Base32Writer, - config::{utils::AsKey, Config}, + config::{Config, utils::AsKey}, }; pub struct S3Store { @@ -109,7 +109,7 @@ impl S3Store { code => { return Err(trc::StoreEvent::S3Error .reason(String::from_utf8_lossy(response.as_slice())) - .ctx(trc::Key::Code, code)) + .ctx(trc::Key::Code, code)); } } } @@ -139,7 +139,7 @@ impl S3Store { code => { return Err(trc::StoreEvent::S3Error .reason(String::from_utf8_lossy(response.as_slice())) - .ctx(trc::Key::Code, code)) + .ctx(trc::Key::Code, code)); } } } @@ -170,7 +170,7 @@ impl S3Store { code => { return Err(trc::StoreEvent::S3Error .reason(String::from_utf8_lossy(response.as_slice())) - .ctx(trc::Key::Code, code)) + .ctx(trc::Key::Code, code)); } } } diff --git a/crates/store/src/backend/sqlite/blob.rs b/crates/store/src/backend/sqlite/blob.rs index 0fc1f8a1..7d39dfb2 100644 --- a/crates/store/src/backend/sqlite/blob.rs +++ b/crates/store/src/backend/sqlite/blob.rs @@ -8,7 +8,7 @@ use std::ops::Range; use rusqlite::OptionalExtension; -use super::{into_error, SqliteStore}; +use super::{SqliteStore, into_error}; impl SqliteStore { pub(crate) async fn get_blob( diff --git a/crates/store/src/backend/sqlite/lookup.rs b/crates/store/src/backend/sqlite/lookup.rs index 6b83aaf7..ab166e63 100644 --- a/crates/store/src/backend/sqlite/lookup.rs +++ b/crates/store/src/backend/sqlite/lookup.rs @@ -4,11 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use rusqlite::{types::FromSql, Row, Rows, ToSql}; +use rusqlite::{Row, Rows, ToSql, types::FromSql}; use crate::{IntoRows, QueryResult, QueryType, Value}; -use super::{into_error, SqliteStore}; +use super::{SqliteStore, into_error}; impl SqliteStore { pub(crate) async fn query( diff --git a/crates/store/src/backend/sqlite/main.rs b/crates/store/src/backend/sqlite/main.rs index 36ba6cb7..90d74168 100644 --- a/crates/store/src/backend/sqlite/main.rs +++ b/crates/store/src/backend/sqlite/main.rs @@ -6,11 +6,11 @@ use r2d2::Pool; use tokio::sync::oneshot; -use utils::config::{utils::AsKey, Config}; +use utils::config::{Config, utils::AsKey}; use crate::*; -use super::{into_error, pool::SqliteConnectionManager, SqliteStore}; +use super::{SqliteStore, into_error, pool::SqliteConnectionManager}; impl SqliteStore { pub fn open(config: &mut Config, prefix: impl AsKey) -> Option { diff --git a/crates/store/src/backend/sqlite/read.rs b/crates/store/src/backend/sqlite/read.rs index 1540324a..5dc736a1 100644 --- a/crates/store/src/backend/sqlite/read.rs +++ b/crates/store/src/backend/sqlite/read.rs @@ -8,11 +8,11 @@ use roaring::RoaringBitmap; use rusqlite::OptionalExtension; use crate::{ - write::{key::DeserializeBigEndian, BitmapClass, ValueClass}, - BitmapKey, Deserialize, IterateParams, Key, ValueKey, U32_LEN, + BitmapKey, Deserialize, IterateParams, Key, U32_LEN, ValueKey, + write::{BitmapClass, ValueClass, key::DeserializeBigEndian}, }; -use super::{into_error, SqliteStore}; +use super::{SqliteStore, into_error}; impl SqliteStore { pub(crate) async fn get_value(&self, key: impl Key) -> trc::Result> diff --git a/crates/store/src/backend/sqlite/write.rs b/crates/store/src/backend/sqlite/write.rs index 1a677cac..8c40a151 100644 --- a/crates/store/src/backend/sqlite/write.rs +++ b/crates/store/src/backend/sqlite/write.rs @@ -5,16 +5,18 @@ */ use roaring::RoaringBitmap; -use rusqlite::{params, OptionalExtension, TransactionBehavior}; +use rusqlite::{OptionalExtension, TransactionBehavior, params}; use crate::{ + BitmapKey, IndexKey, Key, LogKey, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER, SUBSPACE_QUOTA, + U32_LEN, write::{ - key::DeserializeBigEndian, AssignedIds, Batch, BitmapClass, Operation, RandomAvailableId, - ValueOp, - }, BitmapKey, IndexKey, Key, LogKey, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER, SUBSPACE_QUOTA, U32_LEN + AssignedIds, Batch, BitmapClass, Operation, RandomAvailableId, ValueOp, + key::DeserializeBigEndian, + }, }; -use super::{into_error, SqliteStore}; +use super::{SqliteStore, into_error}; impl SqliteStore { pub(crate) async fn write(&self, batch: Batch) -> trc::Result { diff --git a/crates/store/src/config.rs b/crates/store/src/config.rs index 7928896d..87b00915 100644 --- a/crates/store/src/config.rs +++ b/crates/store/src/config.rs @@ -4,11 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use utils::config::{cron::SimpleCron, utils::ParseValue, Config}; +use utils::config::{Config, cron::SimpleCron, utils::ParseValue}; use crate::{ - backend::fs::FsStore, BlobStore, CompressionAlgo, InMemoryStore, PurgeSchedule, PurgeStore, - Store, Stores, + BlobStore, CompressionAlgo, InMemoryStore, PurgeSchedule, PurgeStore, Store, Stores, + backend::fs::FsStore, }; #[cfg(feature = "s3")] diff --git a/crates/store/src/dispatch/fts.rs b/crates/store/src/dispatch/fts.rs index fd56451f..f221409b 100644 --- a/crates/store/src/dispatch/fts.rs +++ b/crates/store/src/dispatch/fts.rs @@ -10,8 +10,8 @@ use roaring::RoaringBitmap; use trc::AddContext; use crate::{ - fts::{index::FtsDocument, FtsFilter}, FtsStore, + fts::{FtsFilter, index::FtsDocument}, }; use super::DocumentSet; diff --git a/crates/store/src/fts/query.rs b/crates/store/src/fts/query.rs index 35ea303d..47f6c4a8 100644 --- a/crates/store/src/fts/query.rs +++ b/crates/store/src/fts/query.rs @@ -15,12 +15,12 @@ use roaring::RoaringBitmap; use trc::AddContext; use crate::{ + BitmapKey, IterateParams, Store, U32_LEN, ValueKey, backend::MAX_TOKEN_LENGTH, fts::FtsFilter, write::{ - hash::TokenType, key::DeserializeBigEndian, BitmapHash, DynamicDocumentId, ValueClass, + BitmapHash, DynamicDocumentId, ValueClass, hash::TokenType, key::DeserializeBigEndian, }, - BitmapKey, IterateParams, Store, ValueKey, U32_LEN, }; use super::postings::SerializedPostings; @@ -294,12 +294,9 @@ impl Store { .insert(*document_id, postings.positions()); } bm.insert(*document_id); - } else if position_candidates - .get(document_id) - .is_some_and(|positions| { - postings.matches_positions(positions, pos as u32) - }) - { + } else if position_candidates.get(document_id).is_some_and( + |positions| postings.matches_positions(positions, pos as u32), + ) { bm.insert(*document_id); } } else { @@ -358,12 +355,9 @@ impl Store { position_candidates.insert(document_id, postings.positions()); } bm.insert(document_id); - } else if position_candidates - .get(&document_id) - .is_some_and(|positions| { - postings.matches_positions(positions, pos as u32) - }) - { + } else if position_candidates.get(&document_id).is_some_and( + |positions| postings.matches_positions(positions, pos as u32), + ) { bm.insert(document_id); } } else { diff --git a/crates/store/src/query/acl.rs b/crates/store/src/query/acl.rs index 0ee7cfc5..52101bd9 100644 --- a/crates/store/src/query/acl.rs +++ b/crates/store/src/query/acl.rs @@ -8,8 +8,8 @@ use ahash::AHashSet; use trc::AddContext; use crate::{ - write::{key::DeserializeBigEndian, BatchBuilder, Operation, ValueClass, ValueOp}, - Deserialize, IterateParams, Store, ValueKey, U32_LEN, + Deserialize, IterateParams, Store, U32_LEN, ValueKey, + write::{BatchBuilder, Operation, ValueClass, ValueOp, key::DeserializeBigEndian}, }; pub enum AclQuery { diff --git a/crates/store/src/query/log.rs b/crates/store/src/query/log.rs index e1419e99..995265f6 100644 --- a/crates/store/src/query/log.rs +++ b/crates/store/src/query/log.rs @@ -7,7 +7,7 @@ use trc::AddContext; use utils::codec::leb128::Leb128Iterator; -use crate::{write::key::DeserializeBigEndian, IterateParams, LogKey, Store, U64_LEN}; +use crate::{IterateParams, LogKey, Store, U64_LEN, write::key::DeserializeBigEndian}; #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Change { diff --git a/crates/store/src/write/blob.rs b/crates/store/src/write/blob.rs index 4c2a6276..df128365 100644 --- a/crates/store/src/write/blob.rs +++ b/crates/store/src/write/blob.rs @@ -6,14 +6,14 @@ use ahash::AHashSet; use trc::AddContext; -use utils::{BlobHash, BLOB_HASH_LEN}; +use utils::{BLOB_HASH_LEN, BlobHash}; use crate::{ - write::BatchBuilder, BlobClass, BlobStore, Deserialize, IterateParams, Store, ValueKey, - U32_LEN, U64_LEN, + BlobClass, BlobStore, Deserialize, IterateParams, Store, U32_LEN, U64_LEN, ValueKey, + write::BatchBuilder, }; -use super::{key::DeserializeBigEndian, now, BlobOp, Operation, ValueClass, ValueOp}; +use super::{BlobOp, Operation, ValueClass, ValueOp, key::DeserializeBigEndian, now}; #[derive(Debug, PartialEq, Eq)] pub struct BlobQuota { diff --git a/crates/trc/event-macro/src/lib.rs b/crates/trc/event-macro/src/lib.rs index 5157f1fc..aecd8f13 100644 --- a/crates/trc/event-macro/src/lib.rs +++ b/crates/trc/event-macro/src/lib.rs @@ -7,7 +7,7 @@ use proc_macro::TokenStream; use quote::quote; use syn::{ - parse::Parse, parse_macro_input, Data, DeriveInput, Expr, ExprPath, Fields, Ident, Token, + Data, DeriveInput, Expr, ExprPath, Fields, Ident, Token, parse::Parse, parse_macro_input, }; static mut GLOBAL_ID_COUNTER: usize = 0; diff --git a/crates/trc/src/atomics/bitset.rs b/crates/trc/src/atomics/bitset.rs index f5ce17b3..ca6ef073 100644 --- a/crates/trc/src/atomics/bitset.rs +++ b/crates/trc/src/atomics/bitset.rs @@ -6,7 +6,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; -use crate::ipc::{bitset::Bitset, USIZE_BITS, USIZE_BITS_MASK}; +use crate::ipc::{USIZE_BITS, USIZE_BITS_MASK, bitset::Bitset}; pub struct AtomicBitset([AtomicUsize; N]); diff --git a/crates/trc/src/atomics/histogram.rs b/crates/trc/src/atomics/histogram.rs index c52c4557..a4685310 100644 --- a/crates/trc/src/atomics/histogram.rs +++ b/crates/trc/src/atomics/histogram.rs @@ -73,20 +73,12 @@ impl AtomicHistogram { pub fn min(&self) -> Option { let min = self.min.load(Ordering::Relaxed); - if min != u64::MAX { - Some(min) - } else { - None - } + if min != u64::MAX { Some(min) } else { None } } pub fn max(&self) -> Option { let max = self.max.load(Ordering::Relaxed); - if max != 0 { - Some(max) - } else { - None - } + if max != 0 { Some(max) } else { None } } pub fn buckets_iter(&self) -> impl IntoIterator + '_ { diff --git a/crates/trc/src/ipc/channel.rs b/crates/trc/src/ipc/channel.rs index 4eb01678..cdca99d9 100644 --- a/crates/trc/src/ipc/channel.rs +++ b/crates/trc/src/ipc/channel.rs @@ -7,16 +7,16 @@ use std::{ cell::UnsafeCell, sync::{ - atomic::{AtomicU64, Ordering}, Arc, + atomic::{AtomicU64, Ordering}, }, }; use rtrb::{Consumer, Producer, PushError, RingBuffer}; use crate::{ - ipc::collector::{Update, COLLECTOR_THREAD, COLLECTOR_UPDATES}, Error, Event, EventType, + ipc::collector::{COLLECTOR_THREAD, COLLECTOR_UPDATES, Update}, }; use super::collector::{Collector, CollectorThread}; diff --git a/crates/trc/src/ipc/collector.rs b/crates/trc/src/ipc/collector.rs index c63d00f2..1f878cba 100644 --- a/crates/trc/src/ipc/collector.rs +++ b/crates/trc/src/ipc/collector.rs @@ -5,17 +5,17 @@ */ use std::{ - sync::{atomic::Ordering, Arc, LazyLock}, - thread::{park, Builder, JoinHandle}, + sync::{Arc, LazyLock, atomic::Ordering}, + thread::{Builder, JoinHandle, park}, time::SystemTime, }; use ahash::AHashMap; use atomics::bitset::AtomicBitset; use ipc::{ - channel::{Receiver, CHANNEL_FLAGS, CHANNEL_UPDATE_MARKER}, - subscriber::{Interests, Subscriber}, USIZE_BITS, + channel::{CHANNEL_FLAGS, CHANNEL_UPDATE_MARKER, Receiver}, + subscriber::{Interests, Subscriber}, }; use parking_lot::Mutex; diff --git a/crates/trc/src/ipc/metrics.rs b/crates/trc/src/ipc/metrics.rs index ca13b63c..a4929af8 100644 --- a/crates/trc/src/ipc/metrics.rs +++ b/crates/trc/src/ipc/metrics.rs @@ -8,7 +8,7 @@ use std::sync::atomic::Ordering; use atomics::{array::AtomicU32Array, gauge::AtomicGauge, histogram::AtomicHistogram}; use ipc::{ - collector::{Collector, GlobalInterests, EVENT_TYPES}, + collector::{Collector, EVENT_TYPES, GlobalInterests}, subscriber::Interests, }; diff --git a/crates/trc/src/ipc/subscriber.rs b/crates/trc/src/ipc/subscriber.rs index 5de9e0f8..c9c1f451 100644 --- a/crates/trc/src/ipc/subscriber.rs +++ b/crates/trc/src/ipc/subscriber.rs @@ -11,10 +11,10 @@ use tokio::sync::mpsc::{self, error::TrySendError}; use crate::{Event, EventDetails, EventType, Level, TOTAL_EVENT_COUNT}; use super::{ + USIZE_BITS, bitset::Bitset, channel::ChannelError, - collector::{Collector, Update, COLLECTOR_UPDATES}, - USIZE_BITS, + collector::{COLLECTOR_UPDATES, Collector, Update}, }; const MAX_BATCH_SIZE: usize = 32768; diff --git a/crates/trc/src/macros.rs b/crates/trc/src/macros.rs index a9352206..a459f8a8 100644 --- a/crates/trc/src/macros.rs +++ b/crates/trc/src/macros.rs @@ -6,9 +6,7 @@ #[macro_export] macro_rules! location { - () => {{ - concat!(file!(), ":", line!()) - }}; + () => {{ concat!(file!(), ":", line!()) }}; } #[macro_export] diff --git a/crates/trc/src/serializers/binary.rs b/crates/trc/src/serializers/binary.rs index 23e583d8..e092d824 100644 --- a/crates/trc/src/serializers/binary.rs +++ b/crates/trc/src/serializers/binary.rs @@ -35,9 +35,11 @@ pub fn deserialize_events(bytes: &[u8]) -> crate::Result .details("EOF while reading version") })? != VERSION { - crate::bail!(StoreEvent::DataCorruption - .caused_by(crate::location!()) - .details("Invalid version")); + crate::bail!( + StoreEvent::DataCorruption + .caused_by(crate::location!()) + .details("Invalid version") + ); } let len = leb128_read(&mut iter).ok_or_else(|| { StoreEvent::DataCorruption @@ -63,9 +65,11 @@ pub fn deserialize_single_event(bytes: &[u8]) -> crate::Result { writer: T, diff --git a/crates/utils/proc-macros/src/lib.rs b/crates/utils/proc-macros/src/lib.rs index 77fbf969..7d36c354 100644 --- a/crates/utils/proc-macros/src/lib.rs +++ b/crates/utils/proc-macros/src/lib.rs @@ -6,7 +6,7 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{parse_macro_input, Data, DeriveInput}; +use syn::{Data, DeriveInput, parse_macro_input}; #[proc_macro_derive(EnumMethods)] pub fn enum_id(input: TokenStream) -> TokenStream { diff --git a/crates/utils/src/cache.rs b/crates/utils/src/cache.rs index 60167613..0258435a 100644 --- a/crates/utils/src/cache.rs +++ b/crates/utils/src/cache.rs @@ -12,10 +12,10 @@ use std::{ time::{Duration, Instant}, }; -use mail_auth::{ResolverCache, Txt, MX}; +use mail_auth::{MX, ResolverCache, Txt}; use quick_cache::{ - sync::{DefaultLifecycle, PlaceholderGuard}, Equivalent, Weighter, + sync::{DefaultLifecycle, PlaceholderGuard}, }; use crate::config::Config; diff --git a/crates/utils/src/config/ipmask.rs b/crates/utils/src/config/ipmask.rs index bb0c80ac..55cd2f9e 100644 --- a/crates/utils/src/config/ipmask.rs +++ b/crates/utils/src/config/ipmask.rs @@ -6,7 +6,7 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; -use rustls::{crypto::ring::cipher_suite::*, SupportedCipherSuite}; +use rustls::{SupportedCipherSuite, crypto::ring::cipher_suite::*}; use super::utils::ParseValue; @@ -84,13 +84,13 @@ impl ParseValue for IpAddrMask { return Ok(IpAddrMask::V4 { addr, mask: u32::MAX << (32 - mask), - }) + }); } IpAddr::V6(addr) if (8..=128).contains(&mask) => { return Ok(IpAddrMask::V6 { addr, mask: u128::MAX << (128 - mask), - }) + }); } _ => (), } @@ -101,13 +101,13 @@ impl ParseValue for IpAddrMask { return Ok(IpAddrMask::V4 { addr, mask: u32::MAX, - }) + }); } Ok(IpAddr::V6(addr)) => { return Ok(IpAddrMask::V6 { addr, mask: u128::MAX, - }) + }); } _ => (), } diff --git a/crates/utils/src/config/parser.rs b/crates/utils/src/config/parser.rs index 0f618005..30abd9ea 100644 --- a/crates/utils/src/config/parser.rs +++ b/crates/utils/src/config/parser.rs @@ -5,7 +5,7 @@ */ use std::{ - collections::{btree_map::Entry, BTreeMap}, + collections::{BTreeMap, btree_map::Entry}, iter::Peekable, str::Chars, }; @@ -299,9 +299,9 @@ impl<'x, 'y> TomlParser<'x, 'y> { '}' => break, ch => { return Err(format!( - "Unexpected character {:?} found in inline table for property {:?} at line {}.", - ch, key, self.line - )); + "Unexpected character {:?} found in inline table for property {:?} at line {}.", + ch, key, self.line + )); } } } @@ -397,7 +397,7 @@ impl<'x, 'y> TomlParser<'x, 'y> { "Expected {:?} but found {:?} in value at line {}.", stop_chars, ch, self.line )) - } + }; } } diff --git a/crates/utils/src/config/utils.rs b/crates/utils/src/config/utils.rs index 2790731d..861fb20f 100644 --- a/crates/utils/src/config/utils.rs +++ b/crates/utils/src/config/utils.rs @@ -12,9 +12,9 @@ use std::{ }; use mail_auth::{ + IpLookupStrategy, common::crypto::{Algorithm, HashAlgorithm}, dkim::Canonicalization, - IpLookupStrategy, }; use smtp_proto::MtPriority; @@ -216,11 +216,7 @@ impl Config { if let Some(value) = self.keys.get(&key).and_then(|v| { let v = v.trim(); - if !v.is_empty() { - Some(v) - } else { - None - } + if !v.is_empty() { Some(v) } else { None } }) { Some(value) } else { diff --git a/crates/utils/src/json/mod.rs b/crates/utils/src/json/mod.rs index 9824cb37..47e4d5cf 100644 --- a/crates/utils/src/json/mod.rs +++ b/crates/utils/src/json/mod.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - pub mod parser; +pub mod parser; pub mod pointer; use downcast_rs::{Downcast, impl_downcast}; diff --git a/crates/utils/src/json/pointer.rs b/crates/utils/src/json/pointer.rs index befe58e2..068f1cab 100644 --- a/crates/utils/src/json/pointer.rs +++ b/crates/utils/src/json/pointer.rs @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ - use super::{JsonPointerItem, JsonQueryable}; +use super::{JsonPointerItem, JsonQueryable}; use std::hash::BuildHasher; use std::{collections::HashMap, slice::Iter}; diff --git a/tests/src/directory/internal.rs b/tests/src/directory/internal.rs index c1bc72e2..e6fee5b7 100644 --- a/tests/src/directory/internal.rs +++ b/tests/src/directory/internal.rs @@ -6,22 +6,22 @@ use ahash::AHashSet; use directory::{ + Principal, QueryBy, Type, backend::{ + RcptType, internal::{ + PrincipalField, PrincipalUpdate, PrincipalValue, lookup::DirectoryStore, manage::{self, ChangedPrincipals, ManageDirectory, UpdatePrincipal}, - PrincipalField, PrincipalUpdate, PrincipalValue, }, - RcptType, }, - Principal, QueryBy, Type, }; use jmap_proto::types::collection::Collection; use mail_send::Credentials; use store::{ + BitmapKey, Store, ValueKey, roaring::RoaringBitmap, write::{BatchBuilder, BitmapClass, ValueClass}, - BitmapKey, Store, ValueKey, }; use crate::directory::{DirectoryTest, IntoTestPrincipal, TestPrincipal}; @@ -110,15 +110,17 @@ async fn internal_directory() { assert!(!store.is_local_domain("otherdomain.org").await.unwrap()); // Add an email address - assert!(store - .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ - PrincipalUpdate::add_item( - PrincipalField::Emails, - PrincipalValue::String("john@example.org".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ + PrincipalUpdate::add_item( + PrincipalField::Emails, + PrincipalValue::String("john@example.org".to_string()), + ) + ])) + .await + .is_ok() + ); assert_eq!( store.rcpt("john@example.org").await.unwrap(), RcptType::Mailbox @@ -246,22 +248,24 @@ async fn internal_directory() { .await .unwrap() .id; - assert!(store - .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ - PrincipalUpdate::set( - PrincipalField::Members, - PrincipalValue::StringList(vec!["john".to_string(), "jane".to_string()]), - ), - PrincipalUpdate::set( - PrincipalField::ExternalMembers, - PrincipalValue::StringList(vec![ - "mike@other.org".to_string(), - "lucy@foobar.net".to_string() - ]), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ + PrincipalUpdate::set( + PrincipalField::Members, + PrincipalValue::StringList(vec!["john".to_string(), "jane".to_string()]), + ), + PrincipalUpdate::set( + PrincipalField::ExternalMembers, + PrincipalValue::StringList(vec![ + "mike@other.org".to_string(), + "lucy@foobar.net".to_string() + ]), + ) + ])) + .await + .is_ok() + ); assert_list_members( &store, @@ -339,19 +343,21 @@ async fn internal_directory() { .unwrap(); // Add John to the Sales and Support groups - assert!(store - .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ - PrincipalUpdate::add_item( - PrincipalField::MemberOf, - PrincipalValue::String("sales".to_string()), - ), - PrincipalUpdate::add_item( - PrincipalField::MemberOf, - PrincipalValue::String("support".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ + PrincipalUpdate::add_item( + PrincipalField::MemberOf, + PrincipalValue::String("sales".to_string()), + ), + PrincipalUpdate::add_item( + PrincipalField::MemberOf, + PrincipalValue::String("support".to_string()), + ) + ])) + .await + .is_ok() + ); let mut principal = store .query(QueryBy::Name("john"), true) .await @@ -386,15 +392,17 @@ async fn internal_directory() { ); // Remove a member from a group - assert!(store - .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ - PrincipalUpdate::remove_item( - PrincipalField::MemberOf, - PrincipalValue::String("support".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ + PrincipalUpdate::remove_item( + PrincipalField::MemberOf, + PrincipalValue::String("support".to_string()), + ) + ])) + .await + .is_ok() + ); let mut principal = store .query(QueryBy::Name("john"), true) .await @@ -416,32 +424,34 @@ async fn internal_directory() { ); // Update multiple fields - assert!(store - .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ - PrincipalUpdate::set( - PrincipalField::Name, - PrincipalValue::String("john.doe".to_string()) - ), - PrincipalUpdate::set( - PrincipalField::Description, - PrincipalValue::String("Johnny Doe".to_string()) - ), - PrincipalUpdate::set( - PrincipalField::Secrets, - PrincipalValue::StringList(vec!["12345".to_string()]) - ), - PrincipalUpdate::set(PrincipalField::Quota, PrincipalValue::Integer(1024)), - PrincipalUpdate::remove_item( - PrincipalField::Emails, - PrincipalValue::String("john@example.org".to_string()), - ), - PrincipalUpdate::add_item( - PrincipalField::Emails, - PrincipalValue::String("john.doe@example.org".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("john").with_updates(vec![ + PrincipalUpdate::set( + PrincipalField::Name, + PrincipalValue::String("john.doe".to_string()) + ), + PrincipalUpdate::set( + PrincipalField::Description, + PrincipalValue::String("Johnny Doe".to_string()) + ), + PrincipalUpdate::set( + PrincipalField::Secrets, + PrincipalValue::StringList(vec!["12345".to_string()]) + ), + PrincipalUpdate::set(PrincipalField::Quota, PrincipalValue::Integer(1024)), + PrincipalUpdate::remove_item( + PrincipalField::Emails, + PrincipalValue::String("john@example.org".to_string()), + ), + PrincipalUpdate::add_item( + PrincipalField::Emails, + PrincipalValue::String("john.doe@example.org".to_string()), + ) + ])) + .await + .is_ok() + ); let mut principal = store .query(QueryBy::Name("john.doe"), true) @@ -475,30 +485,34 @@ async fn internal_directory() { ); // Remove a member from a mailing list and then add it back - assert!(store - .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ - PrincipalUpdate::remove_item( - PrincipalField::Members, - PrincipalValue::String("john.doe".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ + PrincipalUpdate::remove_item( + PrincipalField::Members, + PrincipalValue::String("john.doe".to_string()), + ) + ])) + .await + .is_ok() + ); assert_list_members( &store, "list@example.org", ["jane@example.org", "mike@other.org", "lucy@foobar.net"], ) .await; - assert!(store - .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ - PrincipalUpdate::add_item( - PrincipalField::Members, - PrincipalValue::String("john.doe".to_string()), - ) - ])) - .await - .is_ok()); + assert!( + store + .update_principal(UpdatePrincipal::by_name("list").with_updates(vec![ + PrincipalUpdate::add_item( + PrincipalField::Members, + PrincipalValue::String("john.doe".to_string()), + ) + ])) + .await + .is_ok() + ); assert_list_members( &store, "list@example.org", @@ -738,7 +752,7 @@ async fn internal_directory() { #[allow(async_fn_in_trait)] pub trait TestInternalDirectory { async fn create_test_user(&self, login: &str, secret: &str, name: &str, emails: &[&str]) - -> u32; + -> u32; async fn create_test_group(&self, login: &str, name: &str, emails: &[&str]) -> u32; async fn create_test_list(&self, login: &str, name: &str, emails: &[&str]) -> u32; async fn set_test_quota(&self, login: &str, quota: u32); diff --git a/tests/src/directory/ldap.rs b/tests/src/directory/ldap.rs index ea2d5e39..997a925a 100644 --- a/tests/src/directory/ldap.rs +++ b/tests/src/directory/ldap.rs @@ -7,13 +7,13 @@ use std::fmt::Debug; use directory::{ - backend::{internal::manage::ManageDirectory, RcptType}, - QueryBy, Type, ROLE_USER, + QueryBy, ROLE_USER, Type, + backend::{RcptType, internal::manage::ManageDirectory}, }; use mail_send::Credentials; use crate::directory::{ - map_account_id, map_account_ids, DirectoryTest, IntoTestPrincipal, TestPrincipal, + DirectoryTest, IntoTestPrincipal, TestPrincipal, map_account_id, map_account_ids, }; #[tokio::test] @@ -96,17 +96,19 @@ async fn ldap_directory() { } .into_sorted() ); - assert!(handle - .query( - QueryBy::Credentials(&Credentials::Plain { - username: "bill".to_string(), - secret: "invalid".to_string() - }), - true - ) - .await - .unwrap() - .is_none()); + assert!( + handle + .query( + QueryBy::Credentials(&Credentials::Plain { + username: "bill".to_string(), + secret: "invalid".to_string() + }), + true + ) + .await + .unwrap() + .is_none() + ); // Get user by name assert_eq!( diff --git a/tests/src/directory/mod.rs b/tests/src/directory/mod.rs index dfb1b894..a7dfd547 100644 --- a/tests/src/directory/mod.rs +++ b/tests/src/directory/mod.rs @@ -11,10 +11,10 @@ pub mod oidc; pub mod smtp; pub mod sql; -use common::{config::smtp::session::AddressMapping, Core, Server}; +use common::{Core, Server, config::smtp::session::AddressMapping}; use directory::{ - backend::internal::{manage::ManageDirectory, PrincipalField}, Directories, Principal, Type, + backend::internal::{PrincipalField, manage::ManageDirectory}, }; use mail_send::Credentials; use rustls::ServerConfig; @@ -24,7 +24,7 @@ use std::{borrow::Cow, io::BufReader, sync::Arc}; use store::{Store, Stores}; use tokio_rustls::TlsAcceptor; -use crate::{store::TempDir, AssertConfig}; +use crate::{AssertConfig, store::TempDir}; const CONFIG: &str = r#" [directory."rocksdb"] diff --git a/tests/src/directory/smtp.rs b/tests/src/directory/smtp.rs index 14123cd2..3f74b132 100644 --- a/tests/src/directory/smtp.rs +++ b/tests/src/directory/smtp.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use common::listener::limiter::{ConcurrencyLimiter, InFlight}; -use directory::{backend::RcptType, QueryBy}; +use directory::{QueryBy, backend::RcptType}; use mail_parser::decoders::base64::base64_decode; use mail_send::Credentials; use tokio::{ diff --git a/tests/src/imap/acl.rs b/tests/src/imap/acl.rs index 156ba1f3..fd38e1ae 100644 --- a/tests/src/imap/acl.rs +++ b/tests/src/imap/acl.rs @@ -8,7 +8,7 @@ use imap_proto::ResponseType; use crate::jmap::delivery::SmtpConnection; -use super::{append::assert_append_message, AssertResult, ImapConnection, Type}; +use super::{AssertResult, ImapConnection, Type, append::assert_append_message}; pub async fn test(mut imap_john: &mut ImapConnection, _imap_check: &mut ImapConnection) { // Delivery to support account diff --git a/tests/src/imap/append.rs b/tests/src/imap/append.rs index bebf8eb6..2fc2899a 100644 --- a/tests/src/imap/append.rs +++ b/tests/src/imap/append.rs @@ -10,7 +10,7 @@ use imap_proto::ResponseType; use crate::jmap::wait_for_index; -use super::{resources_dir, AssertResult, IMAPTest, ImapConnection, Type}; +use super::{AssertResult, IMAPTest, ImapConnection, Type, resources_dir}; pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection, handle: &IMAPTest) { println!("Running APPEND tests..."); @@ -32,7 +32,7 @@ pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection, h let mut expected_uid = 1; for file_name in entries.into_iter().take(20) { - if file_name.extension().is_none_or( |e| e != "txt") { + if file_name.extension().is_none_or(|e| e != "txt") { continue; } let raw_message = fs::read(&file_name).unwrap(); diff --git a/tests/src/imap/condstore.rs b/tests/src/imap/condstore.rs index 244b31bc..4fca54a0 100644 --- a/tests/src/imap/condstore.rs +++ b/tests/src/imap/condstore.rs @@ -7,8 +7,8 @@ use imap_proto::ResponseType; use crate::imap::{ - append::{assert_append_message, build_messages}, AssertResult, + append::{assert_append_message, build_messages}, }; use super::{ImapConnection, Type}; diff --git a/tests/src/imap/thread.rs b/tests/src/imap/thread.rs index 87559147..5553a4c4 100644 --- a/tests/src/imap/thread.rs +++ b/tests/src/imap/thread.rs @@ -6,9 +6,9 @@ use imap_proto::ResponseType; -use crate::imap::{expand_uid_list, AssertResult}; +use crate::imap::{AssertResult, expand_uid_list}; -use super::{append::build_messages, ImapConnection, Type}; +use super::{ImapConnection, Type, append::build_messages}; pub async fn test(imap: &mut ImapConnection, _imap_check: &mut ImapConnection) { println!("Running THREAD tests..."); diff --git a/tests/src/jmap/auth_acl.rs b/tests/src/jmap/auth_acl.rs index 9c614e02..74f7bb7a 100644 --- a/tests/src/jmap/auth_acl.rs +++ b/tests/src/jmap/auth_acl.rs @@ -10,7 +10,7 @@ use jmap_client::{ error::{MethodError, MethodErrorType}, set::{SetError, SetErrorType}, }, - email::{self, import::EmailImportResponse, query::Filter, Property}, + email::{self, Property, import::EmailImportResponse, query::Filter}, mailbox::{self, Role}, principal::ACL, }; @@ -214,15 +214,17 @@ pub async fn test(params: &mut JMAPTest) { ); // John should not have access to emails in Jane's Trash folder - assert!(john_client - .set_default_account_id(jane_id.to_string()) - .email_get( - email_ids.get("jane").unwrap().last().unwrap(), - [Property::Subject].into(), - ) - .await - .unwrap() - .is_none()); + assert!( + john_client + .set_default_account_id(jane_id.to_string()) + .email_get( + email_ids.get("jane").unwrap().last().unwrap(), + [Property::Subject].into(), + ) + .await + .unwrap() + .is_none() + ); // John should only be able to copy blobs he has access to let blob_id = jane_client @@ -642,10 +644,12 @@ pub async fn test(params: &mut JMAPTest) { .await, ); john_client.refresh_session().await.unwrap(); - assert!(john_client - .session() - .account(&jane_id.to_string()) - .is_none()); + assert!( + john_client + .session() + .account(&jane_id.to_string()) + .is_none() + ); assert_eq!( bill_client .set_default_account_id(jane_id.to_string()) @@ -685,11 +689,13 @@ pub async fn test(params: &mut JMAPTest) { .name(), "sales@example.com" ); - assert!(!john_client - .session() - .account(&sales_id.to_string()) - .unwrap() - .is_personal()); + assert!( + !john_client + .session() + .account(&sales_id.to_string()) + .unwrap() + .is_personal() + ); assert_eq!( jane_client .session() @@ -698,10 +704,12 @@ pub async fn test(params: &mut JMAPTest) { .name(), "sales@example.com" ); - assert!(bill_client - .session() - .account(&sales_id.to_string()) - .is_none()); + assert!( + bill_client + .session() + .account(&sales_id.to_string()) + .is_none() + ); // Insert a message in Sales's inbox let blob_id = john_client diff --git a/tests/src/jmap/auth_limits.rs b/tests/src/jmap/auth_limits.rs index dab06f6e..5e768cf8 100644 --- a/tests/src/jmap/auth_limits.rs +++ b/tests/src/jmap/auth_limits.rs @@ -173,10 +173,12 @@ pub async fn test(params: &mut JMAPTest) { .size(), 5000000 ); - assert!(client - .upload(None, vec![b'A'; 5000001], None) - .await - .is_err()); + assert!( + client + .upload(None, vec![b'A'; 5000001], None) + .await + .is_err() + ); // Users should be allowed to create identities only // using email addresses associated to their principal diff --git a/tests/src/jmap/email_copy.rs b/tests/src/jmap/email_copy.rs index dae35803..a16c00fe 100644 --- a/tests/src/jmap/email_copy.rs +++ b/tests/src/jmap/email_copy.rs @@ -92,13 +92,15 @@ pub async fn test(params: &mut JMAPTest) { assert_eq!(email.received_at().unwrap(), 311923920); // Check that the email was deleted - assert!(params - .client - .set_default_account_id(Id::new(1).to_string()) - .email_get(&ac1_email_id, None::>) - .await - .unwrap() - .is_none()); + assert!( + params + .client + .set_default_account_id(Id::new(1).to_string()) + .email_get(&ac1_email_id, None::>) + .await + .unwrap() + .is_none() + ); // Empty store destroy_all_mailboxes(params).await; diff --git a/tests/src/jmap/email_query.rs b/tests/src/jmap/email_query.rs index 7b1daf6e..0b445fb3 100644 --- a/tests/src/jmap/email_query.rs +++ b/tests/src/jmap/email_query.rs @@ -21,7 +21,7 @@ use mail_parser::{DateTime, HeaderName}; use store::{ ahash::AHashMap, - write::{now, BatchBuilder, ValueClass}, + write::{BatchBuilder, ValueClass, now}, }; use super::JMAPTest; diff --git a/tests/src/jmap/email_search_snippet.rs b/tests/src/jmap/email_search_snippet.rs index 2fb05a7a..0788a44c 100644 --- a/tests/src/jmap/email_search_snippet.rs +++ b/tests/src/jmap/email_search_snippet.rs @@ -119,10 +119,11 @@ pub async fn test(params: &mut JMAPTest) { "html", Some("Die Hasen und die Frösche"), Some(concat!( - "und die Frösche Die Hasen klagten einst über ihre mißliche Lage; ", - ""wir leben", sprach ein Redner, "in steter Furcht vor Menschen und ", - "Tieren, eine Beute der Hunde, der Adler, ja fast aller Raubtiere! ", - "Unsere stete Angst ist är")), + "und die Frösche Die Hasen klagten einst über ihre mißliche Lage; ", + ""wir leben", sprach ein Redner, "in steter Furcht vor Menschen und ", + "Tieren, eine Beute der Hunde, der Adler, ja fast aller Raubtiere! ", + "Unsere stete Angst ist är" + )), ), ( Filter::text("es:galería vasto biblioteca").into(), diff --git a/tests/src/jmap/event_source.rs b/tests/src/jmap/event_source.rs index f7f8e1bf..6f8b659b 100644 --- a/tests/src/jmap/event_source.rs +++ b/tests/src/jmap/event_source.rs @@ -16,7 +16,7 @@ use crate::{ use email::mailbox::INBOX_ID; use futures::StreamExt; -use jmap_client::{event_source::Changes, mailbox::Role, TypeState}; +use jmap_client::{TypeState, event_source::Changes, mailbox::Role}; use jmap_proto::types::id::Id; use store::ahash::AHashSet; diff --git a/tests/src/jmap/mailbox.rs b/tests/src/jmap/mailbox.rs index 87cbb274..b69dad9b 100644 --- a/tests/src/jmap/mailbox.rs +++ b/tests/src/jmap/mailbox.rs @@ -5,13 +5,13 @@ */ use jmap_client::{ + Error, Set, client::Client, core::{ query::Filter, set::{SetError, SetErrorType, SetObject, SetRequest}, }, mailbox::{self, Mailbox, Role}, - Error, Set, }; use jmap_proto::types::{id::Id, state::State}; use serde::{Deserialize, Serialize}; @@ -19,7 +19,7 @@ use store::ahash::AHashMap; use crate::jmap::assert_is_empty; -use super::{wait_for_index, JMAPTest}; +use super::{JMAPTest, wait_for_index}; pub async fn test(params: &mut JMAPTest) { println!("Running Mailbox tests..."); @@ -299,12 +299,14 @@ pub async fn test(params: &mut JMAPTest) { .update(&id_map["1.1.1.1.1"]) .name("Renamed and moved") .parent_id((&id_map["l.2"]).into()); - assert!(request - .send_set_mailbox() - .await - .unwrap() - .updated(&id_map["1.1.1.1.1"]) - .is_ok()); + assert!( + request + .send_set_mailbox() + .await + .unwrap() + .updated(&id_map["1.1.1.1.1"]) + .is_ok() + ); // Verify changes let state = client.mailbox_changes(state, 0).await.unwrap(); @@ -494,24 +496,30 @@ pub async fn test(params: &mut JMAPTest) { .destroy([&id_map["trash"]]) .arguments() .on_destroy_remove_emails(true); - assert!(request - .send_set_mailbox() - .await - .unwrap() - .destroyed(&id_map["trash"]) - .is_ok()); + assert!( + request + .send_set_mailbox() + .await + .unwrap() + .destroyed(&id_map["trash"]) + .is_ok() + ); // Verify that Trash folder and its contents are gone - assert!(client - .mailbox_get(&id_map["trash"], None::>) - .await - .unwrap() - .is_none()); - assert!(client - .email_get(&mail_id, None::>) - .await - .unwrap() - .is_none()); + assert!( + client + .mailbox_get(&id_map["trash"], None::>) + .await + .unwrap() + .is_none() + ); + assert!( + client + .email_get(&mail_id, None::>) + .await + .unwrap() + .is_none() + ); // Check search results after changing folder properties let mut request = client.build(); @@ -522,12 +530,14 @@ pub async fn test(params: &mut JMAPTest) { .sort_order(100) .parent_id((&id_map["l.2"]).into()) .role(Role::None); - assert!(request - .send_set_mailbox() - .await - .unwrap() - .updated(&id_map["drafts"]) - .is_ok()); + assert!( + request + .send_set_mailbox() + .await + .unwrap() + .updated(&id_map["drafts"]) + .is_ok() + ); assert_eq!( client .mailbox_query( @@ -547,24 +557,28 @@ pub async fn test(params: &mut JMAPTest) { .collect::>(), ["drafts"] ); - assert!(client - .mailbox_query( - mailbox::query::Filter::name("Drafts").into(), - [mailbox::query::Comparator::name()].into() - ) - .await - .unwrap() - .ids() - .is_empty()); - assert!(client - .mailbox_query( - mailbox::query::Filter::role(Role::Drafts).into(), - [mailbox::query::Comparator::name()].into() - ) - .await - .unwrap() - .ids() - .is_empty()); + assert!( + client + .mailbox_query( + mailbox::query::Filter::name("Drafts").into(), + [mailbox::query::Comparator::name()].into() + ) + .await + .unwrap() + .ids() + .is_empty() + ); + assert!( + client + .mailbox_query( + mailbox::query::Filter::role(Role::Drafts).into(), + [mailbox::query::Comparator::name()].into() + ) + .await + .unwrap() + .ids() + .is_empty() + ); assert_eq!( client .mailbox_query( diff --git a/tests/src/jmap/sieve_script.rs b/tests/src/jmap/sieve_script.rs index 90973fc6..d29ce953 100644 --- a/tests/src/jmap/sieve_script.rs +++ b/tests/src/jmap/sieve_script.rs @@ -5,10 +5,10 @@ */ use jmap_client::{ + Error, core::set::{SetError, SetErrorType}, email, mailbox, sieve::query::{Comparator, Filter}, - Error, }; use jmap_proto::types::id::Id; use std::{ @@ -22,7 +22,7 @@ use crate::{ jmap::{ assert_is_empty, delivery::SmtpConnection, - email_submission::{assert_message_delivery, spawn_mock_smtp_server, MockMessage}, + email_submission::{MockMessage, assert_message_delivery, spawn_mock_smtp_server}, mailbox::destroy_all_mailboxes, }, smtp::DnsCache, diff --git a/tests/src/jmap/vacation_response.rs b/tests/src/jmap/vacation_response.rs index dc2f0d32..af26585e 100644 --- a/tests/src/jmap/vacation_response.rs +++ b/tests/src/jmap/vacation_response.rs @@ -15,7 +15,7 @@ use crate::{ assert_is_empty, delivery::SmtpConnection, email_submission::{ - assert_message_delivery, expect_nothing, spawn_mock_smtp_server, MockMessage, + MockMessage, assert_message_delivery, expect_nothing, spawn_mock_smtp_server, }, mailbox::destroy_all_mailboxes, }, diff --git a/tests/src/jmap/websocket.rs b/tests/src/jmap/websocket.rs index 36745164..ccecf042 100644 --- a/tests/src/jmap/websocket.rs +++ b/tests/src/jmap/websocket.rs @@ -7,12 +7,12 @@ use ahash::AHashSet; use futures::StreamExt; use jmap_client::{ + TypeState, client_ws::WebSocketMessage, core::{ response::{Response, TaggedMethodResponse}, set::SetObject, }, - TypeState, }; use jmap_proto::types::id::Id; use std::time::Duration; diff --git a/tests/src/smtp/config.rs b/tests/src/smtp/config.rs index cae1973e..d90703d8 100644 --- a/tests/src/smtp/config.rs +++ b/tests/src/smtp/config.rs @@ -7,12 +7,12 @@ use std::{fs, net::IpAddr, path::PathBuf, sync::Arc, time::Duration}; use common::{ + Server, config::{ server::{Listener, Listeners, ServerProtocol, TcpListener}, smtp::*, }, expr::{functions::ResolveVariable, if_block::*, tokenizer::TokenMap, *}, - Server, }; use throttle::parse_queue_rate_limiter; use tokio::net::TcpSocket; diff --git a/tests/src/smtp/inbound/asn.rs b/tests/src/smtp/inbound/asn.rs index 9f47d05b..9016d897 100644 --- a/tests/src/smtp/inbound/asn.rs +++ b/tests/src/smtp/inbound/asn.rs @@ -8,7 +8,7 @@ mod tests { use std::time::{Duration, Instant}; - use common::{config::network::AsnGeoLookupConfig, Core, Server}; + use common::{Core, Server, config::network::AsnGeoLookupConfig}; #[tokio::test] #[ignore] diff --git a/tests/src/smtp/inbound/auth.rs b/tests/src/smtp/inbound/auth.rs index 1542839c..d3629bd1 100644 --- a/tests/src/smtp/inbound/auth.rs +++ b/tests/src/smtp/inbound/auth.rs @@ -10,11 +10,11 @@ use store::Stores; use utils::config::Config; use crate::{ - smtp::{ - session::{TestSession, VerifyResponse}, - TempDir, TestSMTP, - }, AssertConfig, + smtp::{ + TempDir, TestSMTP, + session::{TestSession, VerifyResponse}, + }, }; use smtp::core::{Session, State}; diff --git a/tests/src/smtp/inbound/basic.rs b/tests/src/smtp/inbound/basic.rs index 62e0d978..bdca8d20 100644 --- a/tests/src/smtp/inbound/basic.rs +++ b/tests/src/smtp/inbound/basic.rs @@ -8,8 +8,8 @@ use common::Core; use smtp::core::Session; use crate::smtp::{ - session::{TestSession, VerifyResponse}, TestSMTP, + session::{TestSession, VerifyResponse}, }; #[tokio::test] diff --git a/tests/src/smtp/inbound/data.rs b/tests/src/smtp/inbound/data.rs index 5420e703..4c87ea11 100644 --- a/tests/src/smtp/inbound/data.rs +++ b/tests/src/smtp/inbound/data.rs @@ -9,12 +9,12 @@ use store::Stores; use utils::config::Config; use crate::{ - smtp::{ - inbound::TestMessage, - session::{load_test_message, TestSession, VerifyResponse}, - TempDir, TestSMTP, - }, AssertConfig, + smtp::{ + TempDir, TestSMTP, + inbound::TestMessage, + session::{TestSession, VerifyResponse, load_test_message}, + }, }; use smtp::core::Session; diff --git a/tests/src/smtp/inbound/dmarc.rs b/tests/src/smtp/inbound/dmarc.rs index 2192470b..35e4f5e9 100644 --- a/tests/src/smtp/inbound/dmarc.rs +++ b/tests/src/smtp/inbound/dmarc.rs @@ -6,7 +6,7 @@ use std::time::{Duration, Instant}; -use common::{config::smtp::report::AggregateFrequency, Core}; +use common::{Core, config::smtp::report::AggregateFrequency}; use mail_auth::{ common::{parse::TxtRecordParser, verify::DomainKey}, @@ -19,9 +19,9 @@ use store::Stores; use utils::config::Config; use crate::smtp::{ - inbound::{sign::SIGNATURES, TestMessage, TestReportingEvent}, - session::{TestSession, VerifyResponse}, DnsCache, TempDir, TestSMTP, + inbound::{TestMessage, TestReportingEvent, sign::SIGNATURES}, + session::{TestSession, VerifyResponse}, }; use smtp::core::Session; diff --git a/tests/src/smtp/inbound/ehlo.rs b/tests/src/smtp/inbound/ehlo.rs index d0a87684..607e5147 100644 --- a/tests/src/smtp/inbound/ehlo.rs +++ b/tests/src/smtp/inbound/ehlo.rs @@ -7,14 +7,14 @@ use std::time::{Duration, Instant}; use common::Core; -use mail_auth::{common::parse::TxtRecordParser, spf::Spf, SpfResult}; +use mail_auth::{SpfResult, common::parse::TxtRecordParser, spf::Spf}; use smtp::core::Session; use utils::config::Config; use crate::smtp::{ - session::{TestSession, VerifyResponse}, DnsCache, TestSMTP, + session::{TestSession, VerifyResponse}, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/inbound/limits.rs b/tests/src/smtp/inbound/limits.rs index dc39e5d1..299a23a0 100644 --- a/tests/src/smtp/inbound/limits.rs +++ b/tests/src/smtp/inbound/limits.rs @@ -13,8 +13,8 @@ use smtp::core::Session; use utils::config::Config; use crate::smtp::{ - session::{TestSession, VerifyResponse}, TestSMTP, + session::{TestSession, VerifyResponse}, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/inbound/mail.rs b/tests/src/smtp/inbound/mail.rs index e24eb947..7ae37f32 100644 --- a/tests/src/smtp/inbound/mail.rs +++ b/tests/src/smtp/inbound/mail.rs @@ -7,7 +7,7 @@ use std::time::{Duration, Instant, SystemTime}; use common::Core; -use mail_auth::{common::parse::TxtRecordParser, spf::Spf, IprevResult, SpfResult}; +use mail_auth::{IprevResult, SpfResult, common::parse::TxtRecordParser, spf::Spf}; use smtp_proto::{MAIL_BY_NOTIFY, MAIL_BY_RETURN, MAIL_REQUIRETLS}; use smtp::core::Session; @@ -15,8 +15,8 @@ use store::Stores; use utils::config::Config; use crate::smtp::{ - session::{TestSession, VerifyResponse}, DnsCache, TempDir, TestSMTP, + session::{TestSession, VerifyResponse}, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/inbound/rcpt.rs b/tests/src/smtp/inbound/rcpt.rs index b546f106..8021374c 100644 --- a/tests/src/smtp/inbound/rcpt.rs +++ b/tests/src/smtp/inbound/rcpt.rs @@ -15,8 +15,8 @@ use utils::config::Config; use smtp::core::{Session, State}; use crate::smtp::{ - session::{TestSession, VerifyResponse}, TempDir, TestSMTP, + session::{TestSession, VerifyResponse}, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/inbound/rewrite.rs b/tests/src/smtp/inbound/rewrite.rs index 4b17d70e..7bb55842 100644 --- a/tests/src/smtp/inbound/rewrite.rs +++ b/tests/src/smtp/inbound/rewrite.rs @@ -9,7 +9,7 @@ use common::Core; use smtp::core::Session; use utils::config::Config; -use crate::smtp::{session::TestSession, TestSMTP}; +use crate::smtp::{TestSMTP, session::TestSession}; const CONFIG: &str = r#" [session.mail] diff --git a/tests/src/smtp/inbound/scripts.rs b/tests/src/smtp/inbound/scripts.rs index c2dfcbbe..8aa40961 100644 --- a/tests/src/smtp/inbound/scripts.rs +++ b/tests/src/smtp/inbound/scripts.rs @@ -8,19 +8,18 @@ use core::panic; use std::{fmt::Write, fs, path::PathBuf}; use crate::{ - enable_logging, + AssertConfig, enable_logging, smtp::{ - inbound::{sign::SIGNATURES, TestMessage, TestQueueEvent}, - session::{TestSession, VerifyResponse}, TempDir, TestSMTP, + inbound::{TestMessage, TestQueueEvent, sign::SIGNATURES}, + session::{TestSession, VerifyResponse}, }, - AssertConfig, }; use common::Core; use smtp::{ core::Session, - scripts::{event_loop::RunScript, ScriptResult}, + scripts::{ScriptResult, event_loop::RunScript}, }; use store::Stores; use utils::config::Config; diff --git a/tests/src/smtp/inbound/throttle.rs b/tests/src/smtp/inbound/throttle.rs index 8536e523..cce7970b 100644 --- a/tests/src/smtp/inbound/throttle.rs +++ b/tests/src/smtp/inbound/throttle.rs @@ -6,7 +6,7 @@ use std::time::Duration; -use crate::smtp::{session::TestSession, TempDir, TestSMTP}; +use crate::smtp::{TempDir, TestSMTP, session::TestSession}; use common::Core; use smtp::core::{Session, SessionAddress}; use store::Stores; diff --git a/tests/src/smtp/inbound/vrfy.rs b/tests/src/smtp/inbound/vrfy.rs index 88952ec4..1e535f76 100644 --- a/tests/src/smtp/inbound/vrfy.rs +++ b/tests/src/smtp/inbound/vrfy.rs @@ -12,11 +12,11 @@ use utils::config::Config; use smtp::core::Session; use crate::{ - smtp::{ - session::{TestSession, VerifyResponse}, - TempDir, TestSMTP, - }, AssertConfig, + smtp::{ + TempDir, TestSMTP, + session::{TestSession, VerifyResponse}, + }, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/lookup/sql.rs b/tests/src/smtp/lookup/sql.rs index 83119c8b..ecd06fcc 100644 --- a/tests/src/smtp/lookup/sql.rs +++ b/tests/src/smtp/lookup/sql.rs @@ -7,13 +7,13 @@ use std::time::{Duration, Instant}; use common::{ - expr::{tokenizer::TokenMap, *}, Core, + expr::{tokenizer::TokenMap, *}, }; use directory::{ - backend::internal::{manage::ManageDirectory, PrincipalField, PrincipalValue}, Principal, QueryBy, Type, + backend::internal::{PrincipalField, PrincipalValue, manage::ManageDirectory}, }; use mail_auth::MX; use store::Stores; @@ -22,8 +22,8 @@ use utils::config::Config; use crate::{ directory::DirectoryStore, smtp::{ - session::{TestSession, VerifyResponse}, DnsCache, TempDir, TestSMTP, + session::{TestSession, VerifyResponse}, }, }; use smtp::{core::Session, queue::RecipientDomain}; diff --git a/tests/src/smtp/lookup/utils.rs b/tests/src/smtp/lookup/utils.rs index d395cf04..7af811a1 100644 --- a/tests/src/smtp/lookup/utils.rs +++ b/tests/src/smtp/lookup/utils.rs @@ -7,11 +7,11 @@ use std::time::{Duration, Instant}; use common::{ + Core, config::smtp::{ report::AggregateFrequency, resolver::{Mode, MxPattern, Policy}, }, - Core, }; use mail_auth::MX; @@ -98,9 +98,11 @@ async fn lookup_ip() { std::net::IpAddr::V4(v4) => v4, _ => unreachable!(), })); - assert!(resolve_result - .remote_ips - .contains(&"172.168.0.100".parse().unwrap())); + assert!( + resolve_result + .remote_ips + .contains(&"172.168.0.100".parse().unwrap()) + ); // Ipv6 strategy let mut config = Config::new(CONFIG_V6).unwrap(); @@ -133,9 +135,11 @@ async fn lookup_ip() { std::net::IpAddr::V6(v6) => v6, _ => unreachable!(), })); - assert!(resolve_result - .remote_ips - .contains(&"e:f::a".parse().unwrap())); + assert!( + resolve_result + .remote_ips + .contains(&"e:f::a".parse().unwrap()) + ); } #[test] diff --git a/tests/src/smtp/outbound/extensions.rs b/tests/src/smtp/outbound/extensions.rs index 02744719..bfca2da4 100644 --- a/tests/src/smtp/outbound/extensions.rs +++ b/tests/src/smtp/outbound/extensions.rs @@ -11,9 +11,9 @@ use mail_auth::MX; use smtp_proto::{MAIL_REQUIRETLS, MAIL_RET_HDRS, MAIL_SMTPUTF8, RCPT_NOTIFY_NEVER}; use crate::smtp::{ + DnsCache, TestSMTP, inbound::{TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - DnsCache, TestSMTP, }; const LOCAL: &str = r#" diff --git a/tests/src/smtp/outbound/fallback_relay.rs b/tests/src/smtp/outbound/fallback_relay.rs index a039ee74..d5446fce 100644 --- a/tests/src/smtp/outbound/fallback_relay.rs +++ b/tests/src/smtp/outbound/fallback_relay.rs @@ -10,7 +10,7 @@ use common::config::server::ServerProtocol; use mail_auth::MX; use store::write::now; -use crate::smtp::{session::TestSession, DnsCache, TestSMTP}; +use crate::smtp::{DnsCache, TestSMTP, session::TestSession}; const LOCAL: &str = r#" [queue.outbound] diff --git a/tests/src/smtp/outbound/ip_lookup.rs b/tests/src/smtp/outbound/ip_lookup.rs index 7fa451da..ed6013fe 100644 --- a/tests/src/smtp/outbound/ip_lookup.rs +++ b/tests/src/smtp/outbound/ip_lookup.rs @@ -9,7 +9,7 @@ use std::time::{Duration, Instant}; use common::config::server::ServerProtocol; use mail_auth::{IpLookupStrategy, MX}; -use crate::smtp::{session::TestSession, DnsCache, TestSMTP}; +use crate::smtp::{DnsCache, TestSMTP, session::TestSession}; const LOCAL: &str = r#" [session.rcpt] diff --git a/tests/src/smtp/outbound/lmtp.rs b/tests/src/smtp/outbound/lmtp.rs index 9482b838..d9bd429e 100644 --- a/tests/src/smtp/outbound/lmtp.rs +++ b/tests/src/smtp/outbound/lmtp.rs @@ -7,9 +7,9 @@ use std::time::{Duration, Instant}; use crate::smtp::{ + DnsCache, TestSMTP, inbound::TestMessage, session::{TestSession, VerifyResponse}, - DnsCache, TestSMTP, }; use common::{config::server::ServerProtocol, ipc::QueueEvent}; use smtp::queue::spool::SmtpSpool; diff --git a/tests/src/smtp/outbound/smtp.rs b/tests/src/smtp/outbound/smtp.rs index de97c9ed..92815e35 100644 --- a/tests/src/smtp/outbound/smtp.rs +++ b/tests/src/smtp/outbound/smtp.rs @@ -11,9 +11,9 @@ use mail_auth::MX; use store::write::now; use crate::smtp::{ + DnsCache, TestSMTP, inbound::{TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - DnsCache, TestSMTP, }; use smtp::queue::spool::SmtpSpool; diff --git a/tests/src/smtp/outbound/throttle.rs b/tests/src/smtp/outbound/throttle.rs index d5232738..d7694a6e 100644 --- a/tests/src/smtp/outbound/throttle.rs +++ b/tests/src/smtp/outbound/throttle.rs @@ -13,9 +13,9 @@ use mail_auth::MX; use store::write::now; use crate::smtp::{ - inbound::TestQueueEvent, queue::manager::new_message, session::TestSession, DnsCache, TestSMTP, + DnsCache, TestSMTP, inbound::TestQueueEvent, queue::manager::new_message, session::TestSession, }; -use smtp::queue::{throttle::IsAllowed, Domain, Message, QueueEnvelope, Schedule, Status}; +use smtp::queue::{Domain, Message, QueueEnvelope, Schedule, Status, throttle::IsAllowed}; const CONFIG: &str = r#" [session.rcpt] diff --git a/tests/src/smtp/outbound/tls.rs b/tests/src/smtp/outbound/tls.rs index f82341f1..e547fb20 100644 --- a/tests/src/smtp/outbound/tls.rs +++ b/tests/src/smtp/outbound/tls.rs @@ -11,9 +11,9 @@ use mail_auth::MX; use store::write::now; use crate::smtp::{ + DnsCache, TestSMTP, inbound::TestMessage, session::{TestSession, VerifyResponse}, - DnsCache, TestSMTP, }; const LOCAL: &str = r#" diff --git a/tests/src/smtp/queue/concurrent.rs b/tests/src/smtp/queue/concurrent.rs index f0dea570..604ca059 100644 --- a/tests/src/smtp/queue/concurrent.rs +++ b/tests/src/smtp/queue/concurrent.rs @@ -9,7 +9,7 @@ use std::time::{Duration, Instant}; use common::{config::server::ServerProtocol, core::BuildServer, ipc::QueueEvent}; use mail_auth::MX; -use crate::smtp::{session::TestSession, DnsCache, TestSMTP}; +use crate::smtp::{DnsCache, TestSMTP, session::TestSession}; use smtp::queue::manager::Queue; const LOCAL: &str = r#" diff --git a/tests/src/smtp/queue/manager.rs b/tests/src/smtp/queue/manager.rs index 2f9684cf..7aa03efe 100644 --- a/tests/src/smtp/queue/manager.rs +++ b/tests/src/smtp/queue/manager.rs @@ -8,7 +8,7 @@ use std::time::Duration; use mail_auth::hickory_resolver::proto::op::ResponseCode; -use smtp::queue::{spool::SmtpSpool, Domain, Message, Schedule, Status}; +use smtp::queue::{Domain, Message, Schedule, Status, spool::SmtpSpool}; use store::write::now; use crate::smtp::TestSMTP; @@ -94,9 +94,11 @@ fn delivery_events() { .unwrap(), message.domain("c").expires ); - assert!(message - .next_event_after(message.domain("c").expires) - .is_none()); + assert!( + message + .next_event_after(message.domain("c").expires) + .is_none() + ); if t == 0 { message.domains.reverse(); diff --git a/tests/src/smtp/queue/retry.rs b/tests/src/smtp/queue/retry.rs index e7bbb7af..c0c0b70a 100644 --- a/tests/src/smtp/queue/retry.rs +++ b/tests/src/smtp/queue/retry.rs @@ -7,9 +7,9 @@ use std::time::Duration; use crate::smtp::{ + TestSMTP, inbound::{TestMessage, TestQueueEvent}, session::{TestSession, VerifyResponse}, - TestSMTP, }; use ahash::AHashSet; use common::ipc::{QueueEvent, QueueEventStatus}; diff --git a/tests/src/smtp/reporting/analyze.rs b/tests/src/smtp/reporting/analyze.rs index bd971bca..145e3ab6 100644 --- a/tests/src/smtp/reporting/analyze.rs +++ b/tests/src/smtp/reporting/analyze.rs @@ -6,11 +6,11 @@ use std::time::Duration; -use crate::smtp::{inbound::TestQueueEvent, session::TestSession, TestSMTP}; +use crate::smtp::{TestSMTP, inbound::TestQueueEvent, session::TestSession}; use store::{ - write::{ReportClass, ValueClass}, IterateParams, ValueKey, + write::{ReportClass, ValueClass}, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/reporting/dmarc.rs b/tests/src/smtp/reporting/dmarc.rs index 93e2f1b3..08500919 100644 --- a/tests/src/smtp/reporting/dmarc.rs +++ b/tests/src/smtp/reporting/dmarc.rs @@ -20,9 +20,9 @@ use smtp::reporting::dmarc::DmarcReporting; use store::write::QueueClass; use crate::smtp::{ - inbound::{sign::SIGNATURES, TestMessage}, - session::VerifyResponse, DnsCache, TestSMTP, + inbound::{TestMessage, sign::SIGNATURES}, + session::VerifyResponse, }; const CONFIG: &str = r#" diff --git a/tests/src/smtp/reporting/scheduler.rs b/tests/src/smtp/reporting/scheduler.rs index 306339ef..31773466 100644 --- a/tests/src/smtp/reporting/scheduler.rs +++ b/tests/src/smtp/reporting/scheduler.rs @@ -182,10 +182,12 @@ fn report_strip_json() { testing: false, fo: None, }, - records: vec![Record::default() - .with_count(1) - .with_envelope_from("domain.net") - .with_envelope_to("other.org")], + records: vec![ + Record::default() + .with_count(1) + .with_envelope_from("domain.net") + .with_envelope_to("other.org"), + ], }; let mut s = serde_json::to_string(&d).unwrap(); s.truncate(s.len() - 2); diff --git a/tests/src/smtp/reporting/tls.rs b/tests/src/smtp/reporting/tls.rs index dc2d550e..ded74916 100644 --- a/tests/src/smtp/reporting/tls.rs +++ b/tests/src/smtp/reporting/tls.rs @@ -15,12 +15,12 @@ use mail_auth::{ }; use store::write::QueueClass; -use smtp::reporting::tls::{TlsReporting, TLS_HTTP_REPORT}; +use smtp::reporting::tls::{TLS_HTTP_REPORT, TlsReporting}; use crate::smtp::{ - inbound::{sign::SIGNATURES, TestMessage}, - session::VerifyResponse, TestSMTP, + inbound::{TestMessage, sign::SIGNATURES}, + session::VerifyResponse, }; const CONFIG: &str = r#" @@ -149,14 +149,18 @@ async fn report_tls() { assert_eq!(policy.summary.total_success, 0); assert_eq!(policy.policy.policy_domain, "foobar.org"); assert_eq!(policy.failure_details.len(), 2); - assert!(policy - .failure_details - .iter() - .any(|d| d.result_type == ResultType::StsPolicyFetchError)); - assert!(policy - .failure_details - .iter() - .any(|d| d.result_type == ResultType::StsPolicyInvalid)); + assert!( + policy + .failure_details + .iter() + .any(|d| d.result_type == ResultType::StsPolicyFetchError) + ); + assert!( + policy + .failure_details + .iter() + .any(|d| d.result_type == ResultType::StsPolicyInvalid) + ); } PolicyType::NoPolicyFound => { seen[2] = true; diff --git a/tests/src/smtp/session.rs b/tests/src/smtp/session.rs index f301c07e..00562bf8 100644 --- a/tests/src/smtp/session.rs +++ b/tests/src/smtp/session.rs @@ -7,11 +7,11 @@ use std::{borrow::Cow, path::PathBuf, sync::Arc}; use common::{ - config::server::ServerProtocol, - listener::{limiter::ConcurrencyLimiter, ServerInstance, SessionStream, TcpAcceptor}, Server, + config::server::ServerProtocol, + listener::{ServerInstance, SessionStream, TcpAcceptor, limiter::ConcurrencyLimiter}, }; -use rustls::{server::ResolvesServerCert, ServerConfig}; +use rustls::{ServerConfig, server::ResolvesServerCert}; use tokio::{ io::{AsyncRead, AsyncWrite}, sync::watch, diff --git a/tests/src/store/assign_id.rs b/tests/src/store/assign_id.rs index 8cb86c94..2cf3ef77 100644 --- a/tests/src/store/assign_id.rs +++ b/tests/src/store/assign_id.rs @@ -6,7 +6,7 @@ use std::collections::HashSet; -use store::{write::BatchBuilder, Store}; +use store::{Store, write::BatchBuilder}; pub async fn test(db: Store) { println!("Running Store ID assignment tests...");