mirror of
https://github.com/ViViDboarder/bitwarden_rs.git
synced 2024-11-25 06:36:37 +00:00
Add sync interval
This commit is contained in:
parent
ca7ff10057
commit
80a2e4bd13
@ -307,6 +307,8 @@ make_config! {
|
|||||||
ldap_search_filter: String, true, def, "(&(objectClass=*)(uid=*))".to_string();
|
ldap_search_filter: String, true, def, "(&(objectClass=*)(uid=*))".to_string();
|
||||||
/// Email field
|
/// Email field
|
||||||
ldap_mail_field: String, true, def, "mail".to_string();
|
ldap_mail_field: String, true, def, "mail".to_string();
|
||||||
|
/// Sync interval in seconds
|
||||||
|
ldap_sync_interval: u64, true, def, 600;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
147
src/ldap.rs
147
src/ldap.rs
@ -5,9 +5,9 @@ extern crate tokio_timer;
|
|||||||
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::thread;
|
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::prelude::*;
|
||||||
use tokio::timer::Interval;
|
use tokio::timer::Interval;
|
||||||
use tokio_core::reactor::{Core, Handle};
|
use tokio_core::reactor::{Core, Handle};
|
||||||
@ -17,121 +17,16 @@ use crate::db::models::{Invitation, User};
|
|||||||
use crate::db::DbConn;
|
use crate::db::DbConn;
|
||||||
use crate::CONFIG;
|
use crate::CONFIG;
|
||||||
|
|
||||||
fn main() {
|
|
||||||
match do_search() {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => println!("{}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an LDAP connection, authenticating if necessary
|
|
||||||
fn ldap_client() -> Result<LdapConn, Box<Error>> {
|
|
||||||
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<LdapConnAsync, Box<Error>> {
|
|
||||||
* 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<Vec<SearchEntry>, Box<Error>> {
|
|
||||||
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<Error>> {
|
|
||||||
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<Error>> {
|
|
||||||
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<SearchEntry>) -> Result<(), Box<Error>> {
|
fn invite_from_results(conn: DbConn, results: Vec<SearchEntry>) -> Result<(), Box<Error>> {
|
||||||
let mail_field = CONFIG.ldap_mail_field();
|
let mail_field = CONFIG.ldap_mail_field();
|
||||||
for ldap_user in results {
|
for ldap_user in results {
|
||||||
if let Some(user_email) = ldap_user.attrs[mail_field.as_str()].first() {
|
if let Some(user_email) = ldap_user.attrs[mail_field.as_str()].first() {
|
||||||
match User::find_by_mail(user_email.as_str(), &conn) {
|
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 => {
|
None => {
|
||||||
println!("New user, should try to add invite: {}", user_email);
|
println!("New user, should try to add invite: {}", user_email);
|
||||||
match Invitation::find_by_mail(user_email.as_str(), &conn) {
|
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 => {
|
None => {
|
||||||
println!("Creating new invite for {}", user_email);
|
println!("Creating new invite for {}", user_email);
|
||||||
Invitation::new(user_email.clone()).save(&conn)?;
|
Invitation::new(user_email.clone()).save(&conn)?;
|
||||||
@ -145,28 +40,6 @@ fn invite_from_results(conn: DbConn, results: Vec<SearchEntry>) -> Result<(), Bo
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_ldap_sync_old() -> Result<(), Box<Error>> {
|
|
||||||
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<LdapConnAsync, Box<Error>> {
|
fn new_ldap_client_async(handle: &Handle) -> Result<LdapConnAsync, Box<Error>> {
|
||||||
let scheme = if CONFIG.ldap_ssl() { "ldaps" } else { "ldap" };
|
let scheme = if CONFIG.ldap_ssl() { "ldaps" } else { "ldap" };
|
||||||
let host = CONFIG.ldap_host().unwrap();
|
let host = CONFIG.ldap_host().unwrap();
|
||||||
@ -210,6 +83,7 @@ fn ldap_sync(handle: &Handle) -> Result<(), Box<Error>> {
|
|||||||
entries.push(SearchEntry::construct(result));
|
entries.push(SearchEntry::construct(result));
|
||||||
}
|
}
|
||||||
let conn = db::get_dbconn().expect("Can't reach database");
|
let conn = db::get_dbconn().expect("Can't reach database");
|
||||||
|
// Can't figure out how to use this result
|
||||||
invite_from_results(conn, entries);
|
invite_from_results(conn, entries);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -225,15 +99,18 @@ pub fn start_ldap_sync() -> Result<(), Box<Error>> {
|
|||||||
let mut core = Core::new().expect("Could not create core");
|
let mut core = Core::new().expect("Could not create core");
|
||||||
let handle = core.handle();
|
let handle = core.handle();
|
||||||
|
|
||||||
let task = Interval::new_interval(Duration::from_secs(5))
|
let now = Instant::now();
|
||||||
.take(10)
|
let sync_interval = CONFIG.ldap_sync_interval().clone();
|
||||||
.for_each(|instant| {
|
|
||||||
|
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);
|
ldap_sync(&handle);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.map_err(|e| panic!("interval errored: {:?}", e));
|
.map_err(|e| panic!("interval errored: {:?}", e));
|
||||||
|
|
||||||
core.run(task);
|
core.run(task)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user