Skip to main content

axess_core/federation/
ldap.rs

1//! Orchestrator-side LDAP code: `HealthCheck` impl for
2//! [`LdapProviderConfig`]. The verifier itself, the configuration
3//! struct, and the mock implementation live in [`axess_factors::ldap`].
4
5use crate::health::{HealthCheck, HealthStatus};
6use axess_factors::ldap::LdapProviderConfig;
7
8impl HealthCheck for LdapProviderConfig {
9    fn check(
10        &self,
11    ) -> std::pin::Pin<Box<dyn std::future::Future<Output = HealthStatus> + Send + '_>> {
12        Box::pin(async {
13            // Attempt a TCP connection to verify the LDAP server is reachable.
14            // This does not authenticate; it only checks connectivity.
15            match tokio::time::timeout(
16                self.connection_timeout,
17                ldap3::LdapConnAsync::new(&self.url),
18            )
19            .await
20            {
21                Ok(Ok((conn, mut ldap))) => {
22                    tokio::spawn(async move { conn.drive().await });
23                    if let Err(err) = ldap.unbind().await {
24                        tracing::trace!(
25                            target: "axess::federation::ldap",
26                            ?err,
27                            "ldap unbind on health-check teardown failed",
28                        );
29                    }
30                    HealthStatus::Healthy
31                }
32                Ok(Err(e)) => HealthStatus::Unhealthy(format!("LDAP connection failed: {e}")),
33                Err(_) => HealthStatus::Unhealthy(format!(
34                    "LDAP connection timeout ({}s)",
35                    self.connection_timeout.as_secs()
36                )),
37            }
38        })
39    }
40}