diff --git a/src/config.rs b/src/config.rs index dbf991a..8508482 100644 --- a/src/config.rs +++ b/src/config.rs @@ -307,6 +307,8 @@ make_config! { ldap_search_filter: String, true, def, "(&(objectClass=*)(uid=*))".to_string(); /// Email field ldap_mail_field: String, true, def, "mail".to_string(); + /// Sync interval in seconds + ldap_sync_interval: u64, true, def, 600; }, } diff --git a/src/ldap.rs b/src/ldap.rs index 73270b6..d0270e1 100644 --- a/src/ldap.rs +++ b/src/ldap.rs @@ -5,9 +5,9 @@ extern crate tokio_timer; use std::error::Error; use std::thread; -use std::time::Duration; +use std::time::{Duration, Instant}; -use ldap3::{DerefAliases, LdapConn, LdapConnAsync, Scope, SearchEntry, SearchOptions}; +use ldap3::{DerefAliases, LdapConnAsync, Scope, SearchEntry, SearchOptions}; use tokio::prelude::*; use tokio::timer::Interval; use tokio_core::reactor::{Core, Handle}; @@ -17,121 +17,16 @@ use crate::db::models::{Invitation, User}; use crate::db::DbConn; use crate::CONFIG; -fn main() { - match do_search() { - Ok(_) => (), - Err(e) => println!("{}", e), - } -} - -/// Creates an LDAP connection, authenticating if necessary -fn ldap_client() -> Result> { - let scheme = if CONFIG.ldap_ssl() { "ldaps" } else { "ldap" }; - let host = CONFIG.ldap_host().unwrap(); - let port = CONFIG.ldap_port().to_string(); - - let ldap = LdapConn::new(&format!("{}://{}:{}", scheme, host, port))?; - - match (&CONFIG.ldap_bind_dn(), &CONFIG.ldap_bind_password()) { - (Some(bind_dn), Some(pass)) => { - match ldap.simple_bind(bind_dn, pass) { - _ => {} - }; - } - (_, _) => {} - }; - - Ok(ldap) -} - -/* - * /// Creates an LDAP connection, authenticating if necessary - * fn ldap_async_client(handle: &Handle, core: &Core) -> Result> { - * let scheme = if CONFIG.ldap_ssl() { "ldaps" } else { "ldap" }; - * let host = CONFIG.ldap_host().unwrap(); - * let port = CONFIG.ldap_port().to_string(); - * - * let ldap_uri = &format!("{}://{}:{}", scheme, host, port); - * - * let ldap = LdapConnAsync::new(ldap_uri, &handle)?.and_then(|ldap| { - * match (&CONFIG.ldap_bind_dn(), &CONFIG.ldap_bind_password()) { - * (Some(bind_dn), Some(pass)) => { - * match ldap.simple_bind(bind_dn, pass) { - * _ => {} - * }; - * } - * (_, _) => {} - * }; - * }); - * - * Ok(ldap) - * } - */ - -/// Retrieves search results from ldap -fn search_entries() -> Result, Box> { - let ldap = ldap_client()?; - - let mail_field = CONFIG.ldap_mail_field(); - let fields = vec!["uid", "givenname", "sn", "cn", mail_field.as_str()]; - - // TODO: Something something error handling - let (results, _res) = ldap - .with_search_options(SearchOptions::new().deref(DerefAliases::Always)) - .search( - &CONFIG.ldap_search_base_dn().unwrap(), - Scope::Subtree, - &CONFIG.ldap_search_filter(), - fields, - )? - .success()?; - - // Build list of entries - let mut entries = Vec::new(); - for result in results { - entries.push(SearchEntry::construct(result)); - } - - Ok(entries) -} - -pub fn do_search() -> Result<(), Box> { - let mail_field = CONFIG.ldap_mail_field(); - let entries = search_entries()?; - for user in entries { - println!("{:?}", user); - if let Some(user_email) = user.attrs[mail_field.as_str()].first() { - println!("{}", user_email); - } - } - - Ok(()) -} - -pub fn invite_from_ldap(conn: DbConn) -> Result<(), Box> { - let mail_field = CONFIG.ldap_mail_field(); - for ldap_user in search_entries()? { - if let Some(user_email) = ldap_user.attrs[mail_field.as_str()].first() { - let user = match User::find_by_mail(user_email.as_str(), &conn) { - Some(user) => println!("User already exists with email: {}", user_email), - None => println!("New user, should add to invites: {}", user_email), - }; - } - } - - Ok(()) -} - fn invite_from_results(conn: DbConn, results: Vec) -> Result<(), Box> { let mail_field = CONFIG.ldap_mail_field(); for ldap_user in results { if let Some(user_email) = ldap_user.attrs[mail_field.as_str()].first() { match User::find_by_mail(user_email.as_str(), &conn) { - Some(user) => println!("User already exists with email: {}", user_email), + Some(_) => println!("User already exists with email: {}", user_email), None => { println!("New user, should try to add invite: {}", user_email); match Invitation::find_by_mail(user_email.as_str(), &conn) { - Some(invite) => println!("User invite exists for {}", user_email), + Some(_) => println!("User invite exists for {}", user_email), None => { println!("Creating new invite for {}", user_email); Invitation::new(user_email.clone()).save(&conn)?; @@ -145,28 +40,6 @@ fn invite_from_results(conn: DbConn, results: Vec) -> Result<(), Bo Ok(()) } -pub fn start_ldap_sync_old() -> Result<(), Box> { - let duration = Duration::from_secs(2); - let task = Interval::new_interval(duration) - .take(10) - .for_each(|instant| { - let db_conn = db::get_dbconn().expect("Can't reach database"); - match invite_from_ldap(db_conn) { - Ok(_) => println!("Worked!"), - Err(e) => { - println!("{}", e); - panic!("Failed!"); - } - }; - Ok(()) - }) - .map_err(|e| panic!("interval errored: {:?}", e)); - - tokio::run(task); - - Ok(()) -} - fn new_ldap_client_async(handle: &Handle) -> Result> { let scheme = if CONFIG.ldap_ssl() { "ldaps" } else { "ldap" }; let host = CONFIG.ldap_host().unwrap(); @@ -210,6 +83,7 @@ fn ldap_sync(handle: &Handle) -> Result<(), Box> { entries.push(SearchEntry::construct(result)); } let conn = db::get_dbconn().expect("Can't reach database"); + // Can't figure out how to use this result invite_from_results(conn, entries); Ok(()) }) @@ -225,15 +99,18 @@ pub fn start_ldap_sync() -> Result<(), Box> { let mut core = Core::new().expect("Could not create core"); let handle = core.handle(); - let task = Interval::new_interval(Duration::from_secs(5)) - .take(10) - .for_each(|instant| { + let now = Instant::now(); + let sync_interval = CONFIG.ldap_sync_interval().clone(); + + let task = Interval::new(now, Duration::from_secs(sync_interval)) + .for_each(|_| { + // Can't figure out how to get this error handled ldap_sync(&handle); Ok(()) }) .map_err(|e| panic!("interval errored: {:?}", e)); - core.run(task); + core.run(task) }); Ok(())