server: extract graphql crate

This commit is contained in:
Valentin Tolmer
2025-04-05 00:24:24 -05:00
committed by nitnelave
parent db77a0f023
commit d38a2cd08b
11 changed files with 220 additions and 101 deletions
+75
View File
@@ -0,0 +1,75 @@
[package]
name = "lldap_graphql_server"
version = "0.1.0"
description = "GraphQL server for LLDAP"
edition.workspace = true
authors.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
[dependencies]
anyhow = "*"
juniper = "0.15"
serde_json = "1"
tracing = "*"
urlencoding = "2"
[dependencies.chrono]
features = ["serde"]
version = "*"
[dependencies.lldap_access_control]
path = "../access-control"
[dependencies.lldap_auth]
path = "../auth"
features = ["opaque_server", "opaque_client", "sea_orm"]
[dependencies.lldap_domain]
path = "../domain"
[dependencies.lldap_domain_model]
path = "../domain-model"
[dependencies.lldap_domain_handlers]
path = "../domain-handlers"
[dependencies.lldap_ldap]
path = "../ldap"
[dependencies.lldap_sql_backend_handler]
path = "../sql-backend-handler"
[dependencies.lldap_validation]
path = "../validation"
[dependencies.serde]
workspace = true
[dependencies.uuid]
features = ["v1", "v3"]
version = "1"
[dev-dependencies]
mockall = "0.11.4"
pretty_assertions = "1"
#[dev-dependencies.lldap_auth]
#path = "../auth"
#features = ["test"]
#
#[dev-dependencies.lldap_opaque_handler]
#path = "../opaque-handler"
#features = ["test"]
[dev-dependencies.lldap_test_utils]
path = "../test-utils"
#
#[dev-dependencies.lldap_sql_backend_handler]
#path = "../sql-backend-handler"
#features = ["test"]
[dev-dependencies.tokio]
features = ["full"]
version = "1.25"
+91
View File
@@ -0,0 +1,91 @@
use crate::{mutation::Mutation, query::Query};
use juniper::{EmptySubscription, FieldError, RootNode};
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;
pub struct Context<Handler: BackendHandler> {
pub handler: AccessControlledBackendHandler<Handler>,
pub validation_result: ValidationResults,
}
pub fn field_error_callback<'a>(
span: &'a tracing::Span,
error_message: &'a str,
) -> impl 'a + FnOnce() -> FieldError {
move || {
span.in_scope(|| debug!("Unauthorized"));
FieldError::from(error_message)
}
}
impl<Handler: BackendHandler> Context<Handler> {
#[cfg(test)]
pub fn new_for_tests(handler: Handler, validation_result: ValidationResults) -> Self {
Self {
handler: AccessControlledBackendHandler::new(handler),
validation_result,
}
}
pub fn get_admin_handler(&self) -> Option<&(impl AdminBackendHandler + use<Handler>)> {
self.handler.get_admin_handler(&self.validation_result)
}
pub fn get_readonly_handler(&self) -> Option<&(impl ReadonlyBackendHandler + use<Handler>)> {
self.handler.get_readonly_handler(&self.validation_result)
}
pub fn get_writeable_handler(
&self,
user_id: &UserId,
) -> Option<&(impl UserWriteableBackendHandler + use<Handler>)> {
self.handler
.get_writeable_handler(&self.validation_result, user_id)
}
pub fn get_readable_handler(
&self,
user_id: &UserId,
) -> Option<&(impl UserReadableBackendHandler + use<Handler>)> {
self.handler
.get_readable_handler(&self.validation_result, user_id)
}
}
impl<Handler: BackendHandler> juniper::Context for Context<Handler> {}
type Schema<Handler> =
RootNode<'static, Query<Handler>, Mutation<Handler>, EmptySubscription<Context<Handler>>>;
pub fn schema<Handler: BackendHandler>() -> Schema<Handler> {
Schema::new(
Query::<Handler>::new(),
Mutation::<Handler>::new(),
EmptySubscription::<Context<Handler>>::new(),
)
}
pub fn export_schema(output_file: Option<String>) -> anyhow::Result<()> {
use anyhow::Context;
use lldap_sql_backend_handler::SqlBackendHandler;
let output = schema::<SqlBackendHandler>().as_schema_language();
match output_file {
None => println!("{}", output),
Some(path) => {
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
let path = Path::new(&path);
let mut file =
File::create(path).context(format!("unable to open '{}'", path.display()))?;
file.write_all(output.as_bytes())
.context(format!("unable to write in '{}'", path.display()))?;
}
}
Ok(())
}
+3
View File
@@ -0,0 +1,3 @@
pub mod api;
pub mod mutation;
pub mod query;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff