Directory refactoring
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use directory::QueryBy;
|
||||
use mail_parser::decoders::base64::base64_decode;
|
||||
use mail_send::Credentials;
|
||||
use tokio::{
|
||||
@@ -78,7 +79,7 @@ async fn imap_directory() {
|
||||
assert_eq!(
|
||||
&LookupResult::from(
|
||||
handle
|
||||
.authenticate(item.as_credentials())
|
||||
.query(QueryBy::credentials(item.as_credentials()))
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some()
|
||||
@@ -98,7 +99,7 @@ async fn imap_directory() {
|
||||
tokio::spawn(async move {
|
||||
LookupResult::from(
|
||||
handle
|
||||
.authenticate(item.as_credentials())
|
||||
.query(QueryBy::credentials(item.as_credentials()))
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some(),
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use directory::{Principal, Type};
|
||||
use directory::{backend::internal::manage::ManageDirectory, Principal, QueryBy, Type};
|
||||
use mail_send::Credentials;
|
||||
|
||||
use crate::directory::parse_config;
|
||||
use crate::directory::{map_account_ids, parse_config, IntoSortedPrincipal};
|
||||
|
||||
#[tokio::test]
|
||||
async fn ldap_directory() {
|
||||
@@ -41,36 +41,52 @@ async fn ldap_directory() {
|
||||
// Obtain directory handle
|
||||
let mut config = parse_config().await;
|
||||
let handle = config.directories.directories.remove("ldap").unwrap();
|
||||
let base_store = config.stores.stores.get("sqlite").unwrap();
|
||||
|
||||
// Test authentication
|
||||
assert_eq!(
|
||||
handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "john".to_string(),
|
||||
secret: "12345".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "john".to_string(),
|
||||
secret: "12345".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
.unwrap()
|
||||
.into_sorted(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("john").await.unwrap().unwrap(),
|
||||
name: "john".to_string(),
|
||||
description: "John Doe".to_string().into(),
|
||||
secrets: vec!["12345".to_string()],
|
||||
typ: Type::Individual,
|
||||
member_of: vec!["sales".to_string()],
|
||||
member_of: map_account_ids(base_store, vec!["sales"]).await,
|
||||
emails: vec![
|
||||
"john@example.org".to_string(),
|
||||
"john.doe@example.org".to_string()
|
||||
],
|
||||
..Default::default()
|
||||
}
|
||||
.into_sorted()
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "password".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "password".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
.unwrap()
|
||||
.into_sorted(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("bill").await.unwrap().unwrap(),
|
||||
name: "bill".to_string(),
|
||||
description: "Bill Foobar".to_string().into(),
|
||||
secrets: vec![
|
||||
@@ -78,37 +94,53 @@ async fn ldap_directory() {
|
||||
],
|
||||
typ: Type::Individual,
|
||||
quota: 500000,
|
||||
emails: vec!["bill@example.org".to_string(),],
|
||||
..Default::default()
|
||||
}
|
||||
.into_sorted()
|
||||
);
|
||||
assert!(handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "invalid".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "invalid".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none());
|
||||
|
||||
// Get user by name
|
||||
let mut principal = handle.principal("jane").await.unwrap().unwrap();
|
||||
principal.member_of.sort_unstable();
|
||||
assert_eq!(
|
||||
principal,
|
||||
handle
|
||||
.query(QueryBy::name("jane").with_store(base_store))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.into_sorted(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("jane").await.unwrap().unwrap(),
|
||||
name: "jane".to_string(),
|
||||
description: "Jane Doe".to_string().into(),
|
||||
typ: Type::Individual,
|
||||
secrets: vec!["abcde".to_string()],
|
||||
member_of: vec!["sales".to_string(), "support".to_string()],
|
||||
member_of: map_account_ids(base_store, vec!["sales", "support"]).await,
|
||||
emails: vec!["jane@example.org".to_string(),],
|
||||
..Default::default()
|
||||
}
|
||||
.into_sorted()
|
||||
);
|
||||
|
||||
// Get group by name
|
||||
assert_eq!(
|
||||
handle.principal("sales").await.unwrap().unwrap(),
|
||||
handle
|
||||
.query(QueryBy::name("sales").with_store(base_store))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("sales").await.unwrap().unwrap(),
|
||||
name: "sales".to_string(),
|
||||
description: "sales".to_string().into(),
|
||||
typ: Type::Group,
|
||||
@@ -116,52 +148,48 @@ async fn ldap_directory() {
|
||||
}
|
||||
);
|
||||
|
||||
// Emails by id
|
||||
compare_sorted(
|
||||
handle.emails_by_name("john").await.unwrap(),
|
||||
vec![
|
||||
"john@example.org".to_string(),
|
||||
"john.doe@example.org".to_string(),
|
||||
],
|
||||
);
|
||||
compare_sorted(
|
||||
handle.emails_by_name("bill").await.unwrap(),
|
||||
vec!["bill@example.org".to_string()],
|
||||
);
|
||||
|
||||
// Ids by email
|
||||
compare_sorted(
|
||||
handle.names_by_email("jane@example.org").await.unwrap(),
|
||||
vec!["jane".to_string()],
|
||||
handle
|
||||
.email_to_ids("jane@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
handle
|
||||
.names_by_email("jane+alias@example.org")
|
||||
.email_to_ids("jane+alias@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["jane".to_string()],
|
||||
);
|
||||
compare_sorted(
|
||||
handle.names_by_email("info@example.org").await.unwrap(),
|
||||
vec!["john".to_string(), "jane".to_string(), "bill".to_string()],
|
||||
map_account_ids(base_store, vec!["jane"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
handle
|
||||
.names_by_email("info+alias@example.org")
|
||||
.email_to_ids("info@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["john".to_string(), "jane".to_string(), "bill".to_string()],
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
handle.names_by_email("unknown@example.org").await.unwrap(),
|
||||
Vec::<String>::new(),
|
||||
handle
|
||||
.email_to_ids("info+alias@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await,
|
||||
);
|
||||
compare_sorted(
|
||||
handle
|
||||
.email_to_ids("unknown@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
Vec::<u32>::new(),
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.names_by_email("anything@catchall.org")
|
||||
.email_to_ids("anything@catchall.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["robert".to_string()]
|
||||
map_account_ids(base_store, vec!["robert"]).await
|
||||
);
|
||||
|
||||
// Domain validation
|
||||
|
||||
@@ -27,13 +27,16 @@ pub mod smtp;
|
||||
pub mod sql;
|
||||
|
||||
use ::smtp::core::Lookup;
|
||||
use directory::{config::ConfigDirectory, AddressMapping, Directories};
|
||||
use directory::{
|
||||
backend::internal::manage::ManageDirectory, config::ConfigDirectory, AddressMapping,
|
||||
Directories, Principal,
|
||||
};
|
||||
use mail_send::Credentials;
|
||||
use rustls::ServerConfig;
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys};
|
||||
use rustls_pki_types::PrivateKeyDer;
|
||||
use std::{borrow::Cow, io::BufReader, path::PathBuf, sync::Arc};
|
||||
use store::{config::ConfigStore, LookupStore, Stores};
|
||||
use store::{config::ConfigStore, LookupStore, Store, Stores};
|
||||
use tokio_rustls::TlsAcceptor;
|
||||
|
||||
use crate::store::TempDir;
|
||||
@@ -164,10 +167,6 @@ verify = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(|(mail=*?*)(gi
|
||||
expand = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(sn=?))"
|
||||
domains = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(|(mail=*@?)(givenName=*@?)(sn=*@?)))"
|
||||
|
||||
[directory."ldap".object-classes]
|
||||
user = "posixAccount"
|
||||
group = "posixGroup"
|
||||
|
||||
# Glauth does not support searchable custom attributes so
|
||||
# 'sn' and 'givenName' are used to search for aliases/lists.
|
||||
|
||||
@@ -179,6 +178,7 @@ groups = ["memberOf", "otherGroups"]
|
||||
email = "mail"
|
||||
email-alias = "givenName"
|
||||
quota = "diskQuota"
|
||||
type = "objectClass"
|
||||
|
||||
##############################################################################
|
||||
|
||||
@@ -225,36 +225,41 @@ type = "memory"
|
||||
catch-all = true
|
||||
subaddressing = true
|
||||
|
||||
[[directory."local".users]]
|
||||
[[directory."local".principals]]
|
||||
name = "john"
|
||||
type = "individual"
|
||||
description = "John Doe"
|
||||
secret = "12345"
|
||||
email = ["john@example.org", "jdoe@example.org", "john.doe@example.org"]
|
||||
email-list = ["info@example.org"]
|
||||
member-of = ["sales"]
|
||||
|
||||
[[directory."local".users]]
|
||||
[[directory."local".principals]]
|
||||
name = "jane"
|
||||
type = "individual"
|
||||
description = "Jane Doe"
|
||||
secret = "abcde"
|
||||
email = "jane@example.org"
|
||||
email-list = ["info@example.org"]
|
||||
member-of = ["sales", "support"]
|
||||
|
||||
[[directory."local".users]]
|
||||
[[directory."local".principals]]
|
||||
name = "bill"
|
||||
type = "individual"
|
||||
description = "Bill Foobar"
|
||||
secret = "$2y$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe"
|
||||
quota = 500000
|
||||
email = "bill@example.org"
|
||||
email-list = ["info@example.org"]
|
||||
|
||||
[[directory."local".groups]]
|
||||
[[directory."local".principals]]
|
||||
name = "sales"
|
||||
type = "group"
|
||||
description = "Sales Team"
|
||||
|
||||
[[directory."local".groups]]
|
||||
[[directory."local".principals]]
|
||||
name = "support"
|
||||
type = "group"
|
||||
description = "Support Team"
|
||||
|
||||
"#;
|
||||
@@ -607,3 +612,23 @@ fn address_mappings() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async fn map_account_ids(store: &Store, names: Vec<impl AsRef<str>>) -> Vec<u32> {
|
||||
let mut ids = Vec::with_capacity(names.len());
|
||||
for name in names {
|
||||
ids.push(store.get_account_id(name.as_ref()).await.unwrap().unwrap());
|
||||
}
|
||||
ids
|
||||
}
|
||||
|
||||
trait IntoSortedPrincipal: Sized {
|
||||
fn into_sorted(self) -> Self;
|
||||
}
|
||||
|
||||
impl IntoSortedPrincipal for Principal {
|
||||
fn into_sorted(mut self) -> Self {
|
||||
self.member_of.sort_unstable();
|
||||
self.emails.sort_unstable();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use directory::DirectoryError;
|
||||
use directory::{DirectoryError, QueryBy};
|
||||
use mail_parser::decoders::base64::base64_decode;
|
||||
use mail_send::Credentials;
|
||||
use tokio::{
|
||||
@@ -96,7 +96,12 @@ async fn smtp_directory() {
|
||||
for (item, expected) in &tests {
|
||||
let result: LookupResult = match item {
|
||||
Item::IsAccount(v) => handle.rcpt(v).await.unwrap().into(),
|
||||
Item::Authenticate(v) => handle.authenticate(v).await.unwrap().is_some().into(),
|
||||
Item::Authenticate(v) => handle
|
||||
.query(QueryBy::credentials(v))
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some()
|
||||
.into(),
|
||||
Item::Verify(v) => match handle.vrfy(v).await {
|
||||
Ok(v) => v.into(),
|
||||
Err(DirectoryError::Unsupported) => LookupResult::False,
|
||||
@@ -123,7 +128,12 @@ async fn smtp_directory() {
|
||||
tokio::spawn(async move {
|
||||
let result: LookupResult = match &item {
|
||||
Item::IsAccount(v) => handle.rcpt(v).await.unwrap().into(),
|
||||
Item::Authenticate(v) => handle.authenticate(v).await.unwrap().is_some().into(),
|
||||
Item::Authenticate(v) => handle
|
||||
.query(QueryBy::credentials(v))
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some()
|
||||
.into(),
|
||||
Item::Verify(v) => match handle.vrfy(v).await {
|
||||
Ok(v) => v.into(),
|
||||
Err(DirectoryError::Unsupported) => LookupResult::False,
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
*/
|
||||
|
||||
use ahash::AHashMap;
|
||||
use directory::{Principal, Type};
|
||||
use directory::{backend::internal::manage::ManageDirectory, Principal, QueryBy, Type};
|
||||
use mail_send::Credentials;
|
||||
use smtp::core::Lookup;
|
||||
use store::{LookupStore, Store};
|
||||
|
||||
use crate::directory::parse_config;
|
||||
use crate::directory::{map_account_ids, parse_config};
|
||||
|
||||
use super::DirectoryStore;
|
||||
|
||||
@@ -57,6 +57,7 @@ async fn sql_directory() {
|
||||
let store = DirectoryStore {
|
||||
store: config.stores.lookup_stores.remove(directory_id).unwrap(),
|
||||
};
|
||||
let base_store = config.stores.stores.get(directory_id).unwrap();
|
||||
|
||||
// Create tables
|
||||
store.create_test_directory().await;
|
||||
@@ -132,32 +133,45 @@ async fn sql_directory() {
|
||||
// Test authentication
|
||||
assert_eq!(
|
||||
handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "john".to_string(),
|
||||
secret: "12345".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "john".to_string(),
|
||||
secret: "12345".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("john").await.unwrap().unwrap(),
|
||||
name: "john".to_string(),
|
||||
description: "John Doe".to_string().into(),
|
||||
secrets: vec!["12345".to_string()],
|
||||
typ: Type::Individual,
|
||||
member_of: vec!["sales".to_string()],
|
||||
member_of: map_account_ids(base_store, vec!["sales"]).await,
|
||||
emails: vec![
|
||||
"john@example.org".to_string(),
|
||||
"jdoe@example.org".to_string(),
|
||||
"john.doe@example.org".to_string()
|
||||
],
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "password".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "password".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("bill").await.unwrap().unwrap(),
|
||||
name: "bill".to_string(),
|
||||
description: "Bill Foobar".to_string().into(),
|
||||
secrets: vec![
|
||||
@@ -165,35 +179,50 @@ async fn sql_directory() {
|
||||
],
|
||||
typ: Type::Individual,
|
||||
quota: 500000,
|
||||
emails: vec!["bill@example.org".to_string(),],
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
assert!(handle
|
||||
.authenticate(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "invalid".to_string()
|
||||
})
|
||||
.query(
|
||||
QueryBy::credentials(&Credentials::Plain {
|
||||
username: "bill".to_string(),
|
||||
secret: "invalid".to_string()
|
||||
})
|
||||
.with_store(base_store)
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none());
|
||||
|
||||
// Get user by name
|
||||
assert_eq!(
|
||||
handle.principal("jane").await.unwrap().unwrap(),
|
||||
handle
|
||||
.query(QueryBy::name("jane").with_store(base_store))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("jane").await.unwrap().unwrap(),
|
||||
name: "jane".to_string(),
|
||||
description: "Jane Doe".to_string().into(),
|
||||
typ: Type::Individual,
|
||||
secrets: vec!["abcde".to_string()],
|
||||
member_of: vec!["sales".to_string(), "support".to_string()],
|
||||
member_of: map_account_ids(base_store, vec!["sales", "support"]).await,
|
||||
emails: vec!["jane@example.org".to_string(),],
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
// Get group by name
|
||||
assert_eq!(
|
||||
handle.principal("sales").await.unwrap().unwrap(),
|
||||
handle
|
||||
.query(QueryBy::name("sales").with_store(base_store))
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
Principal {
|
||||
id: base_store.get_account_id("sales").await.unwrap().unwrap(),
|
||||
name: "sales".to_string(),
|
||||
description: "Sales Team".to_string().into(),
|
||||
typ: Type::Group,
|
||||
@@ -201,53 +230,48 @@ async fn sql_directory() {
|
||||
}
|
||||
);
|
||||
|
||||
// Emails by id
|
||||
assert_eq!(
|
||||
handle.emails_by_name("john").await.unwrap(),
|
||||
vec![
|
||||
"john@example.org".to_string(),
|
||||
"jdoe@example.org".to_string(),
|
||||
"john.doe@example.org".to_string(),
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
handle.emails_by_name("bill").await.unwrap(),
|
||||
vec!["bill@example.org".to_string(),]
|
||||
);
|
||||
|
||||
// Ids by email
|
||||
assert_eq!(
|
||||
handle.names_by_email("jane@example.org").await.unwrap(),
|
||||
vec!["jane".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
handle.names_by_email("info@example.org").await.unwrap(),
|
||||
vec!["bill".to_string(), "jane".to_string(), "john".to_string()]
|
||||
handle
|
||||
.email_to_ids("jane@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["jane"]).await
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.names_by_email("jane+alias@example.org")
|
||||
.email_to_ids("info@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["jane".to_string()]
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.names_by_email("info+alias@example.org")
|
||||
.email_to_ids("jane+alias@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["bill".to_string(), "jane".to_string(), "john".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
handle.names_by_email("unknown@example.org").await.unwrap(),
|
||||
Vec::<String>::new()
|
||||
map_account_ids(base_store, vec!["jane"]).await
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.names_by_email("anything@catchall.org")
|
||||
.email_to_ids("info+alias@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["robert".to_string()]
|
||||
map_account_ids(base_store, vec!["bill", "jane", "john"]).await
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.email_to_ids("unknown@example.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
Vec::<u32>::new()
|
||||
);
|
||||
assert_eq!(
|
||||
handle
|
||||
.email_to_ids("anything@catchall.org", base_store)
|
||||
.await
|
||||
.unwrap(),
|
||||
map_account_ids(base_store, vec!["robert"]).await
|
||||
);
|
||||
|
||||
// Domain validation
|
||||
@@ -317,7 +341,7 @@ impl DirectoryStore {
|
||||
"CREATE TABLE emails (name TEXT NOT NULL, address TEXT NOT",
|
||||
" NULL, type TEXT, PRIMARY KEY (name, address))"
|
||||
),
|
||||
"INSERT INTO accounts (name, secret, type) VALUES ('admin', 'secret', 'individual')",
|
||||
"INSERT INTO accounts (name, secret, type) VALUES ('admin', 'secret', 'admin')",
|
||||
] {
|
||||
let query = if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
query.replace("TEXT", "VARCHAR(255)")
|
||||
@@ -333,25 +357,35 @@ impl DirectoryStore {
|
||||
}
|
||||
|
||||
pub async fn create_test_user(&self, login: &str, secret: &str, name: &str) {
|
||||
let account_type = if login == "admin" {
|
||||
"admin"
|
||||
} else {
|
||||
"individual"
|
||||
};
|
||||
self.store
|
||||
.query::<usize>(
|
||||
if matches!(self.store, LookupStore::Store(Store::PostgreSQL(_))) {
|
||||
concat!(
|
||||
"INSERT INTO accounts (name, secret, description, ",
|
||||
"type, active) VALUES ($1, $2, $3, 'individual', true) ON CONFLICT (name) DO NOTHING"
|
||||
"type, active) VALUES ($1, $2, $3, $4, true) ON CONFLICT (name) DO NOTHING"
|
||||
)
|
||||
} else if matches!(self.store, LookupStore::Store(Store::MySQL(_))) {
|
||||
concat!(
|
||||
"INSERT IGNORE INTO accounts (name, secret, description, ",
|
||||
"type, active) VALUES (?, ?, ?, 'individual', true)"
|
||||
"type, active) VALUES (?, ?, ?, ?, true)"
|
||||
)
|
||||
} else {
|
||||
concat!(
|
||||
"INSERT OR IGNORE INTO accounts (name, secret, description, ",
|
||||
"type, active) VALUES (?, ?, ?, 'individual', true)"
|
||||
"type, active) VALUES (?, ?, ?, ?, true)"
|
||||
)
|
||||
},
|
||||
vec![login.into(), secret.into(), name.into()],
|
||||
vec![
|
||||
login.into(),
|
||||
secret.into(),
|
||||
name.into(),
|
||||
account_type.into(),
|
||||
],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user