diff --git a/server/src/domain/handler.rs b/server/src/domain/handler.rs index 591ab22..3614748 100644 --- a/server/src/domain/handler.rs +++ b/server/src/domain/handler.rs @@ -1,7 +1,8 @@ -use super::{ +use crate::domain::{ error::Result, types::{ - Group, GroupDetails, GroupId, JpegPhoto, User, UserAndGroups, UserColumn, UserId, Uuid, + AttributeType, Group, GroupDetails, GroupId, JpegPhoto, User, UserAndGroups, UserColumn, + UserId, Uuid, }, }; use async_trait::async_trait; @@ -122,6 +123,23 @@ pub struct UpdateGroupRequest { pub display_name: Option, } +#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] +pub struct AttributeSchema { + pub name: String, + //TODO: pub aliases: Vec, + pub attribute_type: AttributeType, + pub is_list: bool, + pub is_visible: bool, + pub is_editable: bool, + pub is_hardcoded: bool, +} + +#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] +pub struct Schema { + pub user_attributes: Vec, + pub group_attributes: Vec, +} + #[async_trait] pub trait LoginHandler: Send + Sync { async fn bind(&self, request: BindRequest) -> Result<()>; @@ -160,6 +178,11 @@ pub trait UserBackendHandler { async fn get_user_groups(&self, user_id: &UserId) -> Result>; } +#[async_trait] +pub trait SchemaBackendHandler { + async fn get_schema(&self) -> Result; +} + #[async_trait] pub trait BackendHandler: Send @@ -168,6 +191,7 @@ pub trait BackendHandler: + UserBackendHandler + UserListerBackendHandler + GroupListerBackendHandler + + SchemaBackendHandler { } @@ -203,6 +227,10 @@ mockall::mock! { async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>; } #[async_trait] + impl SchemaBackendHandler for TestBackendHandler { + async fn get_schema(&self) -> Result; + } + #[async_trait] impl BackendHandler for TestBackendHandler {} #[async_trait] impl LoginHandler for TestBackendHandler { diff --git a/server/src/domain/mod.rs b/server/src/domain/mod.rs index c122cf8..2fbd435 100644 --- a/server/src/domain/mod.rs +++ b/server/src/domain/mod.rs @@ -7,6 +7,7 @@ pub mod sql_backend_handler; pub mod sql_group_backend_handler; pub mod sql_migrations; pub mod sql_opaque_handler; +pub mod sql_schema_backend_handler; pub mod sql_tables; pub mod sql_user_backend_handler; pub mod types; diff --git a/server/src/domain/model/group_attribute_schema.rs b/server/src/domain/model/group_attribute_schema.rs index c6acd95..a62a460 100644 --- a/server/src/domain/model/group_attribute_schema.rs +++ b/server/src/domain/model/group_attribute_schema.rs @@ -1,7 +1,7 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; -use crate::domain::types::AttributeType; +use crate::domain::{handler::AttributeSchema, types::AttributeType}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[sea_orm(table_name = "group_attribute_schema")] @@ -37,3 +37,16 @@ impl Related for Entity { } impl ActiveModelBehavior for ActiveModel {} + +impl From for AttributeSchema { + fn from(value: Model) -> Self { + Self { + name: value.attribute_name, + attribute_type: value.attribute_type, + is_list: value.is_list, + is_visible: value.is_group_visible, + is_editable: value.is_group_editable, + is_hardcoded: value.is_hardcoded, + } + } +} diff --git a/server/src/domain/model/user_attribute_schema.rs b/server/src/domain/model/user_attribute_schema.rs index e83ab06..626e917 100644 --- a/server/src/domain/model/user_attribute_schema.rs +++ b/server/src/domain/model/user_attribute_schema.rs @@ -1,7 +1,7 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; -use crate::domain::types::AttributeType; +use crate::domain::{handler::AttributeSchema, types::AttributeType}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[sea_orm(table_name = "user_attribute_schema")] @@ -37,3 +37,16 @@ impl Related for Entity { } impl ActiveModelBehavior for ActiveModel {} + +impl From for AttributeSchema { + fn from(value: Model) -> Self { + Self { + name: value.attribute_name, + attribute_type: value.attribute_type, + is_list: value.is_list, + is_visible: value.is_user_visible, + is_editable: value.is_user_editable, + is_hardcoded: value.is_hardcoded, + } + } +} diff --git a/server/src/domain/sql_schema_backend_handler.rs b/server/src/domain/sql_schema_backend_handler.rs new file mode 100644 index 0000000..8f73970 --- /dev/null +++ b/server/src/domain/sql_schema_backend_handler.rs @@ -0,0 +1,83 @@ +use crate::domain::{ + error::Result, + handler::{AttributeSchema, Schema, SchemaBackendHandler}, + model, + sql_backend_handler::SqlBackendHandler, +}; +use async_trait::async_trait; +use sea_orm::{EntityTrait, QueryOrder}; + +#[async_trait] +impl SchemaBackendHandler for SqlBackendHandler { + async fn get_schema(&self) -> Result { + Ok(Schema { + user_attributes: self.get_user_attributes().await?, + group_attributes: self.get_group_attributes().await?, + }) + } +} + +impl SqlBackendHandler { + async fn get_user_attributes(&self) -> Result> { + Ok(model::UserAttributeSchema::find() + .order_by_asc(model::UserAttributeSchemaColumn::AttributeName) + .all(&self.sql_pool) + .await? + .into_iter() + .map(|m| m.into()) + .collect()) + } + + async fn get_group_attributes(&self) -> Result> { + Ok(model::GroupAttributeSchema::find() + .order_by_asc(model::GroupAttributeSchemaColumn::AttributeName) + .all(&self.sql_pool) + .await? + .into_iter() + .map(|m| m.into()) + .collect()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::domain::{sql_backend_handler::tests::*, types::AttributeType}; + + #[tokio::test] + async fn test_default_schema() { + let fixture = TestFixture::new().await; + assert_eq!( + fixture.handler.get_schema().await.unwrap(), + Schema { + user_attributes: vec![ + AttributeSchema { + name: "avatar".to_owned(), + attribute_type: AttributeType::JpegPhoto, + is_list: false, + is_visible: true, + is_editable: true, + is_hardcoded: true, + }, + AttributeSchema { + name: "first_name".to_owned(), + attribute_type: AttributeType::String, + is_list: false, + is_visible: true, + is_editable: true, + is_hardcoded: true, + }, + AttributeSchema { + name: "last_name".to_owned(), + attribute_type: AttributeType::String, + is_list: false, + is_visible: true, + is_editable: true, + is_hardcoded: true, + } + ], + group_attributes: Vec::new() + } + ); + } +} diff --git a/server/src/infra/ldap_handler.rs b/server/src/infra/ldap_handler.rs index 4266d95..c99455c 100644 --- a/server/src/infra/ldap_handler.rs +++ b/server/src/infra/ldap_handler.rs @@ -709,6 +709,10 @@ mod tests { async fn remove_user_from_group(&self, user_id: &UserId, group_id: GroupId) -> Result<()>; } #[async_trait] + impl SchemaBackendHandler for TestBackendHandler { + async fn get_schema(&self) -> Result; + } + #[async_trait] impl BackendHandler for TestBackendHandler {} #[async_trait] impl OpaqueHandler for TestBackendHandler {