server: extract access_control to a separate crate

This commit is contained in:
Valentin Tolmer
2025-04-04 21:44:21 -05:00
committed by nitnelave
parent 0eef966c3e
commit dbba4c4e26
18 changed files with 97 additions and 73 deletions

13
Cargo.lock generated
View File

@@ -2541,6 +2541,7 @@ dependencies = [
"ldap3",
"ldap3_proto",
"lettre",
"lldap_access_control",
"lldap_auth",
"lldap_domain",
"lldap_domain_handlers",
@@ -2583,6 +2584,18 @@ dependencies = [
"webpki-roots 0.22.6",
]
[[package]]
name = "lldap_access_control"
version = "0.1.0"
dependencies = [
"async-trait",
"lldap_auth",
"lldap_domain",
"lldap_domain_handlers",
"lldap_domain_model",
"tracing",
]
[[package]]
name = "lldap_app"
version = "0.6.2-alpha"

View File

@@ -0,0 +1,26 @@
[package]
name = "lldap_access_control"
version = "0.1.0"
description = "Access control wrappers for LLDAP"
authors.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
[dependencies]
tracing = "*"
async-trait = "0.1"
[dependencies.lldap_auth]
path = "../auth"
features = ["opaque_server", "opaque_client", "sea_orm"]
[dependencies.lldap_domain]
path = "../domain"
[dependencies.lldap_domain_handlers]
path = "../domain-handlers"
[dependencies.lldap_domain_model]
path = "../domain-model"

View File

@@ -1,5 +1,3 @@
use std::collections::HashSet;
use async_trait::async_trait;
use lldap_auth::access_control::{Permission, ValidationResults};
use lldap_domain_handlers::handler::{
@@ -7,6 +5,7 @@ use lldap_domain_handlers::handler::{
ReadSchemaBackendHandler, SchemaBackendHandler, UserBackendHandler, UserListerBackendHandler,
UserRequestFilter,
};
use std::collections::HashSet;
use tracing::info;
use lldap_domain::{

View File

@@ -79,6 +79,9 @@ features = ["builder", "serde", "smtp-transport", "tokio1-rustls-tls"]
default-features = false
version = "0.10.1"
[dependencies.lldap_access_control]
path = "../crates/access-control"
[dependencies.lldap_auth]
path = "../crates/auth"
features = ["opaque_server", "opaque_client", "sea_orm"]

View File

@@ -1,8 +1,6 @@
use crate::{
domain::sql_backend_handler::SqlBackendHandler,
infra::access_control::UserReadableBackendHandler,
};
use async_trait::async_trait;
use crate::domain::sql_backend_handler::SqlBackendHandler;
use lldap_access_control::UserReadableBackendHandler;
use lldap_domain::{
requests::{CreateGroupRequest, UpdateGroupRequest},
types::{AttributeName, Group, GroupDetails, GroupId, Serialized, Uuid},

View File

@@ -1,3 +1,10 @@
use crate::{
domain::opaque_handler::OpaqueHandler,
infra::{
tcp_backend_handler::*,
tcp_server::{AppState, TcpError, TcpResult, error_to_http_response},
},
};
use actix_web::{
HttpRequest, HttpResponse,
cookie::{Cookie, SameSite},
@@ -12,6 +19,15 @@ use futures::future::{Ready, ok};
use futures_util::FutureExt;
use hmac::Hmac;
use jwt::{SignWithKey, VerifyWithKey};
use lldap_access_control::{ReadonlyBackendHandler, UserReadableBackendHandler};
use lldap_auth::{
JWTClaims, access_control::ValidationResults, login, password_reset, registration,
};
use lldap_domain::types::{GroupDetails, GroupName, UserId};
use lldap_domain_handlers::handler::{
BackendHandler, BindRequest, LoginHandler, UserRequestFilter,
};
use lldap_domain_model::{error::DomainError, model::UserColumn};
use sha2::Sha512;
use std::{
collections::HashSet,
@@ -22,24 +38,6 @@ use std::{
use time::ext::NumericalDuration;
use tracing::{debug, info, instrument, warn};
use lldap_auth::{
JWTClaims, access_control::ValidationResults, login, password_reset, registration,
};
use lldap_domain::types::{GroupDetails, GroupName, UserId};
use lldap_domain_handlers::handler::{
BackendHandler, BindRequest, LoginHandler, UserRequestFilter,
};
use lldap_domain_model::{error::DomainError, model::UserColumn};
use crate::{
domain::opaque_handler::OpaqueHandler,
infra::{
access_control::{ReadonlyBackendHandler, UserReadableBackendHandler},
tcp_backend_handler::*,
tcp_server::{AppState, TcpError, TcpResult, error_to_http_response},
},
};
type Token<S> = jwt::Token<jwt::Header, JWTClaims, S>;
type SignedToken = Token<jwt::token::Signed>;

View File

@@ -1,14 +1,9 @@
use crate::infra::{
access_control::{
AccessControlledBackendHandler, AdminBackendHandler, ReadonlyBackendHandler,
UserReadableBackendHandler, UserWriteableBackendHandler,
},
auth_service::check_if_token_is_valid,
cli::ExportGraphQLSchemaOpts,
graphql::{mutation::Mutation, query::Query},
tcp_server::AppState,
};
use actix_web::FromRequest;
use actix_web::HttpMessage;
use actix_web::{Error, HttpRequest, HttpResponse, error::JsonPayloadError, web};
@@ -20,6 +15,10 @@ use juniper::{
playground::playground_source,
},
};
use lldap_access_control::{
AccessControlledBackendHandler, AdminBackendHandler, ReadonlyBackendHandler,
UserReadableBackendHandler, UserWriteableBackendHandler,
};
use lldap_auth::{access_control::ValidationResults, types::UserId};
use lldap_domain_handlers::handler::BackendHandler;
use tracing::debug;

View File

@@ -1,17 +1,13 @@
use std::{collections::BTreeMap, sync::Arc};
use crate::{
domain::deserialize::deserialize_attribute_value,
infra::{
access_control::{
AdminBackendHandler, ReadonlyBackendHandler, UserReadableBackendHandler,
UserWriteableBackendHandler,
},
graphql::api::{Context, field_error_callback},
},
infra::graphql::api::{Context, field_error_callback},
};
use anyhow::{Context as AnyhowContext, anyhow};
use juniper::{FieldError, FieldResult, GraphQLInputObject, GraphQLObject, graphql_object};
use lldap_access_control::{
AdminBackendHandler, ReadonlyBackendHandler, UserReadableBackendHandler,
UserWriteableBackendHandler,
};
use lldap_domain::{
public_schema::PublicSchema,
requests::{
@@ -26,6 +22,7 @@ use lldap_domain::{
};
use lldap_domain_handlers::handler::BackendHandler;
use lldap_validation::attributes::{ALLOWED_CHARACTERS_DESCRIPTION, validate_attribute_name};
use std::{collections::BTreeMap, sync::Arc};
use tracing::{Instrument, Span, debug, debug_span};
#[derive(PartialEq, Eq, Debug)]

View File

@@ -5,14 +5,12 @@ use crate::{
deserialize::deserialize_attribute_value,
ldap::utils::{UserFieldType, map_user_field},
},
infra::{
access_control::{ReadonlyBackendHandler, UserReadableBackendHandler},
graphql::api::{Context, field_error_callback},
},
infra::graphql::api::{Context, field_error_callback},
};
use anyhow::Context as AnyhowContext;
use chrono::TimeZone;
use juniper::{FieldResult, GraphQLInputObject, graphql_object};
use lldap_access_control::{ReadonlyBackendHandler, UserReadableBackendHandler};
use lldap_domain::{
public_schema::PublicSchema,
types::{AttributeType, Cardinality, GroupDetails, GroupId, LdapObjectClass, UserId},

View File

@@ -6,11 +6,12 @@ use crate::{
utils::{LdapInfo, UserOrGroupName, get_user_or_group_id_from_distinguished_name},
},
},
infra::{access_control::AdminBackendHandler, ldap::handler::make_add_response},
infra::ldap::handler::make_add_response,
};
use ldap3_proto::proto::{
LdapAddRequest, LdapAttribute, LdapOp, LdapPartialAttribute, LdapResultCode,
};
use lldap_access_control::AdminBackendHandler;
use lldap_domain::{
requests::{CreateGroupRequest, CreateUserRequest},
types::{Attribute, AttributeName, AttributeType, Email, GroupName, UserId},

View File

@@ -3,8 +3,8 @@ use crate::{
error::{LdapError, LdapResult},
utils::{LdapInfo, UserOrGroupName, get_user_or_group_id_from_distinguished_name},
},
infra::access_control::AdminBackendHandler,
};
use lldap_access_control::AdminBackendHandler;
use ldap3_proto::proto::{LdapOp, LdapResult as LdapResultOp, LdapResultCode};
use lldap_domain::types::{GroupName, UserId};
use lldap_domain_handlers::handler::GroupRequestFilter;

View File

@@ -6,15 +6,12 @@ use crate::{
},
opaque_handler::OpaqueHandler,
},
infra::{
access_control::AccessControlledBackendHandler,
ldap::{
compare, create, delete, modify,
password::{self, do_password_modification},
search::{
self, is_root_dse_request, make_search_error, make_search_request,
make_search_success, root_dse_response,
},
infra::ldap::{
compare, create, delete, modify,
password::{self, do_password_modification},
search::{
self, is_root_dse_request, make_search_error, make_search_request, make_search_success,
root_dse_response,
},
},
};
@@ -23,6 +20,7 @@ use ldap3_proto::proto::{
LdapExtendedResponse, LdapFilter, LdapModifyRequest, LdapOp, LdapPasswordModifyRequest,
LdapResult as LdapResultOp, LdapResultCode, LdapSearchRequest, OID_PASSWORD_MODIFY, OID_WHOAMI,
};
use lldap_access_control::AccessControlledBackendHandler;
use lldap_auth::access_control::ValidationResults;
use lldap_domain::types::AttributeName;
use lldap_domain_handlers::handler::{BackendHandler, LoginHandler};

View File

@@ -6,15 +6,13 @@ use crate::{
},
opaque_handler::OpaqueHandler,
},
infra::{
access_control::UserReadableBackendHandler,
ldap::{
handler::make_modify_response,
password::{self},
},
infra::ldap::{
handler::make_modify_response,
password::{self},
},
};
use ldap3_proto::proto::{LdapModify, LdapModifyRequest, LdapModifyType, LdapOp, LdapResultCode};
use lldap_access_control::UserReadableBackendHandler;
use lldap_auth::access_control::ValidationResults;
use lldap_domain::types::UserId;

View File

@@ -7,10 +7,10 @@ use crate::{
opaque_handler::OpaqueHandler,
},
infra::{
access_control::{AccessControlledBackendHandler, UserReadableBackendHandler},
ldap::handler::make_extended_response,
},
};
use lldap_access_control::{AccessControlledBackendHandler, UserReadableBackendHandler};
use anyhow::Result;
use ldap3_proto::proto::{
LdapBindCred, LdapBindRequest, LdapOp, LdapPasswordModifyRequest, LdapResultCode,

View File

@@ -1,3 +1,9 @@
use crate::domain::ldap::{
error::{LdapError, LdapResult},
group::{convert_groups_to_ldap_op, get_groups_list},
user::{convert_users_to_ldap_op, get_user_list},
utils::{LdapInfo, is_subtree, parse_distinguished_name},
};
use ldap3_proto::{
LdapFilter, LdapPartialAttribute, LdapResultCode, LdapSearchResultEntry, LdapSearchScope,
proto::{
@@ -5,22 +11,13 @@ use ldap3_proto::{
OID_PASSWORD_MODIFY, OID_WHOAMI,
},
};
use lldap_access_control::UserAndGroupListerBackendHandler;
use lldap_domain::{
public_schema::PublicSchema,
types::{Group, UserAndGroups},
};
use tracing::{debug, instrument, warn};
use crate::{
domain::ldap::{
error::{LdapError, LdapResult},
group::{convert_groups_to_ldap_op, get_groups_list},
user::{convert_users_to_ldap_op, get_user_list},
utils::{LdapInfo, is_subtree, parse_distinguished_name},
},
infra::access_control::UserAndGroupListerBackendHandler,
};
#[derive(Debug)]
enum SearchScope {
Global,

View File

@@ -1,11 +1,11 @@
use crate::{
domain::opaque_handler::OpaqueHandler,
infra::{
access_control::AccessControlledBackendHandler,
configuration::{Configuration, LdapsOptions},
ldap::handler::LdapHandler,
},
};
use lldap_access_control::AccessControlledBackendHandler;
use actix_rt::net::TcpStream;
use actix_server::ServerBuilder;
use actix_service::{ServiceFactoryExt, fn_service};

View File

@@ -1,4 +1,3 @@
pub mod access_control;
pub mod auth_service;
pub mod cli;
pub mod configuration;

View File

@@ -1,13 +1,13 @@
use crate::{
domain::opaque_handler::OpaqueHandler,
infra::{
access_control::{AccessControlledBackendHandler, ReadonlyBackendHandler},
auth_service,
configuration::{Configuration, MailOptions},
logging::CustomRootSpanBuilder,
tcp_backend_handler::*,
},
};
use lldap_access_control::{AccessControlledBackendHandler, ReadonlyBackendHandler};
use actix_files::Files;
use actix_http::{HttpServiceBuilder, header};
use actix_server::ServerBuilder;