mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2024-09-20 07:16:18 +08:00
Test fixes - part 3
This commit is contained in:
parent
6b7dac0fcb
commit
d0303aefa8
|
@ -7,8 +7,9 @@
|
|||
use mail_send::Credentials;
|
||||
use store::{
|
||||
write::{DirectoryClass, ValueClass},
|
||||
IterateParams, Store, ValueKey,
|
||||
Deserialize, IterateParams, Store, ValueKey,
|
||||
};
|
||||
use trc::AddContext;
|
||||
|
||||
use crate::{Principal, QueryBy, Type};
|
||||
|
||||
|
@ -124,12 +125,16 @@ impl DirectoryStore for Store {
|
|||
ValueKey::from(ValueClass::Directory(DirectoryClass::EmailToId(
|
||||
vec![u8::MAX; 10],
|
||||
))),
|
||||
)
|
||||
.no_values(),
|
||||
|key, _| {
|
||||
),
|
||||
|key, value| {
|
||||
let key =
|
||||
std::str::from_utf8(key.get(1..).unwrap_or_default()).unwrap_or_default();
|
||||
if key.split('@').next().unwrap_or(key).contains(address) {
|
||||
if key.split('@').next().unwrap_or(key).contains(address)
|
||||
&& PrincipalInfo::deserialize(value)
|
||||
.caused_by(trc::location!())?
|
||||
.typ
|
||||
!= Type::List
|
||||
{
|
||||
results.push(key.to_string());
|
||||
}
|
||||
Ok(true)
|
||||
|
@ -143,15 +148,23 @@ impl DirectoryStore for Store {
|
|||
|
||||
async fn expn(&self, address: &str) -> trc::Result<Vec<String>> {
|
||||
let mut results = Vec::new();
|
||||
for account_id in self.email_to_ids(address).await? {
|
||||
if let Some(email) = self
|
||||
.get_value::<Principal>(ValueKey::from(ValueClass::Directory(
|
||||
DirectoryClass::Principal(account_id),
|
||||
)))
|
||||
.await?
|
||||
.and_then(|mut p| p.take_str(PrincipalField::Emails))
|
||||
{
|
||||
results.push(email);
|
||||
if let Some(ptype) = self
|
||||
.get_value::<PrincipalInfo>(ValueKey::from(ValueClass::Directory(
|
||||
DirectoryClass::EmailToId(address.as_bytes().to_vec()),
|
||||
)))
|
||||
.await?
|
||||
.filter(|p| p.typ == Type::List)
|
||||
{
|
||||
for account_id in self.get_members(ptype.id).await? {
|
||||
if let Some(email) = self
|
||||
.get_value::<Principal>(ValueKey::from(ValueClass::Directory(
|
||||
DirectoryClass::Principal(account_id),
|
||||
)))
|
||||
.await?
|
||||
.and_then(|mut p| p.take_str(PrincipalField::Emails))
|
||||
{
|
||||
results.push(email);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -942,23 +942,12 @@ impl ManageDirectory for Store {
|
|||
.or_else(|| change.field.map_internal_roles(&member))
|
||||
.ok_or_else(|| not_found(member.clone()))?;
|
||||
|
||||
let expected_type = match change.field {
|
||||
PrincipalField::MemberOf => Type::Group,
|
||||
PrincipalField::Lists => Type::List,
|
||||
PrincipalField::Roles => Type::Role,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if member_info.typ != expected_type {
|
||||
return Err(error(
|
||||
format!("Invalid {} value", change.field.as_str()),
|
||||
format!(
|
||||
"Principal {member:?} is not a {}.",
|
||||
expected_type.as_str()
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
validate_member_of(
|
||||
change.field,
|
||||
principal.inner.typ,
|
||||
member_info.typ,
|
||||
&member,
|
||||
)?;
|
||||
|
||||
if !member_of.contains(&member_info.id) {
|
||||
batch.set(
|
||||
|
@ -1009,23 +998,12 @@ impl ManageDirectory for Store {
|
|||
.ok_or_else(|| not_found(member.clone()))?;
|
||||
|
||||
if !member_of.contains(&member_info.id) {
|
||||
let expected_type = match change.field {
|
||||
PrincipalField::MemberOf => Type::Group,
|
||||
PrincipalField::Lists => Type::List,
|
||||
PrincipalField::Roles => Type::Role,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if member_info.typ != expected_type {
|
||||
return Err(error(
|
||||
format!("Invalid {} value", change.field.as_str()),
|
||||
format!(
|
||||
"Principal {member:?} is not a {}.",
|
||||
expected_type.as_str()
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
validate_member_of(
|
||||
change.field,
|
||||
principal.inner.typ,
|
||||
member_info.typ,
|
||||
&member,
|
||||
)?;
|
||||
|
||||
batch.set(
|
||||
ValueClass::Directory(DirectoryClass::MemberOf {
|
||||
|
@ -1664,6 +1642,38 @@ impl From<Principal> for MaybeDynamicValue {
|
|||
}
|
||||
}
|
||||
|
||||
fn validate_member_of(
|
||||
field: PrincipalField,
|
||||
typ: Type,
|
||||
member_type: Type,
|
||||
member_name: &str,
|
||||
) -> trc::Result<()> {
|
||||
let expected_types = match (field, typ) {
|
||||
(PrincipalField::MemberOf, Type::Individual) => &[Type::Group, Type::Individual][..],
|
||||
(PrincipalField::MemberOf, Type::Group) => &[Type::Group][..],
|
||||
(PrincipalField::Lists, Type::Individual | Type::Group) => &[Type::List][..],
|
||||
(PrincipalField::Roles, Type::Individual | Type::Tenant | Type::Role) => &[Type::Role][..],
|
||||
_ => &[][..],
|
||||
};
|
||||
|
||||
if expected_types.is_empty() || !expected_types.contains(&member_type) {
|
||||
Err(error(
|
||||
format!("Invalid {} value", field.as_str()),
|
||||
format!(
|
||||
"Principal {member_name:?} is not a {}.",
|
||||
expected_types
|
||||
.iter()
|
||||
.map(|t| t.as_str().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
.into(),
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct DynamicPrincipalInfo {
|
||||
typ: Type,
|
||||
|
|
|
@ -474,6 +474,24 @@ impl Store {
|
|||
.caused_by(trc::location!())?;
|
||||
}
|
||||
|
||||
// Delete property counters (TODO: make this more elegant)
|
||||
self.delete_range(
|
||||
ValueKey {
|
||||
account_id,
|
||||
collection: 1,
|
||||
document_id: 0,
|
||||
class: ValueClass::Property(84),
|
||||
},
|
||||
ValueKey {
|
||||
account_id,
|
||||
collection: 1,
|
||||
document_id: u32::MAX,
|
||||
class: ValueClass::Property(84),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.caused_by(trc::location!())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ use mail_send::Credentials;
|
|||
use store::{
|
||||
roaring::RoaringBitmap,
|
||||
write::{BatchBuilder, BitmapClass, ValueClass},
|
||||
BitmapKey, ValueKey,
|
||||
BitmapKey, Store, ValueKey,
|
||||
};
|
||||
|
||||
use crate::directory::{DirectoryTest, IntoTestPrincipal, TestPrincipal};
|
||||
|
@ -718,3 +718,197 @@ 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;
|
||||
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);
|
||||
async fn add_to_group(&self, login: &str, group: &str);
|
||||
async fn remove_from_group(&self, login: &str, group: &str);
|
||||
async fn remove_test_alias(&self, login: &str, alias: &str);
|
||||
async fn create_test_domains(&self, domains: &[&str]);
|
||||
}
|
||||
|
||||
impl TestInternalDirectory for Store {
|
||||
async fn create_test_user(
|
||||
&self,
|
||||
login: &str,
|
||||
secret: &str,
|
||||
name: &str,
|
||||
emails: &[&str],
|
||||
) -> u32 {
|
||||
let role = if login == "admin" { "admin" } else { "user" };
|
||||
self.create_test_domains(emails).await;
|
||||
if let Some(principal) = self.query(QueryBy::Name(login), false).await.unwrap() {
|
||||
self.update_principal(
|
||||
QueryBy::Id(principal.id()),
|
||||
vec![
|
||||
PrincipalUpdate::set(
|
||||
PrincipalField::Secrets,
|
||||
PrincipalValue::StringList(vec![secret.to_string()]),
|
||||
),
|
||||
PrincipalUpdate::set(
|
||||
PrincipalField::Description,
|
||||
PrincipalValue::String(name.to_string()),
|
||||
),
|
||||
PrincipalUpdate::set(
|
||||
PrincipalField::Emails,
|
||||
PrincipalValue::StringList(emails.iter().map(|s| s.to_string()).collect()),
|
||||
),
|
||||
PrincipalUpdate::add_item(
|
||||
PrincipalField::Roles,
|
||||
PrincipalValue::String(role.to_string()),
|
||||
),
|
||||
],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
principal.id()
|
||||
} else {
|
||||
self.create_principal(
|
||||
Principal::new(0, Type::Individual)
|
||||
.with_field(PrincipalField::Name, login.to_string())
|
||||
.with_field(PrincipalField::Description, name.to_string())
|
||||
.with_field(
|
||||
PrincipalField::Secrets,
|
||||
PrincipalValue::StringList(vec![secret.to_string()]),
|
||||
)
|
||||
.with_field(
|
||||
PrincipalField::Emails,
|
||||
PrincipalValue::StringList(emails.iter().map(|s| s.to_string()).collect()),
|
||||
)
|
||||
.with_field(
|
||||
PrincipalField::Roles,
|
||||
PrincipalValue::StringList(vec![role.to_string()]),
|
||||
),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_test_group(&self, login: &str, name: &str, emails: &[&str]) -> u32 {
|
||||
self.create_test_domains(emails).await;
|
||||
if let Some(principal) = self.query(QueryBy::Name(login), false).await.unwrap() {
|
||||
principal.id()
|
||||
} else {
|
||||
self.create_principal(
|
||||
Principal::new(0, Type::Group)
|
||||
.with_field(PrincipalField::Name, login.to_string())
|
||||
.with_field(PrincipalField::Description, name.to_string())
|
||||
.with_field(
|
||||
PrincipalField::Emails,
|
||||
PrincipalValue::StringList(emails.iter().map(|s| s.to_string()).collect()),
|
||||
)
|
||||
.with_field(
|
||||
PrincipalField::Roles,
|
||||
PrincipalValue::StringList(vec!["user".to_string()]),
|
||||
),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_test_list(&self, login: &str, name: &str, members: &[&str]) -> u32 {
|
||||
if let Some(principal) = self.query(QueryBy::Name(login), false).await.unwrap() {
|
||||
principal.id()
|
||||
} else {
|
||||
self.create_test_domains(&[login]).await;
|
||||
self.create_principal(
|
||||
Principal::new(0, Type::List)
|
||||
.with_field(PrincipalField::Name, login.to_string())
|
||||
.with_field(PrincipalField::Description, name.to_string())
|
||||
.with_field(
|
||||
PrincipalField::Members,
|
||||
PrincipalValue::StringList(members.iter().map(|s| s.to_string()).collect()),
|
||||
)
|
||||
.with_field(
|
||||
PrincipalField::Emails,
|
||||
PrincipalValue::StringList(vec![login.to_string()]),
|
||||
),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_test_quota(&self, login: &str, quota: u32) {
|
||||
self.update_principal(
|
||||
QueryBy::Name(login),
|
||||
vec![PrincipalUpdate::set(
|
||||
PrincipalField::Quota,
|
||||
PrincipalValue::Integer(quota as u64),
|
||||
)],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn add_to_group(&self, login: &str, group: &str) {
|
||||
self.update_principal(
|
||||
QueryBy::Name(login),
|
||||
vec![PrincipalUpdate::add_item(
|
||||
PrincipalField::MemberOf,
|
||||
PrincipalValue::String(group.to_string()),
|
||||
)],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn remove_from_group(&self, login: &str, group: &str) {
|
||||
self.update_principal(
|
||||
QueryBy::Name(login),
|
||||
vec![PrincipalUpdate::remove_item(
|
||||
PrincipalField::MemberOf,
|
||||
PrincipalValue::String(group.to_string()),
|
||||
)],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn remove_test_alias(&self, login: &str, alias: &str) {
|
||||
self.update_principal(
|
||||
QueryBy::Name(login),
|
||||
vec![PrincipalUpdate::remove_item(
|
||||
PrincipalField::Emails,
|
||||
PrincipalValue::String(alias.to_string()),
|
||||
)],
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn create_test_domains(&self, domains: &[&str]) {
|
||||
for domain in domains {
|
||||
let domain = domain.rsplit_once('@').map_or(*domain, |(_, d)| d);
|
||||
if self
|
||||
.query(QueryBy::Name(domain), false)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
self.create_principal(
|
||||
Principal::new(0, Type::Domain)
|
||||
.with_field(PrincipalField::Name, domain.to_string()),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ use common::{
|
|||
|
||||
use ::store::Stores;
|
||||
use ahash::AHashSet;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use imap::core::{ImapSessionManager, Inner, IMAP};
|
||||
use imap_proto::ResponseType;
|
||||
use jmap::{api::JmapSessionManager, JMAP};
|
||||
|
@ -49,7 +48,9 @@ use tokio::{
|
|||
};
|
||||
use utils::config::Config;
|
||||
|
||||
use crate::{add_test_certs, directory::DirectoryStore, store::TempDir, AssertConfig};
|
||||
use crate::{
|
||||
add_test_certs, directory::internal::TestInternalDirectory, store::TempDir, AssertConfig,
|
||||
};
|
||||
|
||||
const SERVER: &str = r#"
|
||||
[lookup.default]
|
||||
|
@ -98,7 +99,7 @@ reject-non-fqdn = false
|
|||
[session.rcpt]
|
||||
relay = [ { if = "!is_empty(authenticated_as)", then = true },
|
||||
{ else = false } ]
|
||||
directory = "'auth'"
|
||||
directory = "'{STORE}'"
|
||||
|
||||
[session.rcpt.errors]
|
||||
total = 5
|
||||
|
@ -187,7 +188,7 @@ data = "{STORE}"
|
|||
fts = "{STORE}"
|
||||
blob = "{STORE}"
|
||||
lookup = "{STORE}"
|
||||
directory = "auth"
|
||||
directory = "{STORE}"
|
||||
|
||||
[jmap.protocol]
|
||||
set.max-objects = 100000
|
||||
|
@ -252,17 +253,9 @@ verify = "SELECT address FROM emails WHERE address LIKE '%' || ? || '%' AND type
|
|||
expand = "SELECT p.address FROM emails AS p JOIN emails AS l ON p.name = l.name WHERE p.type = 'primary' AND l.address = ? AND l.type = 'list' ORDER BY p.address LIMIT 50"
|
||||
domains = "SELECT 1 FROM emails WHERE address LIKE '%@' || ? LIMIT 1"
|
||||
|
||||
[directory."auth"]
|
||||
type = "sql"
|
||||
store = "auth"
|
||||
|
||||
[directory."auth".columns]
|
||||
name = "name"
|
||||
description = "description"
|
||||
secret = "secret"
|
||||
email = "address"
|
||||
quota = "quota"
|
||||
class = "type"
|
||||
[directory."{STORE}"]
|
||||
type = "internal"
|
||||
store = "{STORE}"
|
||||
|
||||
[oauth]
|
||||
key = "parerga_und_paralipomena"
|
||||
|
@ -386,48 +379,56 @@ async fn init_imap_tests(store_id: &str, delete_if_exists: bool) -> IMAPTest {
|
|||
};
|
||||
});
|
||||
|
||||
// Create tables and test accounts
|
||||
let lookup = DirectoryStore {
|
||||
store: shared_core
|
||||
.load()
|
||||
.storage
|
||||
.lookups
|
||||
.get("auth")
|
||||
.unwrap()
|
||||
.clone(),
|
||||
};
|
||||
lookup.create_test_directory().await;
|
||||
lookup
|
||||
.create_test_user("admin", "secret", "Superuser")
|
||||
.await;
|
||||
lookup
|
||||
.create_test_user_with_email("jdoe@example.com", "secret", "John Doe")
|
||||
.await;
|
||||
lookup
|
||||
.create_test_user_with_email("jane.smith@example.com", "secret", "Jane Smith")
|
||||
.await;
|
||||
lookup
|
||||
.create_test_user_with_email("foobar@example.com", "secret", "Bill Foobar")
|
||||
.await;
|
||||
lookup
|
||||
.create_test_user_with_email("popper@example.com", "secret", "Karl Popper")
|
||||
.await;
|
||||
lookup
|
||||
.create_test_group_with_email("support@example.com", "Support Group")
|
||||
.await;
|
||||
lookup
|
||||
.add_to_group("jane.smith@example.com", "support@example.com")
|
||||
.await;
|
||||
|
||||
if delete_if_exists {
|
||||
store.destroy().await;
|
||||
}
|
||||
|
||||
// Assign Id 0 to admin (required for some tests)
|
||||
// Create tables and test accounts
|
||||
store
|
||||
.get_or_create_principal_id("admin", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap();
|
||||
.create_test_user("admin", "secret", "Superuser", &[])
|
||||
.await;
|
||||
store
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"secret",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
store
|
||||
.create_test_user(
|
||||
"jane.smith@example.com",
|
||||
"secret",
|
||||
"Jane Smith",
|
||||
&["jane.smith@example.com"],
|
||||
)
|
||||
.await;
|
||||
store
|
||||
.create_test_user(
|
||||
"foobar@example.com",
|
||||
"secret",
|
||||
"Bill Foobar",
|
||||
&["foobar@example.com"],
|
||||
)
|
||||
.await;
|
||||
store
|
||||
.create_test_user(
|
||||
"popper@example.com",
|
||||
"secret",
|
||||
"Karl Popper",
|
||||
&["popper@example.com"],
|
||||
)
|
||||
.await;
|
||||
store
|
||||
.create_test_group(
|
||||
"support@example.com",
|
||||
"Support Group",
|
||||
&["support@example.com"],
|
||||
)
|
||||
.await;
|
||||
store
|
||||
.add_to_group("jane.smith@example.com", "support@example.com")
|
||||
.await;
|
||||
|
||||
IMAPTest {
|
||||
jmap: JMAP::from(jmap.clone()).into(),
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::mailbox::{INBOX_ID, TRASH_ID};
|
||||
use jmap_client::{
|
||||
core::{
|
||||
|
@ -19,7 +18,10 @@ use jmap_proto::types::id::Id;
|
|||
use std::fmt::Debug;
|
||||
use store::ahash::AHashMap;
|
||||
|
||||
use crate::jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, test_account_login};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, test_account_login},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -31,53 +33,48 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
let inbox_id = Id::new(INBOX_ID as u64).to_string();
|
||||
let trash_id = Id::new(TRASH_ID as u64).to_string();
|
||||
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jane.smith@example.com", "abcde", "Jane Smith")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("bill@example.com", "098765", "Bill Foobar")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_group_with_email("sales@example.com", "Sales Group")
|
||||
.await;
|
||||
let john_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.into();
|
||||
let jane_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jane.smith@example.com", directory::Type::Individual)
|
||||
.create_test_user(
|
||||
"jane.smith@example.com",
|
||||
"abcde",
|
||||
"Jane Smith",
|
||||
&["jane.smith@example.com"],
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.into();
|
||||
let bill_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("bill@example.com", directory::Type::Individual)
|
||||
.create_test_user(
|
||||
"bill@example.com",
|
||||
"098765",
|
||||
"Bill Foobar",
|
||||
&["bill@example.com"],
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.into();
|
||||
let sales_id: Id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("sales@example.com", directory::Type::Individual)
|
||||
.create_test_group("sales@example.com", "Sales Group", &["sales@example.com"])
|
||||
.await
|
||||
.unwrap()
|
||||
.into();
|
||||
|
||||
// Authenticate all accounts
|
||||
|
@ -666,8 +663,10 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Add John and Jane to the Sales group
|
||||
for name in ["jdoe@example.com", "jane.smith@example.com"] {
|
||||
params
|
||||
.directory
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.add_to_group(name, "sales@example.com")
|
||||
.await;
|
||||
}
|
||||
|
@ -765,8 +764,10 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
);
|
||||
|
||||
// Remove John from the sales group
|
||||
params
|
||||
.directory
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.remove_from_group("jdoe@example.com", "sales@example.com")
|
||||
.await;
|
||||
server.inner.sessions.clear();
|
||||
|
|
|
@ -11,7 +11,6 @@ use std::{
|
|||
};
|
||||
|
||||
use common::listener::blocked::BLOCKED_IP_KEY;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use imap_proto::ResponseType;
|
||||
use jmap_client::{
|
||||
client::{Client, Credentials},
|
||||
|
@ -22,6 +21,7 @@ use jmap_proto::types::id::Id;
|
|||
use store::write::now;
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{ImapConnection, Type},
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes},
|
||||
};
|
||||
|
@ -33,24 +33,20 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com", "john.doe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
params
|
||||
.directory
|
||||
.link_test_address("jdoe@example.com", "john.doe@example.com", "alias")
|
||||
.await;
|
||||
|
||||
// Reset rate limiters
|
||||
server.inner.concurrency_limiter.clear();
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use bytes::Bytes;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::auth::oauth::{
|
||||
DeviceAuthResponse, ErrorType, OAuthCodeRequest, OAuthMetadata, TokenResponse,
|
||||
};
|
||||
|
@ -19,7 +18,10 @@ use jmap_proto::types::id::Id;
|
|||
use serde::de::DeserializeOwned;
|
||||
use store::ahash::AHashMap;
|
||||
|
||||
use crate::jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, ManagementApi};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, ManagementApi},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -36,18 +38,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let john_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
|
|
|
@ -4,32 +4,33 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::mailbox::INBOX_ID;
|
||||
use jmap_proto::types::id::Id;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::jmap::{assert_is_empty, jmap_json_request, mailbox::destroy_all_mailboxes};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, jmap_json_request, mailbox::destroy_all_mailboxes},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running blob tests...");
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
server.core.storage.data.blob_expire_all().await;
|
||||
|
||||
// Blob/set simple test
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::email::crypto::{
|
||||
try_parse_certs, Algorithm, EncryptMessage, EncryptionMethod, EncryptionParams, EncryptionType,
|
||||
};
|
||||
use jmap_proto::types::id::Id;
|
||||
use mail_parser::{MessageParser, MimeHeaders};
|
||||
|
||||
use crate::jmap::{delivery::SmtpConnection, ManagementApi};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{delivery::SmtpConnection, ManagementApi},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -23,18 +25,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::mailbox::{INBOX_ID, JUNK_ID};
|
||||
use jmap_proto::types::{collection::Collection, id::Id, property::Property};
|
||||
|
||||
|
@ -15,7 +14,10 @@ use tokio::{
|
|||
net::TcpStream,
|
||||
};
|
||||
|
||||
use crate::jmap::{assert_is_empty, mailbox::destroy_all_mailboxes};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -24,65 +26,54 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create a domain name and a test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jane@example.com", "abcdef", "Jane Smith")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("bill@example.com", "098765", "Bill Foobar")
|
||||
.await;
|
||||
let account_id_1 = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.to_string();
|
||||
let account_id_2 = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jane@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.to_string();
|
||||
let account_id_3 = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("bill@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.to_string();
|
||||
params
|
||||
.directory
|
||||
.link_test_address("jdoe@example.com", "john.doe@example.com", "alias")
|
||||
.await;
|
||||
let mut account_id_1 = String::new();
|
||||
let mut account_id_2 = String::new();
|
||||
let mut account_id_3 = String::new();
|
||||
|
||||
for (id, email, password, name, aliases) in [
|
||||
(
|
||||
&mut account_id_1,
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
Some(&["jdoe@example.com", "john.doe@example.com"][..]),
|
||||
),
|
||||
(
|
||||
&mut account_id_2,
|
||||
"jane@example.com",
|
||||
"abcdef",
|
||||
"Jane Smith",
|
||||
None,
|
||||
),
|
||||
(
|
||||
&mut account_id_3,
|
||||
"bill@example.com",
|
||||
"098765",
|
||||
"Bill Foobar",
|
||||
None,
|
||||
),
|
||||
] {
|
||||
*id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(email, password, name, aliases.unwrap_or(&[email][..]))
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
}
|
||||
|
||||
// Create a mailing list
|
||||
params
|
||||
.directory
|
||||
.link_test_address("jdoe@example.com", "members@example.com", "list")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.link_test_address("jane@example.com", "members@example.com", "list")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.link_test_address("bill@example.com", "members@example.com", "list")
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_list(
|
||||
"members@example.com",
|
||||
"Mailing List",
|
||||
&["jdoe@example.com", "jane@example.com", "bill@example.com"],
|
||||
)
|
||||
.await;
|
||||
|
||||
// Delivering to individuals
|
||||
|
@ -225,8 +216,11 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Removing members from the mailing list and chunked ingest
|
||||
params
|
||||
.directory
|
||||
.remove_test_alias("jdoe@example.com", "members@example.com")
|
||||
.server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.remove_from_group("jdoe@example.com", "members@example.com")
|
||||
.await;
|
||||
lmtp.ingest_chunked(
|
||||
"bill@example.com",
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
use ahash::AHashMap;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap_client::{
|
||||
core::set::{SetError, SetErrorType, SetObject},
|
||||
email_submission::{query::Filter, Address, Delivered, DeliveryStatus, Displayed, UndoStatus},
|
||||
|
@ -26,8 +25,9 @@ use tokio::{
|
|||
sync::mpsc,
|
||||
};
|
||||
|
||||
use crate::jmap::{
|
||||
assert_is_empty, email_set::assert_email_properties, mailbox::destroy_all_mailboxes,
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, email_set::assert_email_properties, mailbox::destroy_all_mailboxes},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
@ -76,22 +76,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create a test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.link_test_address("jdoe@example.com", "john.doe@example.com", "alias")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com", "john.doe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ use trc::{
|
|||
use utils::config::{cron::SimpleCron, Config};
|
||||
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{ImapConnection, Type},
|
||||
jmap::delivery::SmtpConnection,
|
||||
AssertConfig,
|
||||
|
@ -112,8 +113,17 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create test account
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "secret", "John Doe")
|
||||
.server
|
||||
.shared_core
|
||||
.load()
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"secret",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
|
||||
alerts(¶ms.server.shared_core.load()).await;
|
||||
|
@ -121,10 +131,39 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
tracing(params).await;
|
||||
metrics(params).await;
|
||||
|
||||
// Disable Enterprise
|
||||
let mut core = params.server.shared_core.load_full().as_ref().clone();
|
||||
core.enterprise = None;
|
||||
params.server.shared_core.store(core.into());
|
||||
params.server.shared_core.store(
|
||||
params
|
||||
.server
|
||||
.shared_core
|
||||
.load_full()
|
||||
.as_ref()
|
||||
.clone()
|
||||
.enable_enterprise()
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
pub trait EnterpriseCore {
|
||||
fn enable_enterprise(self) -> Self;
|
||||
}
|
||||
|
||||
impl EnterpriseCore for Core {
|
||||
fn enable_enterprise(mut self) -> Self {
|
||||
self.enterprise = Enterprise {
|
||||
license: LicenseKey {
|
||||
valid_to: now() + 3600,
|
||||
valid_from: now() - 3600,
|
||||
hostname: String::new(),
|
||||
accounts: 100,
|
||||
},
|
||||
undelete: None,
|
||||
trace_store: None,
|
||||
metrics_store: None,
|
||||
metrics_alerts: vec![],
|
||||
}
|
||||
.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
async fn alerts(core: &Core) {
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::jmap::{
|
||||
assert_is_empty, delivery::SmtpConnection, mailbox::destroy_all_mailboxes, test_account_login,
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
assert_is_empty, delivery::SmtpConnection, mailbox::destroy_all_mailboxes,
|
||||
test_account_login,
|
||||
},
|
||||
};
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use futures::StreamExt;
|
||||
use jmap::mailbox::INBOX_ID;
|
||||
use jmap_client::{event_source::Changes, mailbox::Role, TypeState};
|
||||
|
@ -25,20 +28,21 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
|
||||
let mut changes = client
|
||||
|
|
|
@ -23,7 +23,7 @@ use common::{
|
|||
manager::config::{ConfigManager, Patterns},
|
||||
Core, Ipc, IPC_CHANNEL_BUFFER,
|
||||
};
|
||||
use enterprise::insert_test_metrics;
|
||||
use enterprise::{insert_test_metrics, EnterpriseCore};
|
||||
use hyper::{header::AUTHORIZATION, Method};
|
||||
use imap::core::{ImapSessionManager, IMAP};
|
||||
use jmap::{api::JmapSessionManager, JMAP};
|
||||
|
@ -44,7 +44,9 @@ use tokio::sync::{mpsc, watch};
|
|||
use utils::{config::Config, map::ttl_dashmap::TtlMap, BlobHash};
|
||||
use webhooks::{spawn_mock_webhook_endpoint, MockWebhookEndpoint};
|
||||
|
||||
use crate::{add_test_certs, directory::DirectoryStore, store::TempDir, AssertConfig};
|
||||
use crate::{
|
||||
add_test_certs, directory::internal::TestInternalDirectory, store::TempDir, AssertConfig,
|
||||
};
|
||||
|
||||
pub mod auth_acl;
|
||||
pub mod auth_limits;
|
||||
|
@ -117,7 +119,7 @@ reject-non-fqdn = false
|
|||
[session.rcpt]
|
||||
relay = [ { if = "!is_empty(authenticated_as)", then = true },
|
||||
{ else = false } ]
|
||||
directory = "'auth'"
|
||||
directory = "'{STORE}'"
|
||||
|
||||
[session.rcpt.errors]
|
||||
total = 5
|
||||
|
@ -196,7 +198,7 @@ data = "{STORE}"
|
|||
fts = "{STORE}"
|
||||
blob = "{STORE}"
|
||||
lookup = "{STORE}"
|
||||
directory = "auth"
|
||||
directory = "{STORE}"
|
||||
|
||||
[spam.header]
|
||||
is-spam = "X-Spam-Status: Yes"
|
||||
|
@ -252,17 +254,9 @@ verify = "SELECT address FROM emails WHERE address LIKE '%' || ? || '%' AND type
|
|||
expand = "SELECT p.address FROM emails AS p JOIN emails AS l ON p.name = l.name WHERE p.type = 'primary' AND l.address = ? AND l.type = 'list' ORDER BY p.address LIMIT 50"
|
||||
domains = "SELECT 1 FROM emails WHERE address LIKE '%@' || ? LIMIT 1"
|
||||
|
||||
[directory."auth"]
|
||||
type = "sql"
|
||||
store = "auth"
|
||||
|
||||
[directory."auth".columns]
|
||||
name = "name"
|
||||
description = "description"
|
||||
secret = "secret"
|
||||
email = "address"
|
||||
quota = "quota"
|
||||
class = "type"
|
||||
[directory."{STORE}"]
|
||||
type = "internal"
|
||||
store = "{STORE}"
|
||||
|
||||
[imap.auth]
|
||||
allow-plain-text = true
|
||||
|
@ -316,7 +310,7 @@ pub async fn jmap_tests() {
|
|||
.await;
|
||||
|
||||
webhooks::test(&mut params).await;
|
||||
/*email_query::test(&mut params, delete).await;
|
||||
/* //email_query::test(&mut params, delete).await;
|
||||
email_get::test(&mut params).await;
|
||||
email_set::test(&mut params).await;
|
||||
email_parse::test(&mut params).await;
|
||||
|
@ -324,12 +318,12 @@ pub async fn jmap_tests() {
|
|||
email_changes::test(&mut params).await;
|
||||
email_query_changes::test(&mut params).await;
|
||||
email_copy::test(&mut params).await;
|
||||
thread_get::test(&mut params).await;
|
||||
thread_merge::test(&mut params).await;
|
||||
//thread_get::test(&mut params).await;
|
||||
//thread_merge::test(&mut params).await;
|
||||
mailbox::test(&mut params).await;
|
||||
delivery::test(&mut params).await;
|
||||
auth_acl::test(&mut params).await;
|
||||
auth_limits::test(&mut params).await;*/
|
||||
auth_limits::test(&mut params).await;
|
||||
auth_oauth::test(&mut params).await;
|
||||
event_source::test(&mut params).await;
|
||||
push_subscription::test(&mut params).await;
|
||||
|
@ -339,7 +333,7 @@ pub async fn jmap_tests() {
|
|||
websocket::test(&mut params).await;
|
||||
quota::test(&mut params).await;
|
||||
crypto::test(&mut params).await;
|
||||
blob::test(&mut params).await;
|
||||
blob::test(&mut params).await;*/
|
||||
purge::test(&mut params).await;
|
||||
enterprise::test(&mut params).await;
|
||||
|
||||
|
@ -378,7 +372,6 @@ pub async fn jmap_metric_tests() {
|
|||
pub struct JMAPTest {
|
||||
server: Arc<JMAP>,
|
||||
client: Client,
|
||||
directory: DirectoryStore,
|
||||
temp_dir: TempDir,
|
||||
webhook: Arc<MockWebhookEndpoint>,
|
||||
shutdown_tx: watch::Sender<bool>,
|
||||
|
@ -531,7 +524,9 @@ async fn init_jmap_tests(store_id: &str, delete_if_exists: bool) -> JMAPTest {
|
|||
.unwrap_or_default(),
|
||||
};
|
||||
let tracers = Telemetry::parse(&mut config, &stores);
|
||||
let core = Core::parse(&mut config, stores, config_manager).await;
|
||||
let core = Core::parse(&mut config, stores, config_manager)
|
||||
.await
|
||||
.enable_enterprise();
|
||||
let store = core.storage.data.clone();
|
||||
let shared_core = core.into_shared();
|
||||
|
||||
|
@ -599,25 +594,18 @@ async fn init_jmap_tests(store_id: &str, delete_if_exists: bool) -> JMAPTest {
|
|||
};
|
||||
});
|
||||
|
||||
// Create tables
|
||||
let directory = DirectoryStore {
|
||||
store: shared_core
|
||||
.load()
|
||||
.storage
|
||||
.lookups
|
||||
.get("auth")
|
||||
.unwrap()
|
||||
.clone(),
|
||||
};
|
||||
directory.create_test_directory().await;
|
||||
directory
|
||||
.create_test_user("admin", "secret", "Superuser")
|
||||
.await;
|
||||
|
||||
if delete_if_exists {
|
||||
store.destroy().await;
|
||||
}
|
||||
|
||||
// Create tables
|
||||
shared_core
|
||||
.load()
|
||||
.storage
|
||||
.data
|
||||
.create_test_user("admin", "secret", "Superuser", &[])
|
||||
.await;
|
||||
|
||||
// Create client
|
||||
let mut client = Client::new()
|
||||
.credentials(Credentials::basic("admin", "secret"))
|
||||
|
@ -632,7 +620,6 @@ async fn init_jmap_tests(store_id: &str, delete_if_exists: bool) -> JMAPTest {
|
|||
server: JMAP::from(jmap).into(),
|
||||
temp_dir,
|
||||
client,
|
||||
directory,
|
||||
shutdown_tx,
|
||||
webhook: spawn_mock_webhook_endpoint(),
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
use ahash::AHashSet;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use directory::{backend::internal::manage::ManageDirectory, QueryBy};
|
||||
use imap_proto::ResponseType;
|
||||
use jmap::{
|
||||
mailbox::{INBOX_ID, JUNK_ID, TRASH_ID},
|
||||
|
@ -17,7 +17,11 @@ use store::{
|
|||
IterateParams, LogKey, U32_LEN, U64_LEN,
|
||||
};
|
||||
|
||||
use crate::imap::{AssertResult, ImapConnection, Type};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
imap::{AssertResult, ImapConnection, Type},
|
||||
jmap::assert_is_empty,
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -30,17 +34,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
let junk_id = Id::from(JUNK_ID).to_string();
|
||||
|
||||
// Connect to IMAP
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap();
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut imap = ImapConnection::connect(b"_x ").await;
|
||||
imap.assert_read(Type::Untagged, ResponseType::Ok).await;
|
||||
imap.send("LOGIN \"jdoe@example.com\" \"12345\"").await;
|
||||
|
@ -188,6 +193,16 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
change
|
||||
);
|
||||
}
|
||||
|
||||
// Delete account
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.delete_principal(QueryBy::Id(account_id))
|
||||
.await
|
||||
.unwrap();
|
||||
assert_is_empty(server).await;
|
||||
}
|
||||
|
||||
async fn get_changes(server: &JMAP) -> AHashSet<(u64, u8)> {
|
||||
|
|
|
@ -14,7 +14,6 @@ use std::{
|
|||
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use common::{config::server::Servers, listener::SessionData, Core};
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use ece::EcKeyComponents;
|
||||
use hyper::{body, header::CONTENT_ENCODING, server::conn::http1, service::service_fn, StatusCode};
|
||||
use hyper_util::rt::TokioIo;
|
||||
|
@ -34,6 +33,7 @@ use utils::config::Config;
|
|||
|
||||
use crate::{
|
||||
add_test_certs,
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, test_account_login},
|
||||
AssertConfig,
|
||||
};
|
||||
|
@ -64,19 +64,20 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
|
||||
// Create test account
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
||||
params.client.set_default_account_id(account_id);
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use crate::jmap::{
|
||||
assert_is_empty, delivery::SmtpConnection, emails_purge_tombstoned, jmap_raw_request,
|
||||
mailbox::destroy_all_mailboxes, test_account_login,
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
assert_is_empty, delivery::SmtpConnection, emails_purge_tombstoned, jmap_raw_request,
|
||||
mailbox::destroy_all_mailboxes, test_account_login,
|
||||
},
|
||||
};
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap::{blob::upload::DISABLE_UPLOAD_QUOTA, mailbox::INBOX_ID};
|
||||
use jmap_client::{
|
||||
core::set::{SetErrorType, SetObject},
|
||||
|
@ -21,38 +23,43 @@ use super::JMAPTest;
|
|||
pub async fn test(params: &mut JMAPTest) {
|
||||
println!("Running quota tests...");
|
||||
let server = params.server.clone();
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("robert@example.com", "aabbcc", "Robert Foobar")
|
||||
.await;
|
||||
let other_account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("robert@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
params
|
||||
.directory
|
||||
let mut account_id = Id::from(0u64);
|
||||
let mut other_account_id = Id::from(0u64);
|
||||
|
||||
for (id, email, password, name) in [
|
||||
(
|
||||
&mut other_account_id,
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
),
|
||||
(
|
||||
&mut account_id,
|
||||
"robert@example.com",
|
||||
"aabbcc",
|
||||
"Robert Foobar",
|
||||
),
|
||||
] {
|
||||
*id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.create_test_user(email, password, name, &[email][..])
|
||||
.await,
|
||||
);
|
||||
}
|
||||
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.set_test_quota("robert@example.com", 1024)
|
||||
.await;
|
||||
params
|
||||
.directory
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.add_to_group("robert@example.com", "jdoe@example.com")
|
||||
.await;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap_client::{
|
||||
core::set::{SetError, SetErrorType},
|
||||
email, mailbox,
|
||||
|
@ -18,11 +17,14 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use crate::jmap::{
|
||||
assert_is_empty,
|
||||
delivery::SmtpConnection,
|
||||
email_submission::{assert_message_delivery, spawn_mock_smtp_server, MockMessage},
|
||||
mailbox::destroy_all_mailboxes,
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
assert_is_empty,
|
||||
delivery::SmtpConnection,
|
||||
email_submission::{assert_message_delivery, spawn_mock_smtp_server, MockMessage},
|
||||
mailbox::destroy_all_mailboxes,
|
||||
},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
@ -33,18 +35,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
let client = &mut params.client;
|
||||
|
||||
// Create test account
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
client.set_default_account_id(&account_id);
|
||||
|
|
|
@ -6,17 +6,19 @@
|
|||
|
||||
use chrono::{TimeDelta, Utc};
|
||||
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use jmap_proto::types::id::Id;
|
||||
use std::time::Instant;
|
||||
|
||||
use crate::jmap::{
|
||||
assert_is_empty,
|
||||
delivery::SmtpConnection,
|
||||
email_submission::{
|
||||
assert_message_delivery, expect_nothing, spawn_mock_smtp_server, MockMessage,
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{
|
||||
assert_is_empty,
|
||||
delivery::SmtpConnection,
|
||||
email_submission::{
|
||||
assert_message_delivery, expect_nothing, spawn_mock_smtp_server, MockMessage,
|
||||
},
|
||||
mailbox::destroy_all_mailboxes,
|
||||
},
|
||||
mailbox::destroy_all_mailboxes,
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
@ -27,18 +29,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
// Create test account
|
||||
let server = params.server.clone();
|
||||
let client = &mut params.client;
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
client.set_default_account_id(&account_id);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
use ahash::AHashSet;
|
||||
use directory::backend::internal::manage::ManageDirectory;
|
||||
use futures::StreamExt;
|
||||
use jmap_client::{
|
||||
client_ws::WebSocketMessage,
|
||||
|
@ -20,7 +19,10 @@ use std::time::Duration;
|
|||
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, test_account_login};
|
||||
use crate::{
|
||||
directory::internal::TestInternalDirectory,
|
||||
jmap::{assert_is_empty, mailbox::destroy_all_mailboxes, test_account_login},
|
||||
};
|
||||
|
||||
use super::JMAPTest;
|
||||
|
||||
|
@ -29,18 +31,18 @@ pub async fn test(params: &mut JMAPTest) {
|
|||
let server = params.server.clone();
|
||||
|
||||
// Authenticate all accounts
|
||||
params
|
||||
.directory
|
||||
.create_test_user_with_email("jdoe@example.com", "12345", "John Doe")
|
||||
.await;
|
||||
let account_id = Id::from(
|
||||
server
|
||||
.core
|
||||
.storage
|
||||
.data
|
||||
.get_or_create_principal_id("jdoe@example.com", directory::Type::Individual)
|
||||
.await
|
||||
.unwrap(),
|
||||
.create_test_user(
|
||||
"jdoe@example.com",
|
||||
"12345",
|
||||
"John Doe",
|
||||
&["jdoe@example.com"],
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.to_string();
|
||||
let client = test_account_login("jdoe@example.com", "12345").await;
|
||||
|
|
Loading…
Reference in a new issue