1use async_trait::async_trait;
2use ldap3::{exop::WhoAmI, Ldap, LdapConnAsync, LdapConnSettings, LdapError};
3
4pub struct Manager(String, LdapConnSettings);
5pub type Pool = deadpool::managed::Pool<Manager>;
6
7impl Manager {
9 pub fn new<S: Into<String>>(ldap_url: S) -> Self {
12 Self(ldap_url.into(), LdapConnSettings::new())
13 }
14
15 pub fn with_connection_settings(mut self, settings: LdapConnSettings) -> Self {
18 self.1 = settings;
19 self
20 }
21}
22
23#[async_trait]
24impl deadpool::managed::Manager for Manager {
25 type Type = Ldap;
26 type Error = LdapError;
27
28 async fn create(&self) -> Result<Self::Type, Self::Error> {
29 let (conn, ldap) = LdapConnAsync::with_settings(self.1.clone(), &self.0).await?;
30 #[cfg(feature = "default")]
31 ldap3::drive!(conn);
32 #[cfg(feature = "rt-actix")]
33 actix_rt::spawn(async move {
34 if let Err(e) = conn.drive().await {
35 log::warn!("LDAP connection error: {:?}", e);
36 }
37 });
38 Ok(ldap)
39 }
40 async fn recycle(&self, conn: &mut Self::Type) -> deadpool::managed::RecycleResult<Self::Error> {
41 conn.extended(WhoAmI).await?;
42 Ok(())
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use std::time::Duration;
49 use super::*;
50
51 #[test]
52 fn manager_new_sets_url() {
53 let manager = Manager::new("my_url");
54
55 assert_eq!(manager.0, "my_url");
56 }
57
58 #[cfg(any(feature = "tls-native", feature = "tls-rustls"))]
61 #[test]
62 fn manager_new_sets_default_connection_settings() {
63 let manager = Manager::new("my_url");
64 let default = LdapConnSettings::new();
65
66 assert_eq!(manager.1.starttls(), default.starttls());
67 }
68
69 fn is_manager(s: &dyn std::any::Any) -> bool {
70 std::any::TypeId::of::<Manager>() == s.type_id()
71 }
72
73 #[test]
74 fn manager_with_connection_settings_returns_manager() {
75 let manager = Manager::new("my_url")
76 .with_connection_settings(
77 LdapConnSettings::new()
78 .set_conn_timeout(Duration::from_secs(30))
79 );
80 assert!(is_manager(&manager));
81 }
82
83 #[cfg(any(feature = "tls-native", feature = "tls-rustls"))]
84 #[test]
85 fn manager_with_connection_settings_updates_settings() {
86 let manager = Manager::new("my_url")
87 .with_connection_settings(
88 LdapConnSettings::new()
89 .set_conn_timeout(Duration::from_secs(30))
90 .set_starttls(true)
91 );
92 let default = LdapConnSettings::new();
93
94 assert_ne!(manager.1.starttls(), default.starttls());
95 }
96}