server: move domain::types to separate domain crate (#1086)

Preparation for using basic type definitions in other upcoming
modules, in particular for plugins.
This commit is contained in:
Simon Broeng Jensen
2025-02-03 23:00:27 +01:00
committed by GitHub
parent 417abc54e4
commit 1b26859141
47 changed files with 365 additions and 243 deletions
Generated
+21 -2
View File
@@ -2527,7 +2527,6 @@ dependencies = [
"graphql_client 0.11.0", "graphql_client 0.11.0",
"hmac 0.12.1", "hmac 0.12.1",
"http 0.2.12", "http 0.2.12",
"image",
"itertools", "itertools",
"juniper", "juniper",
"jwt 0.16.0", "jwt 0.16.0",
@@ -2536,6 +2535,7 @@ dependencies = [
"ldap3_proto", "ldap3_proto",
"lettre", "lettre",
"lldap_auth", "lldap_auth",
"lldap_domain",
"lldap_validation", "lldap_validation",
"log", "log",
"mockall", "mockall",
@@ -2551,7 +2551,6 @@ dependencies = [
"sea-orm", "sea-orm",
"secstr", "secstr",
"serde", "serde",
"serde_bytes",
"serde_json", "serde_json",
"serial_test", "serial_test",
"sha2 0.10.8", "sha2 0.10.8",
@@ -2625,6 +2624,26 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "lldap_domain"
version = "0.1.0"
dependencies = [
"anyhow",
"base64 0.21.7",
"bincode",
"chrono",
"derive_more 1.0.0",
"image",
"juniper",
"lldap_auth",
"pretty_assertions",
"sea-orm",
"serde",
"serde_bytes",
"strum",
"uuid 1.11.0",
]
[[package]] [[package]]
name = "lldap_migration_tool" name = "lldap_migration_tool"
version = "0.4.2" version = "0.4.2"
+6 -5
View File
@@ -1,10 +1,11 @@
[workspace] [workspace]
members = [ members = [
"server", "crates/domain",
"auth", "server",
"app", "auth",
"migration-tool", "app",
"set-password", "migration-tool",
"set-password",
] ]
default-members = ["server"] default-members = ["server"]
+59
View File
@@ -0,0 +1,59 @@
[package]
authors = [
"Valentin Tolmer <valentin@tolmer.fr>",
"Simon Broeng Jensen <sbj@cwconsult.dk>",
]
name = "lldap_domain"
version = "0.1.0"
edition = "2021"
[features]
test = []
[dependencies]
anyhow = "*"
base64 = "0.21"
bincode = "1.3"
juniper = "0.15"
serde = "*"
serde_bytes = "0.11"
[dev-dependencies]
pretty_assertions = "1"
[dependencies.chrono]
features = ["serde"]
version = "*"
[dependencies.derive_more]
features = ["debug", "display", "from", "from_str"]
default-features = false
version = "1"
[dependencies.image]
features = ["jpeg"]
default-features = false
version = "0.24"
[dependencies.lldap_auth]
path = "../../auth"
features = ["opaque_server", "opaque_client", "sea_orm"]
[dependencies.sea-orm]
version = "0.12"
default-features = false
features = [
"macros",
"with-chrono",
"with-uuid",
"sqlx-all",
"runtime-actix-rustls",
]
[dependencies.strum]
features = ["derive"]
version = "0.25"
[dependencies.uuid]
features = ["v1", "v3"]
version = "1"
+3
View File
@@ -0,0 +1,3 @@
pub mod requests;
pub mod schema;
pub mod types;
+53
View File
@@ -0,0 +1,53 @@
use serde::{Deserialize, Serialize};
use crate::types::{
AttributeName, AttributeType, AttributeValue, Email, GroupId, GroupName, JpegPhoto, UserId,
};
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct CreateUserRequest {
// Same fields as User, but no creation_date, and with password.
pub user_id: UserId,
pub email: Email,
pub display_name: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub avatar: Option<JpegPhoto>,
pub attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct UpdateUserRequest {
// Same fields as CreateUserRequest, but no with an extra layer of Option.
pub user_id: UserId,
pub email: Option<Email>,
pub display_name: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub avatar: Option<JpegPhoto>,
pub delete_attributes: Vec<AttributeName>,
pub insert_attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct CreateGroupRequest {
pub display_name: GroupName,
pub attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct UpdateGroupRequest {
pub group_id: GroupId,
pub display_name: Option<GroupName>,
pub delete_attributes: Vec<AttributeName>,
pub insert_attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct CreateAttributeRequest {
pub name: AttributeName,
pub attribute_type: AttributeType,
pub is_list: bool,
pub is_visible: bool,
pub is_editable: bool,
}
+39
View File
@@ -0,0 +1,39 @@
use serde::{Deserialize, Serialize};
use crate::types::{AttributeName, AttributeType, LdapObjectClass};
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct Schema {
pub user_attributes: AttributeList,
pub group_attributes: AttributeList,
pub extra_user_object_classes: Vec<LdapObjectClass>,
pub extra_group_object_classes: Vec<LdapObjectClass>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct AttributeSchema {
pub name: AttributeName,
//TODO: pub aliases: Vec<String>,
pub attribute_type: AttributeType,
pub is_list: bool,
pub is_visible: bool,
pub is_editable: bool,
pub is_hardcoded: bool,
pub is_readonly: bool,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct AttributeList {
pub attributes: Vec<AttributeSchema>,
}
impl AttributeList {
pub fn get_attribute_schema(&self, name: &AttributeName) -> Option<&AttributeSchema> {
self.attributes.iter().find(|a| a.name == *name)
}
pub fn get_attribute_type(&self, name: &AttributeName) -> Option<(AttributeType, bool)> {
self.get_attribute_schema(name)
.map(|a| (a.attribute_type, a.is_list))
}
}
@@ -11,7 +11,6 @@ use sea_orm::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::{EnumString, IntoStaticStr}; use strum::{EnumString, IntoStaticStr};
pub use super::model::UserColumn;
pub use lldap_auth::types::UserId; pub use lldap_auth::types::UserId;
#[derive( #[derive(
@@ -66,11 +65,11 @@ impl<'a> std::convert::TryFrom<&'a str> for Uuid {
} }
} }
#[cfg(test)] #[cfg(feature = "test")]
#[macro_export] #[macro_export]
macro_rules! uuid { macro_rules! uuid {
($s:literal) => { ($s:literal) => {
<$crate::domain::types::Uuid as std::convert::TryFrom<_>>::try_from($s).unwrap() <lldap_domain::types::Uuid as std::convert::TryFrom<_>>::try_from($s).unwrap()
}; };
} }
@@ -372,7 +371,7 @@ impl JpegPhoto {
self.0 self.0
} }
#[cfg(test)] #[cfg(any(feature = "test", test))]
pub fn for_tests() -> Self { pub fn for_tests() -> Self {
use image::{ImageOutputFormat, Rgb, RgbImage}; use image::{ImageOutputFormat, Rgb, RgbImage};
let img = RgbImage::from_fn(32, 32, |x, y| { let img = RgbImage::from_fn(32, 32, |x, y| {
@@ -424,7 +423,7 @@ pub struct User {
pub attributes: Vec<AttributeValue>, pub attributes: Vec<AttributeValue>,
} }
#[cfg(test)] #[cfg(feature = "test")]
impl Default for User { impl Default for User {
fn default() -> Self { fn default() -> Self {
let epoch = chrono::Utc.timestamp_opt(0, 0).unwrap().naive_utc(); let epoch = chrono::Utc.timestamp_opt(0, 0).unwrap().naive_utc();
+12 -11
View File
@@ -40,7 +40,6 @@ orion = "0.17"
rand_chacha = "0.3" rand_chacha = "0.3"
rustls-pemfile = "1" rustls-pemfile = "1"
serde = "*" serde = "*"
serde_bytes = "0.11"
serde_json = "1" serde_json = "1"
sha2 = "0.10" sha2 = "0.10"
thiserror = "*" thiserror = "*"
@@ -85,6 +84,13 @@ version = "0.10.1"
path = "../auth" path = "../auth"
features = ["opaque_server", "opaque_client", "sea_orm"] features = ["opaque_server", "opaque_client", "sea_orm"]
[dependencies.lldap_domain]
path = "../crates/domain"
[dev-dependencies.lldap_domain]
path = "../crates/domain"
features = ["test"]
[dependencies.lldap_validation] [dependencies.lldap_validation]
path = "../validation" path = "../validation"
@@ -119,20 +125,15 @@ version = "^0.1.6"
features = ["default", "rustls"] features = ["default", "rustls"]
version = "3" version = "3"
[dependencies.image]
features = ["jpeg"]
default-features = false
version = "0.24"
[dependencies.sea-orm] [dependencies.sea-orm]
version = "0.12" version = "0.12"
default-features = false default-features = false
features = [ features = [
"macros", "macros",
"with-chrono", "with-chrono",
"with-uuid", "with-uuid",
"sqlx-all", "sqlx-all",
"runtime-actix-rustls", "runtime-actix-rustls",
] ]
[dependencies.reqwest] [dependencies.reqwest]
+1 -1
View File
@@ -1,5 +1,5 @@
use crate::domain::types::{AttributeType, JpegPhoto, Serialized};
use anyhow::{bail, Context as AnyhowContext}; use anyhow::{bail, Context as AnyhowContext};
use lldap_domain::types::{AttributeType, JpegPhoto, Serialized};
pub fn deserialize_attribute_value( pub fn deserialize_attribute_value(
value: &[String], value: &[String],
+11 -90
View File
@@ -1,12 +1,16 @@
use crate::domain::{ use crate::domain::{error::Result, model::UserColumn};
error::Result, use async_trait::async_trait;
use lldap_domain::{
requests::{
CreateAttributeRequest, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
UpdateUserRequest,
},
schema::Schema,
types::{ types::{
AttributeName, AttributeType, AttributeValue, Email, Group, GroupDetails, GroupId, AttributeName, Group, GroupDetails, GroupId, GroupName, LdapObjectClass, Serialized, User,
GroupName, JpegPhoto, LdapObjectClass, Serialized, User, UserAndGroups, UserColumn, UserId, UserAndGroups, UserId, Uuid,
Uuid,
}, },
}; };
use async_trait::async_trait;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
@@ -99,90 +103,6 @@ impl From<bool> for GroupRequestFilter {
} }
} }
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct CreateUserRequest {
// Same fields as User, but no creation_date, and with password.
pub user_id: UserId,
pub email: Email,
pub display_name: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub avatar: Option<JpegPhoto>,
pub attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct UpdateUserRequest {
// Same fields as CreateUserRequest, but no with an extra layer of Option.
pub user_id: UserId,
pub email: Option<Email>,
pub display_name: Option<String>,
pub first_name: Option<String>,
pub last_name: Option<String>,
pub avatar: Option<JpegPhoto>,
pub delete_attributes: Vec<AttributeName>,
pub insert_attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone, Default)]
pub struct CreateGroupRequest {
pub display_name: GroupName,
pub attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct UpdateGroupRequest {
pub group_id: GroupId,
pub display_name: Option<GroupName>,
pub delete_attributes: Vec<AttributeName>,
pub insert_attributes: Vec<AttributeValue>,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct AttributeSchema {
pub name: AttributeName,
//TODO: pub aliases: Vec<String>,
pub attribute_type: AttributeType,
pub is_list: bool,
pub is_visible: bool,
pub is_editable: bool,
pub is_hardcoded: bool,
pub is_readonly: bool,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct CreateAttributeRequest {
pub name: AttributeName,
pub attribute_type: AttributeType,
pub is_list: bool,
pub is_visible: bool,
pub is_editable: bool,
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct AttributeList {
pub attributes: Vec<AttributeSchema>,
}
impl AttributeList {
pub fn get_attribute_schema(&self, name: &AttributeName) -> Option<&AttributeSchema> {
self.attributes.iter().find(|a| a.name == *name)
}
pub fn get_attribute_type(&self, name: &AttributeName) -> Option<(AttributeType, bool)> {
self.get_attribute_schema(name)
.map(|a| (a.attribute_type, a.is_list))
}
}
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)]
pub struct Schema {
pub user_attributes: AttributeList,
pub group_attributes: AttributeList,
pub extra_user_object_classes: Vec<LdapObjectClass>,
pub extra_group_object_classes: Vec<LdapObjectClass>,
}
#[async_trait] #[async_trait]
pub trait LoginHandler: Send + Sync { pub trait LoginHandler: Send + Sync {
async fn bind(&self, request: BindRequest) -> Result<()>; async fn bind(&self, request: BindRequest) -> Result<()>;
@@ -257,6 +177,7 @@ pub trait BackendHandler:
mod tests { mod tests {
use super::*; use super::*;
use base64::Engine; use base64::Engine;
use lldap_domain::types::JpegPhoto;
use pretty_assertions::assert_ne; use pretty_assertions::assert_ne;
#[test] #[test]
+3 -1
View File
@@ -17,7 +17,9 @@ use crate::domain::{
}, },
}, },
schema::{PublicSchema, SchemaGroupAttributeExtractor}, schema::{PublicSchema, SchemaGroupAttributeExtractor},
types::{AttributeName, AttributeType, Group, GroupId, LdapObjectClass, UserId, Uuid}, };
use lldap_domain::types::{
AttributeName, AttributeType, Group, GroupId, LdapObjectClass, UserId, Uuid,
}; };
pub fn get_group_attribute( pub fn get_group_attribute(
+4 -4
View File
@@ -16,11 +16,11 @@ use crate::domain::{
LdapInfo, UserFieldType, LdapInfo, UserFieldType,
}, },
}, },
model::UserColumn,
schema::{PublicSchema, SchemaUserAttributeExtractor}, schema::{PublicSchema, SchemaUserAttributeExtractor},
types::{ };
AttributeName, AttributeType, GroupDetails, LdapObjectClass, User, UserAndGroups, use lldap_domain::types::{
UserColumn, UserId, AttributeName, AttributeType, GroupDetails, LdapObjectClass, User, UserAndGroups, UserId,
},
}; };
pub fn get_user_attribute( pub fn get_user_attribute(
+4 -3
View File
@@ -7,10 +7,11 @@ use tracing::{debug, instrument, warn};
use crate::domain::{ use crate::domain::{
handler::SubStringFilter, handler::SubStringFilter,
ldap::error::{LdapError, LdapResult}, ldap::error::{LdapError, LdapResult},
model::UserColumn,
schema::{PublicSchema, SchemaAttributeExtractor}, schema::{PublicSchema, SchemaAttributeExtractor},
types::{ };
AttributeName, AttributeType, AttributeValue, GroupName, JpegPhoto, UserColumn, UserId, use lldap_domain::types::{
}, AttributeName, AttributeType, AttributeValue, GroupName, JpegPhoto, UserId,
}; };
impl From<LdapSubstringFilter> for SubStringFilter { impl From<LdapSubstringFilter> for SubStringFilter {
-1
View File
@@ -12,4 +12,3 @@ pub mod sql_opaque_handler;
pub mod sql_schema_backend_handler; pub mod sql_schema_backend_handler;
pub mod sql_tables; pub mod sql_tables;
pub mod sql_user_backend_handler; pub mod sql_user_backend_handler;
pub mod types;
@@ -1,8 +1,8 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::{ use lldap_domain::{
handler::AttributeSchema, schema::AttributeSchema,
types::{AttributeName, AttributeType}, types::{AttributeName, AttributeType},
}; };
+1 -1
View File
@@ -1,7 +1,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::{AttributeName, AttributeValue, GroupId, Serialized}; use lldap_domain::types::{AttributeName, AttributeValue, GroupId, Serialized};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "group_attributes")] #[sea_orm(table_name = "group_attributes")]
@@ -1,7 +1,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::LdapObjectClass; use lldap_domain::types::LdapObjectClass;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "group_object_classes")] #[sea_orm(table_name = "group_object_classes")]
+3 -3
View File
@@ -3,7 +3,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::{GroupId, GroupName, Uuid}; use lldap_domain::types::{GroupId, GroupName, Uuid};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "groups")] #[sea_orm(table_name = "groups")]
@@ -30,7 +30,7 @@ impl Related<super::memberships::Entity> for Entity {
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}
impl From<Model> for crate::domain::types::Group { impl From<Model> for lldap_domain::types::Group {
fn from(group: Model) -> Self { fn from(group: Model) -> Self {
Self { Self {
id: group.group_id, id: group.group_id,
@@ -43,7 +43,7 @@ impl From<Model> for crate::domain::types::Group {
} }
} }
impl From<Model> for crate::domain::types::GroupDetails { impl From<Model> for lldap_domain::types::GroupDetails {
fn from(group: Model) -> Self { fn from(group: Model) -> Self {
Self { Self {
group_id: group.group_id, group_id: group.group_id,
@@ -3,7 +3,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::UserId; use lldap_domain::types::UserId;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "jwt_refresh_storage")] #[sea_orm(table_name = "jwt_refresh_storage")]
+1 -1
View File
@@ -3,7 +3,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::UserId; use lldap_domain::types::UserId;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "jwt_storage")] #[sea_orm(table_name = "jwt_storage")]
+1 -1
View File
@@ -3,7 +3,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::{GroupId, UserId}; use lldap_domain::types::{GroupId, UserId};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "memberships")] #[sea_orm(table_name = "memberships")]
@@ -3,7 +3,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::UserId; use lldap_domain::types::UserId;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "password_reset_tokens")] #[sea_orm(table_name = "password_reset_tokens")]
@@ -1,8 +1,8 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::{ use lldap_domain::{
handler::AttributeSchema, schema::AttributeSchema,
types::{AttributeName, AttributeType}, types::{AttributeName, AttributeType},
}; };
+1 -1
View File
@@ -1,7 +1,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::{AttributeName, AttributeValue, Serialized, UserId}; use lldap_domain::types::{AttributeName, AttributeValue, Serialized, UserId};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_attributes")] #[sea_orm(table_name = "user_attributes")]
@@ -1,7 +1,7 @@
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::LdapObjectClass; use lldap_domain::types::LdapObjectClass;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_object_classes")] #[sea_orm(table_name = "user_object_classes")]
+2 -2
View File
@@ -3,7 +3,7 @@
use sea_orm::{entity::prelude::*, sea_query::BlobSize}; use sea_orm::{entity::prelude::*, sea_query::BlobSize};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::domain::types::{Email, UserId, Uuid}; use lldap_domain::types::{Email, UserId, Uuid};
#[derive(Copy, Clone, Default, Debug, DeriveEntity)] #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
pub struct Entity; pub struct Entity;
@@ -112,7 +112,7 @@ impl Related<super::password_reset_tokens::Entity> for Entity {
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}
impl From<Model> for crate::domain::types::User { impl From<Model> for lldap_domain::types::User {
fn from(user: Model) -> Self { fn from(user: Model) -> Self {
Self { Self {
user_id: user.user_id, user_id: user.user_id,
+2 -1
View File
@@ -1,5 +1,6 @@
use crate::domain::{error::Result, types::UserId}; use crate::domain::error::Result;
use async_trait::async_trait; use async_trait::async_trait;
use lldap_domain::types::UserId;
pub use lldap_auth::{login, registration}; pub use lldap_auth::{login, registration};
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::domain::{ use lldap_domain::{
handler::{AttributeList, AttributeSchema, Schema}, schema::{AttributeList, AttributeSchema, Schema},
types::AttributeType, types::AttributeType,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
+6 -3
View File
@@ -23,15 +23,18 @@ pub mod tests {
use crate::{ use crate::{
domain::{ domain::{
handler::{ handler::{
CreateGroupRequest, CreateUserRequest, GroupBackendHandler, UserBackendHandler, GroupBackendHandler, UserBackendHandler, UserListerBackendHandler,
UserListerBackendHandler, UserRequestFilter, UserRequestFilter,
}, },
sql_tables::init_table, sql_tables::init_table,
types::{GroupId, UserId},
}, },
infra::configuration::ConfigurationBuilder, infra::configuration::ConfigurationBuilder,
}; };
use lldap_auth::{opaque, registration}; use lldap_auth::{opaque, registration};
use lldap_domain::{
requests::{CreateGroupRequest, CreateUserRequest},
types::{GroupId, UserId},
};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use sea_orm::Database; use sea_orm::Database;
@@ -1,14 +1,14 @@
use crate::domain::{ use crate::domain::{
error::{DomainError, Result}, error::{DomainError, Result},
handler::{ handler::{GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter},
CreateGroupRequest, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
UpdateGroupRequest,
},
model::{self, GroupColumn, MembershipColumn}, model::{self, GroupColumn, MembershipColumn},
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
types::{AttributeName, AttributeValue, Group, GroupDetails, GroupId, Serialized, Uuid},
}; };
use async_trait::async_trait; use async_trait::async_trait;
use lldap_domain::{
requests::{CreateGroupRequest, UpdateGroupRequest},
types::{AttributeName, AttributeValue, Group, GroupDetails, GroupId, Serialized, Uuid},
};
use sea_orm::{ use sea_orm::{
sea_query::{Alias, Cond, Expr, Func, IntoCondition, OnConflict, SimpleExpr}, sea_query::{Alias, Cond, Expr, Func, IntoCondition, OnConflict, SimpleExpr},
ActiveModelTrait, ColumnTrait, DatabaseTransaction, EntityTrait, QueryFilter, QueryOrder, ActiveModelTrait, ColumnTrait, DatabaseTransaction, EntityTrait, QueryFilter, QueryOrder,
@@ -314,8 +314,11 @@ impl SqlBackendHandler {
mod tests { mod tests {
use super::*; use super::*;
use crate::domain::{ use crate::domain::{
handler::{CreateAttributeRequest, SchemaBackendHandler, SubStringFilter}, handler::{SchemaBackendHandler, SubStringFilter},
sql_backend_handler::tests::*, sql_backend_handler::tests::*,
};
use lldap_domain::{
requests::CreateAttributeRequest,
types::{AttributeType, GroupName, Serialized, UserId}, types::{AttributeType, GroupName, Serialized, UserId},
}; };
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
+2 -4
View File
@@ -1,8 +1,6 @@
use crate::domain::{ use crate::domain::sql_tables::{DbConnection, SchemaVersion, LAST_SCHEMA_VERSION};
sql_tables::{DbConnection, SchemaVersion, LAST_SCHEMA_VERSION},
types::{AttributeType, GroupId, JpegPhoto, Serialized, UserId, Uuid},
};
use itertools::Itertools; use itertools::Itertools;
use lldap_domain::types::{AttributeType, GroupId, JpegPhoto, Serialized, UserId, Uuid};
use sea_orm::{ use sea_orm::{
sea_query::{ sea_query::{
self, all, BinOper, BlobSize::Blob, ColumnDef, Expr, ForeignKey, ForeignKeyAction, Func, self, all, BinOper, BlobSize::Blob, ColumnDef, Expr, ForeignKey, ForeignKeyAction, Func,
+1 -1
View File
@@ -4,11 +4,11 @@ use super::{
model::{self, UserColumn}, model::{self, UserColumn},
opaque_handler::{login, registration, OpaqueHandler}, opaque_handler::{login, registration, OpaqueHandler},
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
types::UserId,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use base64::Engine; use base64::Engine;
use lldap_auth::opaque; use lldap_auth::opaque;
use lldap_domain::types::UserId;
use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait, QuerySelect}; use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait, QuerySelect};
use secstr::SecUtf8; use secstr::SecUtf8;
use tracing::{debug, info, instrument, warn}; use tracing::{debug, info, instrument, warn};
@@ -1,14 +1,15 @@
use crate::domain::{ use crate::domain::{
error::{DomainError, Result}, error::{DomainError, Result},
handler::{ handler::{ReadSchemaBackendHandler, SchemaBackendHandler},
AttributeList, AttributeSchema, CreateAttributeRequest, ReadSchemaBackendHandler, Schema,
SchemaBackendHandler,
},
model, model,
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
types::{AttributeName, LdapObjectClass},
}; };
use async_trait::async_trait; use async_trait::async_trait;
use lldap_domain::{
requests::CreateAttributeRequest,
schema::{AttributeList, AttributeSchema, Schema},
types::{AttributeName, LdapObjectClass},
};
use sea_orm::{ use sea_orm::{
ActiveModelTrait, DatabaseTransaction, EntityTrait, QueryOrder, Set, TransactionTrait, ActiveModelTrait, DatabaseTransaction, EntityTrait, QueryOrder, Set, TransactionTrait,
}; };
@@ -175,10 +176,12 @@ impl SqlBackendHandler {
mod tests { mod tests {
use super::*; use super::*;
use crate::domain::{ use crate::domain::{
handler::{AttributeList, UpdateUserRequest, UserBackendHandler, UserRequestFilter}, handler::{UserBackendHandler, UserRequestFilter},
sql_backend_handler::tests::*, sql_backend_handler::tests::*,
types::{AttributeType, AttributeValue, Serialized},
}; };
use lldap_domain::requests::UpdateUserRequest;
use lldap_domain::schema::AttributeList;
use lldap_domain::types::{AttributeType, AttributeValue, Serialized};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
#[tokio::test] #[tokio::test]
+4 -6
View File
@@ -123,10 +123,8 @@ pub async fn set_private_key_info(pool: &DbConnection, info: PrivateKeyInfo) ->
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::domain::{ use crate::domain::sql_migrations;
sql_migrations, use lldap_domain::types::{GroupId, JpegPhoto, Serialized, Uuid};
types::{GroupId, JpegPhoto, Serialized, Uuid},
};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use super::*; use super::*;
@@ -254,11 +252,11 @@ mod tests {
vec![ vec![
SimpleUser { SimpleUser {
display_name: None, display_name: None,
uuid: crate::uuid!("a02eaf13-48a7-30f6-a3d4-040ff7c52b04") uuid: lldap_domain::uuid!("a02eaf13-48a7-30f6-a3d4-040ff7c52b04")
}, },
SimpleUser { SimpleUser {
display_name: Some("John Doe".to_owned()), display_name: Some("John Doe".to_owned()),
uuid: crate::uuid!("986765a5-3f03-389e-b47b-536b2d6e1bec") uuid: lldap_domain::uuid!("986765a5-3f03-389e-b47b-536b2d6e1bec")
} }
] ]
); );
@@ -1,17 +1,17 @@
use crate::domain::{ use crate::domain::{
error::{DomainError, Result}, error::{DomainError, Result},
handler::{ handler::{UserBackendHandler, UserListerBackendHandler, UserRequestFilter},
CreateUserRequest, UpdateUserRequest, UserBackendHandler, UserListerBackendHandler,
UserRequestFilter,
},
model::{self, GroupColumn, UserColumn}, model::{self, GroupColumn, UserColumn},
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
};
use async_trait::async_trait;
use lldap_domain::{
requests::{CreateUserRequest, UpdateUserRequest},
types::{ types::{
AttributeName, AttributeValue, GroupDetails, GroupId, Serialized, User, UserAndGroups, AttributeName, AttributeValue, GroupDetails, GroupId, Serialized, User, UserAndGroups,
UserId, Uuid, UserId, Uuid,
}, },
}; };
use async_trait::async_trait;
use sea_orm::{ use sea_orm::{
sea_query::{ sea_query::{
query::OnConflict, Alias, Cond, Expr, Func, IntoColumnRef, IntoCondition, SimpleExpr, query::OnConflict, Alias, Cond, Expr, Func, IntoColumnRef, IntoCondition, SimpleExpr,
@@ -430,10 +430,9 @@ impl UserBackendHandler for SqlBackendHandler {
mod tests { mod tests {
use super::*; use super::*;
use crate::domain::{ use crate::domain::{
handler::SubStringFilter, handler::SubStringFilter, model::UserColumn, sql_backend_handler::tests::*,
sql_backend_handler::tests::*,
types::{JpegPhoto, UserColumn},
}; };
use lldap_domain::types::JpegPhoto;
use pretty_assertions::{assert_eq, assert_ne}; use pretty_assertions::{assert_eq, assert_ne};
#[tokio::test] #[tokio::test]
+10 -4
View File
@@ -6,12 +6,18 @@ use tracing::info;
use crate::domain::{ use crate::domain::{
error::Result, error::Result,
handler::{ handler::{
AttributeSchema, BackendHandler, CreateAttributeRequest, CreateGroupRequest, BackendHandler, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter,
CreateUserRequest, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter, ReadSchemaBackendHandler, SchemaBackendHandler, UserBackendHandler,
ReadSchemaBackendHandler, Schema, SchemaBackendHandler, UpdateGroupRequest, UserListerBackendHandler, UserRequestFilter,
UpdateUserRequest, UserBackendHandler, UserListerBackendHandler, UserRequestFilter,
}, },
schema::PublicSchema, schema::PublicSchema,
};
use lldap_domain::{
requests::{
CreateAttributeRequest, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
UpdateUserRequest,
},
schema::{AttributeSchema, Schema},
types::{ types::{
AttributeName, Group, GroupDetails, GroupId, GroupName, LdapObjectClass, User, AttributeName, Group, GroupDetails, GroupId, GroupName, LdapObjectClass, User,
UserAndGroups, UserId, UserAndGroups, UserId,
+2 -1
View File
@@ -22,13 +22,14 @@ use time::ext::NumericalDuration;
use tracing::{debug, info, instrument, warn}; use tracing::{debug, info, instrument, warn};
use lldap_auth::{login, password_reset, registration, JWTClaims}; use lldap_auth::{login, password_reset, registration, JWTClaims};
use lldap_domain::types::{GroupDetails, GroupName, UserId};
use crate::{ use crate::{
domain::{ domain::{
error::DomainError, error::DomainError,
handler::{BackendHandler, BindRequest, LoginHandler, UserRequestFilter}, handler::{BackendHandler, BindRequest, LoginHandler, UserRequestFilter},
model::UserColumn,
opaque_handler::OpaqueHandler, opaque_handler::OpaqueHandler,
types::{GroupDetails, GroupName, UserColumn, UserId},
}, },
infra::{ infra::{
access_control::{ReadonlyBackendHandler, UserReadableBackendHandler, ValidationResults}, access_control::{ReadonlyBackendHandler, UserReadableBackendHandler, ValidationResults},
+3 -5
View File
@@ -1,10 +1,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use crate::{ use crate::{
domain::{ domain::sql_tables::{ConfigLocation, PrivateKeyHash, PrivateKeyInfo, PrivateKeyLocation},
sql_tables::{ConfigLocation, PrivateKeyHash, PrivateKeyInfo, PrivateKeyLocation},
types::{AttributeName, UserId},
},
infra::{ infra::{
cli::{ cli::{
GeneralConfigOpts, LdapsOpts, RunOpts, SmtpEncryption, SmtpOpts, TestEmailOpts, GeneralConfigOpts, LdapsOpts, RunOpts, SmtpEncryption, SmtpOpts, TestEmailOpts,
@@ -20,6 +17,7 @@ use figment::{
}; };
use figment_file_provider_adapter::FileAdapter; use figment_file_provider_adapter::FileAdapter;
use lldap_auth::opaque::{server::ServerSetup, KeyPair}; use lldap_auth::opaque::{server::ServerSetup, KeyPair};
use lldap_domain::types::{AttributeName, UserId};
use secstr::SecUtf8; use secstr::SecUtf8;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::PathBuf; use std::path::PathBuf;
@@ -623,7 +621,7 @@ where
Either set the `jwt_secret` config value or the `LLDAP_JWT_SECRET` environment variable. \ Either set the `jwt_secret` config value or the `LLDAP_JWT_SECRET` environment variable. \
You can generate the value by running\n\ You can generate the value by running\n\
LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\\''()*+,-./:;<=>?@[\\]^_{{|}}~' </dev/urandom | head -c 32; echo ''\n\ LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\\''()*+,-./:;<=>?@[\\]^_{{|}}~' </dev/urandom | head -c 32; echo ''\n\
or you can use this random value: {}", or you can use this random value: {}",
rand::thread_rng() rand::thread_rng()
.sample_iter(&Symbols) .sample_iter(&Symbols)
.take(32) .take(32)
+3 -1
View File
@@ -1,5 +1,5 @@
use crate::{ use crate::{
domain::{handler::BackendHandler, types::UserId}, domain::handler::BackendHandler,
infra::{ infra::{
access_control::{ access_control::{
AccessControlledBackendHandler, AdminBackendHandler, ReadonlyBackendHandler, AccessControlledBackendHandler, AdminBackendHandler, ReadonlyBackendHandler,
@@ -11,6 +11,7 @@ use crate::{
tcp_server::AppState, tcp_server::AppState,
}, },
}; };
use actix_web::FromRequest; use actix_web::FromRequest;
use actix_web::HttpMessage; use actix_web::HttpMessage;
use actix_web::{error::JsonPayloadError, web, Error, HttpRequest, HttpResponse}; use actix_web::{error::JsonPayloadError, web, Error, HttpRequest, HttpResponse};
@@ -22,6 +23,7 @@ use juniper::{
}, },
EmptySubscription, FieldError, RootNode, ScalarValue, EmptySubscription, FieldError, RootNode, ScalarValue,
}; };
use lldap_domain::types::UserId;
use tracing::debug; use tracing::debug;
pub struct Context<Handler: BackendHandler> { pub struct Context<Handler: BackendHandler> {
+17 -17
View File
@@ -2,16 +2,7 @@ use std::sync::Arc;
use crate::{ use crate::{
domain::{ domain::{
deserialize::deserialize_attribute_value, deserialize::deserialize_attribute_value, handler::BackendHandler, schema::PublicSchema,
handler::{
AttributeList, BackendHandler, CreateAttributeRequest, CreateGroupRequest,
CreateUserRequest, UpdateGroupRequest, UpdateUserRequest,
},
schema::PublicSchema,
types::{
AttributeName, AttributeType, AttributeValue as DomainAttributeValue, Email, GroupId,
JpegPhoto, LdapObjectClass, UserId,
},
}, },
infra::{ infra::{
access_control::{ access_control::{
@@ -24,6 +15,17 @@ use crate::{
use anyhow::{anyhow, Context as AnyhowContext}; use anyhow::{anyhow, Context as AnyhowContext};
use base64::Engine; use base64::Engine;
use juniper::{graphql_object, FieldError, FieldResult, GraphQLInputObject, GraphQLObject}; use juniper::{graphql_object, FieldError, FieldResult, GraphQLInputObject, GraphQLObject};
use lldap_domain::{
requests::{
CreateAttributeRequest, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
UpdateUserRequest,
},
schema::AttributeList,
types::{
AttributeName, AttributeType, AttributeValue as DomainAttributeValue, Email, GroupId,
JpegPhoto, LdapObjectClass, UserId,
},
};
use lldap_validation::attributes::{validate_attribute_name, ALLOWED_CHARACTERS_DESCRIPTION}; use lldap_validation::attributes::{validate_attribute_name, ALLOWED_CHARACTERS_DESCRIPTION};
use tracing::{debug, debug_span, Instrument, Span}; use tracing::{debug, debug_span, Instrument, Span};
@@ -731,18 +733,16 @@ fn deserialize_attribute(
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::infra::{
domain::types::{AttributeName, AttributeType}, access_control::{Permission, ValidationResults},
infra::{ graphql::query::Query,
access_control::{Permission, ValidationResults}, test_utils::MockTestBackendHandler,
graphql::query::Query,
test_utils::MockTestBackendHandler,
},
}; };
use juniper::{ use juniper::{
execute, graphql_value, DefaultScalarValue, EmptySubscription, GraphQLType, InputValue, execute, graphql_value, DefaultScalarValue, EmptySubscription, GraphQLType, InputValue,
RootNode, Variables, RootNode, Variables,
}; };
use lldap_domain::types::{AttributeName, AttributeType};
use mockall::predicate::eq; use mockall::predicate::eq;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
+21 -23
View File
@@ -7,9 +7,6 @@ use crate::{
ldap::utils::{map_user_field, UserFieldType}, ldap::utils::{map_user_field, UserFieldType},
model::UserColumn, model::UserColumn,
schema::PublicSchema, schema::PublicSchema,
types::{
AttributeType, GroupDetails, GroupId, JpegPhoto, LdapObjectClass, Serialized, UserId,
},
}, },
infra::{ infra::{
access_control::{ReadonlyBackendHandler, UserReadableBackendHandler}, access_control::{ReadonlyBackendHandler, UserReadableBackendHandler},
@@ -19,16 +16,19 @@ use crate::{
use anyhow::Context as AnyhowContext; use anyhow::Context as AnyhowContext;
use chrono::{NaiveDateTime, TimeZone}; use chrono::{NaiveDateTime, TimeZone};
use juniper::{graphql_object, FieldResult, GraphQLInputObject}; use juniper::{graphql_object, FieldResult, GraphQLInputObject};
use lldap_domain::types::{
AttributeType, GroupDetails, GroupId, JpegPhoto, LdapObjectClass, Serialized, UserId,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::{debug, debug_span, Instrument, Span}; use tracing::{debug, debug_span, Instrument, Span};
type DomainRequestFilter = crate::domain::handler::UserRequestFilter; type DomainRequestFilter = crate::domain::handler::UserRequestFilter;
type DomainUser = crate::domain::types::User; type DomainUser = lldap_domain::types::User;
type DomainGroup = crate::domain::types::Group; type DomainGroup = lldap_domain::types::Group;
type DomainUserAndGroups = crate::domain::types::UserAndGroups; type DomainUserAndGroups = lldap_domain::types::UserAndGroups;
type DomainAttributeList = crate::domain::handler::AttributeList; type DomainAttributeList = lldap_domain::schema::AttributeList;
type DomainAttributeSchema = crate::domain::handler::AttributeSchema; type DomainAttributeSchema = lldap_domain::schema::AttributeSchema;
type DomainAttributeValue = crate::domain::types::AttributeValue; type DomainAttributeValue = lldap_domain::types::AttributeValue;
#[derive(PartialEq, Eq, Debug, GraphQLInputObject)] #[derive(PartialEq, Eq, Debug, GraphQLInputObject)]
/// A filter for requests, specifying a boolean expression based on field constraints. Only one of /// A filter for requests, specifying a boolean expression based on field constraints. Only one of
@@ -801,21 +801,19 @@ impl<Handler: BackendHandler> AttributeValue<Handler> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::infra::{
domain::{ access_control::{Permission, ValidationResults},
handler::AttributeList, test_utils::{setup_default_schema, MockTestBackendHandler},
types::{AttributeName, AttributeType, LdapObjectClass, Serialized},
},
infra::{
access_control::{Permission, ValidationResults},
test_utils::{setup_default_schema, MockTestBackendHandler},
},
}; };
use chrono::TimeZone; use chrono::TimeZone;
use juniper::{ use juniper::{
execute, graphql_value, DefaultScalarValue, EmptyMutation, EmptySubscription, GraphQLType, execute, graphql_value, DefaultScalarValue, EmptyMutation, EmptySubscription, GraphQLType,
RootNode, Variables, RootNode, Variables,
}; };
use lldap_domain::{
schema::{AttributeList, Schema},
types::{AttributeName, AttributeType, LdapObjectClass, Serialized},
};
use mockall::predicate::eq; use mockall::predicate::eq;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use std::collections::HashSet; use std::collections::HashSet;
@@ -860,7 +858,7 @@ mod tests {
let mut mock = MockTestBackendHandler::new(); let mut mock = MockTestBackendHandler::new();
mock.expect_get_schema().returning(|| { mock.expect_get_schema().returning(|| {
Ok(crate::domain::handler::Schema { Ok(Schema {
user_attributes: DomainAttributeList { user_attributes: DomainAttributeList {
attributes: vec![ attributes: vec![
DomainAttributeSchema { DomainAttributeSchema {
@@ -908,7 +906,7 @@ mod tests {
user_id: UserId::new("bob"), user_id: UserId::new("bob"),
email: "bob@bobbers.on".into(), email: "bob@bobbers.on".into(),
creation_date: chrono::Utc.timestamp_millis_opt(42).unwrap().naive_utc(), creation_date: chrono::Utc.timestamp_millis_opt(42).unwrap().naive_utc(),
uuid: crate::uuid!("b1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"), uuid: lldap_domain::uuid!("b1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
attributes: vec![ attributes: vec![
DomainAttributeValue { DomainAttributeValue {
name: "first_name".into(), name: "first_name".into(),
@@ -927,7 +925,7 @@ mod tests {
group_id: GroupId(3), group_id: GroupId(3),
display_name: "Bobbersons".into(), display_name: "Bobbersons".into(),
creation_date: chrono::Utc.timestamp_nanos(42).naive_utc(), creation_date: chrono::Utc.timestamp_nanos(42).naive_utc(),
uuid: crate::uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"), uuid: lldap_domain::uuid!("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
attributes: vec![DomainAttributeValue { attributes: vec![DomainAttributeValue {
name: "club_name".into(), name: "club_name".into(),
value: Serialized::from("Gang of Four"), value: Serialized::from("Gang of Four"),
@@ -937,7 +935,7 @@ mod tests {
group_id: GroupId(7), group_id: GroupId(7),
display_name: "Jefferees".into(), display_name: "Jefferees".into(),
creation_date: chrono::Utc.timestamp_nanos(12).naive_utc(), creation_date: chrono::Utc.timestamp_nanos(12).naive_utc(),
uuid: crate::uuid!("b1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"), uuid: lldap_domain::uuid!("b1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"),
attributes: Vec::new(), attributes: Vec::new(),
}); });
mock.expect_get_user_groups() mock.expect_get_user_groups()
@@ -1299,7 +1297,7 @@ mod tests {
let mut mock = MockTestBackendHandler::new(); let mut mock = MockTestBackendHandler::new();
mock.expect_get_schema().times(1).return_once(|| { mock.expect_get_schema().times(1).return_once(|| {
Ok(crate::domain::handler::Schema { Ok(Schema {
user_attributes: AttributeList { user_attributes: AttributeList {
attributes: vec![DomainAttributeSchema { attributes: vec![DomainAttributeSchema {
name: "invisible".into(), name: "invisible".into(),
+12 -8
View File
@@ -1,8 +1,6 @@
use crate::{ use crate::{
domain::{ domain::{
handler::{ handler::{BackendHandler, BindRequest, LoginHandler, ReadSchemaBackendHandler},
BackendHandler, BindRequest, CreateUserRequest, LoginHandler, ReadSchemaBackendHandler,
},
ldap::{ ldap::{
error::{LdapError, LdapResult}, error::{LdapError, LdapResult},
group::{convert_groups_to_ldap_op, get_groups_list}, group::{convert_groups_to_ldap_op, get_groups_list},
@@ -13,7 +11,6 @@ use crate::{
}, },
opaque_handler::OpaqueHandler, opaque_handler::OpaqueHandler,
schema::PublicSchema, schema::PublicSchema,
types::{AttributeName, Email, Group, JpegPhoto, UserAndGroups, UserId},
}, },
infra::access_control::{ infra::access_control::{
AccessControlledBackendHandler, AdminBackendHandler, UserAndGroupListerBackendHandler, AccessControlledBackendHandler, AdminBackendHandler, UserAndGroupListerBackendHandler,
@@ -28,6 +25,10 @@ use ldap3_proto::proto::{
LdapResult as LdapResultOp, LdapResultCode, LdapSearchRequest, LdapSearchResultEntry, LdapResult as LdapResultOp, LdapResultCode, LdapSearchRequest, LdapSearchResultEntry,
LdapSearchScope, LdapSearchScope,
}; };
use lldap_domain::{
requests::CreateUserRequest,
types::{AttributeName, Email, Group, JpegPhoto, UserAndGroups, UserId},
};
use std::collections::HashMap; use std::collections::HashMap;
use tracing::{debug, instrument, warn}; use tracing::{debug, instrument, warn};
@@ -879,12 +880,15 @@ impl<Backend: BackendHandler + LoginHandler + OpaqueHandler> LdapHandler<Backend
mod tests { mod tests {
use super::*; use super::*;
use crate::{ use crate::{
domain::{handler::*, types::*}, domain::handler::*,
domain::model::UserColumn,
infra::test_utils::{setup_default_schema, MockTestBackendHandler}, infra::test_utils::{setup_default_schema, MockTestBackendHandler},
uuid,
}; };
use chrono::TimeZone; use chrono::TimeZone;
use ldap3_proto::proto::{LdapDerefAliases, LdapSearchScope, LdapSubstringFilter}; use ldap3_proto::proto::{LdapDerefAliases, LdapSearchScope, LdapSubstringFilter};
use lldap_domain::schema::{AttributeList, AttributeSchema, Schema};
use lldap_domain::types::*;
use lldap_domain::uuid;
use mockall::predicate::eq; use mockall::predicate::eq;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use std::collections::HashSet; use std::collections::HashSet;
@@ -1691,7 +1695,7 @@ mod tests {
}]) }])
}); });
mock.expect_get_schema().returning(|| { mock.expect_get_schema().returning(|| {
Ok(crate::domain::handler::Schema { Ok(Schema {
user_attributes: AttributeList { user_attributes: AttributeList {
attributes: Vec::new(), attributes: Vec::new(),
}, },
@@ -3020,7 +3024,7 @@ mod tests {
}]) }])
}); });
mock.expect_get_schema().returning(|| { mock.expect_get_schema().returning(|| {
Ok(crate::domain::handler::Schema { Ok(Schema {
user_attributes: AttributeList { user_attributes: AttributeList {
attributes: vec![AttributeSchema { attributes: vec![AttributeSchema {
name: "nickname".into(), name: "nickname".into(),
+1 -1
View File
@@ -2,7 +2,6 @@ use crate::{
domain::{ domain::{
handler::{BackendHandler, LoginHandler}, handler::{BackendHandler, LoginHandler},
opaque_handler::OpaqueHandler, opaque_handler::OpaqueHandler,
types::AttributeName,
}, },
infra::{ infra::{
access_control::AccessControlledBackendHandler, access_control::AccessControlledBackendHandler,
@@ -15,6 +14,7 @@ use actix_server::ServerBuilder;
use actix_service::{fn_service, ServiceFactoryExt}; use actix_service::{fn_service, ServiceFactoryExt};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use ldap3_proto::{control::LdapControl, proto::LdapMsg, proto::LdapOp, LdapCodec}; use ldap3_proto::{control::LdapControl, proto::LdapMsg, proto::LdapOp, LdapCodec};
use lldap_domain::types::AttributeName;
use rustls::PrivateKey; use rustls::PrivateKey;
use tokio_rustls::TlsAcceptor as RustlsTlsAcceptor; use tokio_rustls::TlsAcceptor as RustlsTlsAcceptor;
use tokio_util::codec::{FramedRead, FramedWrite}; use tokio_util::codec::{FramedRead, FramedWrite};
+1 -1
View File
@@ -3,10 +3,10 @@ use crate::domain::{
error::*, error::*,
model::{self, JwtRefreshStorageColumn, JwtStorageColumn, PasswordResetTokensColumn}, model::{self, JwtRefreshStorageColumn, JwtStorageColumn, PasswordResetTokensColumn},
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
types::UserId,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use lldap_domain::types::UserId;
use sea_orm::{ use sea_orm::{
sea_query::{Cond, Expr}, sea_query::{Cond, Expr},
ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect,
+2 -1
View File
@@ -2,7 +2,8 @@ use async_trait::async_trait;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use std::collections::HashSet; use std::collections::HashSet;
use crate::domain::{error::Result, types::UserId}; use crate::domain::error::Result;
use lldap_domain::types::UserId;
#[async_trait] #[async_trait]
pub trait TcpBackendHandler: Sync { pub trait TcpBackendHandler: Sync {
+9 -1
View File
@@ -1,4 +1,12 @@
use crate::domain::{error::Result, handler::*, opaque_handler::*, types::*}; use crate::domain::{error::Result, handler::*, opaque_handler::*};
use lldap_domain::{
requests::{
CreateAttributeRequest, CreateGroupRequest, CreateUserRequest, UpdateGroupRequest,
UpdateUserRequest,
},
schema::{AttributeList, AttributeSchema, Schema},
types::*,
};
use async_trait::async_trait; use async_trait::async_trait;
use std::collections::HashSet; use std::collections::HashSet;
+4 -2
View File
@@ -8,8 +8,8 @@ use std::time::Duration;
use crate::{ use crate::{
domain::{ domain::{
handler::{ handler::{
CreateGroupRequest, CreateUserRequest, GroupBackendHandler, GroupListerBackendHandler, GroupBackendHandler, GroupListerBackendHandler, GroupRequestFilter, UserBackendHandler,
GroupRequestFilter, UserBackendHandler, UserListerBackendHandler, UserRequestFilter, UserListerBackendHandler, UserRequestFilter,
}, },
sql_backend_handler::SqlBackendHandler, sql_backend_handler::SqlBackendHandler,
sql_opaque_handler::register_password, sql_opaque_handler::register_password,
@@ -30,6 +30,8 @@ use futures_util::TryFutureExt;
use sea_orm::{Database, DatabaseConnection}; use sea_orm::{Database, DatabaseConnection};
use tracing::{debug, error, info, instrument, span, warn, Instrument, Level}; use tracing::{debug, error, info, instrument, span, warn, Instrument, Level};
use lldap_domain::requests::{CreateGroupRequest, CreateUserRequest};
mod domain; mod domain;
mod infra; mod infra;