diff --git a/model/src/lib.rs b/model/src/lib.rs index 3125629..c078495 100644 --- a/model/src/lib.rs +++ b/model/src/lib.rs @@ -67,19 +67,6 @@ pub mod registration { } } -#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] -pub enum RequestFilter { - And(Vec), - Or(Vec), - Not(Box), - Equality(String, String), -} - -#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] -pub struct ListUsersRequest { - pub filters: Option, -} - #[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] pub struct UserDetailsRequest { pub user_id: String, diff --git a/src/domain/handler.rs b/src/domain/handler.rs index bab3de2..55edc45 100644 --- a/src/domain/handler.rs +++ b/src/domain/handler.rs @@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize}; use std::collections::HashSet; pub use lldap_model::{ - AddUserToGroupRequest, CreateGroupRequest, CreateUserRequest, DeleteUserRequest, Group, - ListUsersRequest, RequestFilter, User, UserDetailsRequest, + AddUserToGroupRequest, CreateGroupRequest, CreateUserRequest, DeleteUserRequest, Group, User, + UserDetailsRequest, }; #[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] @@ -14,6 +14,14 @@ pub struct BindRequest { pub password: String, } +#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, Clone)] +pub enum RequestFilter { + And(Vec), + Or(Vec), + Not(Box), + Equality(String, String), +} + #[async_trait] pub trait LoginHandler: Clone + Send { async fn bind(&self, request: BindRequest) -> Result<()>; @@ -21,7 +29,7 @@ pub trait LoginHandler: Clone + Send { #[async_trait] pub trait BackendHandler: Clone + Send { - async fn list_users(&self, request: ListUsersRequest) -> Result>; + async fn list_users(&self, filters: Option) -> Result>; async fn list_groups(&self) -> Result>; async fn get_user_details(&self, request: UserDetailsRequest) -> Result; async fn create_user(&self, request: CreateUserRequest) -> Result<()>; @@ -39,7 +47,7 @@ mockall::mock! { } #[async_trait] impl BackendHandler for TestBackendHandler { - async fn list_users(&self, request: ListUsersRequest) -> Result>; + async fn list_users(&self, filters: Option) -> Result>; async fn list_groups(&self) -> Result>; async fn get_user_details(&self, request: UserDetailsRequest) -> Result; async fn create_user(&self, request: CreateUserRequest) -> Result<()>; diff --git a/src/domain/sql_backend_handler.rs b/src/domain/sql_backend_handler.rs index d037503..e4f6a14 100644 --- a/src/domain/sql_backend_handler.rs +++ b/src/domain/sql_backend_handler.rs @@ -42,7 +42,7 @@ fn get_filter_expr(filter: RequestFilter) -> SimpleExpr { #[async_trait] impl BackendHandler for SqlBackendHandler { - async fn list_users(&self, request: ListUsersRequest) -> Result> { + async fn list_users(&self, filters: Option) -> Result> { let query = { let mut query_builder = Query::select() .column(Users::UserId) @@ -55,7 +55,7 @@ impl BackendHandler for SqlBackendHandler { .from(Users::Table) .order_by(Users::UserId, Order::Asc) .to_owned(); - if let Some(filter) = request.filters { + if let Some(filter) = filters { if filter != RequestFilter::And(Vec::new()) && filter != RequestFilter::Or(Vec::new()) { @@ -234,6 +234,7 @@ mod tests { use super::*; use crate::domain::sql_tables::init_table; use crate::infra::configuration::ConfigurationBuilder; + use lldap_model::{opaque, registration}; fn get_default_config() -> Configuration { ConfigurationBuilder::default() @@ -384,7 +385,7 @@ mod tests { insert_user(&handler, "John", "Pa33w0rd!").await; { let users = handler - .list_users(ListUsersRequest { filters: None }) + .list_users(None) .await .unwrap() .into_iter() @@ -394,12 +395,10 @@ mod tests { } { let users = handler - .list_users(ListUsersRequest { - filters: Some(RequestFilter::Equality( - "user_id".to_string(), - "bob".to_string(), - )), - }) + .list_users(Some(RequestFilter::Equality( + "user_id".to_string(), + "bob".to_string(), + ))) .await .unwrap() .into_iter() @@ -409,12 +408,10 @@ mod tests { } { let users = handler - .list_users(ListUsersRequest { - filters: Some(RequestFilter::Or(vec![ - RequestFilter::Equality("user_id".to_string(), "bob".to_string()), - RequestFilter::Equality("user_id".to_string(), "John".to_string()), - ])), - }) + .list_users(Some(RequestFilter::Or(vec![ + RequestFilter::Equality("user_id".to_string(), "bob".to_string()), + RequestFilter::Equality("user_id".to_string(), "John".to_string()), + ]))) .await .unwrap() .into_iter() @@ -424,12 +421,10 @@ mod tests { } { let users = handler - .list_users(ListUsersRequest { - filters: Some(RequestFilter::Not(Box::new(RequestFilter::Equality( - "user_id".to_string(), - "bob".to_string(), - )))), - }) + .list_users(Some(RequestFilter::Not(Box::new(RequestFilter::Equality( + "user_id".to_string(), + "bob".to_string(), + ))))) .await .unwrap() .into_iter() @@ -540,7 +535,7 @@ mod tests { .unwrap(); let users = handler - .list_users(ListUsersRequest { filters: None }) + .list_users(None) .await .unwrap() .into_iter() @@ -565,7 +560,7 @@ mod tests { .unwrap(); let users = handler - .list_users(ListUsersRequest { filters: None }) + .list_users(None) .await .unwrap() .into_iter() diff --git a/src/infra/graphql/query.rs b/src/infra/graphql/query.rs index 870f53b..6ca6e02 100644 --- a/src/infra/graphql/query.rs +++ b/src/infra/graphql/query.rs @@ -1,9 +1,10 @@ use crate::domain::handler::BackendHandler; use juniper::{graphql_object, FieldResult, GraphQLInputObject}; -use lldap_model::{ListUsersRequest, UserDetailsRequest}; +use lldap_model::UserDetailsRequest; use serde::{Deserialize, Serialize}; use std::convert::TryInto; +type DomainRequestFilter = crate::domain::handler::RequestFilter; use super::api::Context; #[derive(PartialEq, Eq, Debug, GraphQLInputObject)] @@ -16,9 +17,9 @@ pub struct RequestFilter { eq: Option, } -impl TryInto for RequestFilter { +impl TryInto for RequestFilter { type Error = String; - fn try_into(self) -> Result { + fn try_into(self) -> Result { let mut field_count = 0; if self.any.is_some() { field_count += 1; @@ -39,24 +40,24 @@ impl TryInto for RequestFilter { return Err("Multiple fields specified in request filter".to_string()); } if let Some(e) = self.eq { - return Ok(lldap_model::RequestFilter::Equality(e.field, e.value)); + return Ok(DomainRequestFilter::Equality(e.field, e.value)); } if let Some(c) = self.any { - return Ok(lldap_model::RequestFilter::Or( + return Ok(DomainRequestFilter::Or( c.into_iter() .map(TryInto::try_into) .collect::, String>>()?, )); } if let Some(c) = self.all { - return Ok(lldap_model::RequestFilter::And( + return Ok(DomainRequestFilter::And( c.into_iter() .map(TryInto::try_into) .collect::, String>>()?, )); } if let Some(c) = self.not { - return Ok(lldap_model::RequestFilter::Not(Box::new((*c).try_into()?))); + return Ok(DomainRequestFilter::Not(Box::new((*c).try_into()?))); } unreachable!(); } @@ -108,12 +109,7 @@ impl Query { } Ok(context .handler - .list_users(ListUsersRequest { - filters: match filters { - None => None, - Some(f) => Some(f.try_into()?), - }, - }) + .list_users(filters.map(TryInto::try_into).transpose()?) .await .map(|v| v.into_iter().map(Into::into).collect())?) } @@ -304,14 +300,13 @@ mod tests { }"#; let mut mock = MockTestBackendHandler::new(); - use lldap_model::{RequestFilter, User}; + use crate::domain::handler::RequestFilter; + use lldap_model::User; mock.expect_list_users() - .with(eq(ListUsersRequest { - filters: Some(RequestFilter::Or(vec![ - RequestFilter::Equality("id".to_string(), "bob".to_string()), - RequestFilter::Equality("email".to_string(), "robert@bobbers.on".to_string()), - ])), - })) + .with(eq(Some(RequestFilter::Or(vec![ + RequestFilter::Equality("id".to_string(), "bob".to_string()), + RequestFilter::Equality("email".to_string(), "robert@bobbers.on".to_string()), + ])))) .return_once(|_| { Ok(vec![ User { diff --git a/src/infra/ldap_handler.rs b/src/infra/ldap_handler.rs index 4cebc8e..46149f1 100644 --- a/src/infra/ldap_handler.rs +++ b/src/infra/ldap_handler.rs @@ -1,4 +1,4 @@ -use crate::domain::handler::{BackendHandler, ListUsersRequest, LoginHandler, RequestFilter, User}; +use crate::domain::handler::{BackendHandler, LoginHandler, RequestFilter, User}; use anyhow::{bail, Result}; use ldap3_server::simple::*; @@ -226,11 +226,7 @@ impl LdapHandler { )] } }; - let users = match self - .backend_handler - .list_users(ListUsersRequest { filters }) - .await - { + let users = match self.backend_handler.list_users(filters).await { Ok(users) => users, Err(e) => { return vec![lsr.gen_error( @@ -591,14 +587,12 @@ mod tests { async fn test_search_filters() { let mut mock = MockTestBackendHandler::new(); mock.expect_list_users() - .with(eq(ListUsersRequest { - filters: Some(RequestFilter::And(vec![RequestFilter::Or(vec![ - RequestFilter::Not(Box::new(RequestFilter::Equality( - "user_id".to_string(), - "bob".to_string(), - ))), - ])])), - })) + .with(eq(Some(RequestFilter::And(vec![RequestFilter::Or(vec![ + RequestFilter::Not(Box::new(RequestFilter::Equality( + "user_id".to_string(), + "bob".to_string(), + ))), + ])])))) .times(1) .return_once(|_| Ok(vec![])); let mut ldap_handler = setup_bound_handler(mock).await; diff --git a/src/infra/tcp_backend_handler.rs b/src/infra/tcp_backend_handler.rs index d647e25..823ccc4 100644 --- a/src/infra/tcp_backend_handler.rs +++ b/src/infra/tcp_backend_handler.rs @@ -26,7 +26,7 @@ mockall::mock! { } #[async_trait] impl BackendHandler for TestTcpBackendHandler { - async fn list_users(&self, request: ListUsersRequest) -> DomainResult>; + async fn list_users(&self, filters: Option) -> DomainResult>; async fn list_groups(&self) -> DomainResult>; async fn get_user_details(&self, request: UserDetailsRequest) -> DomainResult; async fn get_user_groups(&self, user: &str) -> DomainResult>;