mirror of
https://github.com/ViViDboarder/bitwarden_rs.git
synced 2024-12-22 11:37:45 +00:00
Woo! Got db connections
This commit is contained in:
parent
d3773a433a
commit
2de6ba6001
@ -99,6 +99,9 @@ handlebars = "1.1.0"
|
||||
soup = "0.3.0"
|
||||
regex = "1.1.0"
|
||||
|
||||
# LDAP libraries
|
||||
ldap3 = "0.6"
|
||||
|
||||
[patch.crates-io]
|
||||
# Add support for Timestamp type
|
||||
rmp = { git = 'https://github.com/dani-garcia/msgpack-rust' }
|
||||
|
@ -286,6 +286,28 @@ make_config! {
|
||||
/// Password
|
||||
smtp_password: Pass, true, option;
|
||||
},
|
||||
|
||||
/// LDAP settings
|
||||
ldap: _enable_ldap {
|
||||
/// Enabled
|
||||
_enable_ldap: bool, true, def, true;
|
||||
/// Host
|
||||
ldap_host: String, true, option;
|
||||
/// Enable SSL
|
||||
ldap_ssl: bool, true, def, false;
|
||||
/// Port
|
||||
ldap_port: u16, true, auto, |c| if c.ldap_ssl {636} else {389};
|
||||
/// Bind dn
|
||||
ldap_bind_dn: String, true, option;
|
||||
/// Bind password
|
||||
ldap_bind_password: Pass, true, option;
|
||||
/// Search base dn
|
||||
ldap_search_base_dn: String, true, option;
|
||||
/// Search filter
|
||||
ldap_search_filter: String, true, def, "(&(objectClass=*)(uid=*))".to_string();
|
||||
/// Email field
|
||||
ldap_mail_field: String, true, def, "mail".to_string();
|
||||
},
|
||||
}
|
||||
|
||||
fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
|
||||
@ -301,6 +323,10 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
|
||||
err!("Both `SMTP_USERNAME` and `SMTP_PASSWORD` need to be set to enable email authentication")
|
||||
}
|
||||
|
||||
if cfg.ldap_bind_dn.is_some() != cfg.ldap_bind_password.is_some() {
|
||||
err!("Both `LDAP_BIND_DN` and `LDAP_BIND_PASSWORD` need to be set to enable ldap authentication")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -398,6 +424,10 @@ impl Config {
|
||||
let inner = &self.inner.read().unwrap().config;
|
||||
inner._enable_yubico && inner.yubico_client_id.is_some() && inner.yubico_secret_key.is_some()
|
||||
}
|
||||
pub fn ldap_enabled(&self) -> bool {
|
||||
let inner = &self.inner.read().unwrap().config;
|
||||
inner._enable_ldap && inner.ldap_host.is_some() && inner.ldap_search_base_dn.is_some()
|
||||
}
|
||||
|
||||
pub fn render_template<T: serde::ser::Serialize>(
|
||||
&self,
|
||||
|
90
src/ldap.rs
Normal file
90
src/ldap.rs
Normal file
@ -0,0 +1,90 @@
|
||||
extern crate ldap3;
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
use ldap3::{DerefAliases, LdapConn, Scope, SearchEntry, SearchOptions};
|
||||
|
||||
use crate::db::models::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<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)
|
||||
}
|
||||
|
||||
/// 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(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user