renamed bitwarden_root_cert into bitwarden_root_cert_file

separate get_root_cert() function
formatting (rustfmt)
This commit is contained in:
jerhat 2020-07-10 11:14:12 +08:00
parent acf8165bed
commit f5b94ee792
4 changed files with 38 additions and 40 deletions

View File

@ -19,7 +19,7 @@ Configuration values are as follows:
|----|----|--------|-----------| |----|----|--------|-----------|
|`bitwarden_url`|String||The root URL for accessing `bitwarden_rs`. Eg: `https://bw.example.com`| |`bitwarden_url`|String||The root URL for accessing `bitwarden_rs`. Eg: `https://bw.example.com`|
|`bitwarden_admin_token`|String||The value passed as `ADMIN_TOKEN` to `bitwarden_rs`| |`bitwarden_admin_token`|String||The value passed as `ADMIN_TOKEN` to `bitwarden_rs`|
|`bitwarden_root_cert`|String|Optional|Path to an additional der-encoded root certificate to trust. Eg. `root.cert`. If using Docker see `docker-compose.yml` for how to expose it. Defaults to `empty`| |`bitwarden_root_cert_file`|String|Optional|Path to an additional der-encoded root certificate to trust. Eg. `root.cert`. If using Docker see `docker-compose.yml` for how to expose it. Defaults to `empty`|
|`ldap_host`|String||The hostname or IP address for your ldap server| |`ldap_host`|String||The hostname or IP address for your ldap server|
|`ldap_scheme`|String|Optional|The that should be used to connect. `ldap` or `ldaps`. This is set by default based on SSL settings| |`ldap_scheme`|String|Optional|The that should be used to connect. `ldap` or `ldaps`. This is set by default based on SSL settings|
|`ldap_ssl`|Boolean|Optional|Indicates if SSL should be used. Defaults to `false`| |`ldap_ssl`|Boolean|Optional|Indicates if SSL should be used. Defaults to `false`|

View File

@ -5,9 +5,9 @@ use reqwest::Response;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::time::{Duration, Instant};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::time::{Duration, Instant};
const COOKIE_LIFESPAN: Duration = Duration::from_secs(20 * 60); const COOKIE_LIFESPAN: Duration = Duration::from_secs(20 * 60);
@ -33,39 +33,40 @@ impl User {
pub struct Client { pub struct Client {
url: String, url: String,
admin_token: String, admin_token: String,
root_cert: String, root_cert_file: String,
cookie: Option<String>, cookie: Option<String>,
cookie_created: Option<Instant> cookie_created: Option<Instant>,
} }
impl Client { impl Client {
/// Create new instance of client /// Create new instance of client
pub fn new(url: String, admin_token: String, root_cert: String) -> Client { pub fn new(url: String, admin_token: String, root_cert_file: String) -> Client {
Client { Client {
url, url,
admin_token, admin_token,
root_cert, root_cert_file,
cookie: None, cookie: None,
cookie_created: None cookie_created: None,
} }
} }
fn get_root_cert(&self) -> reqwest::Certificate {
let mut buf = Vec::new();
// read a local binary DER encoded certificate
File::open(&self.root_cert_file)
.expect("Could not open root cert file")
.read_to_end(&mut buf)
.expect("Could not read root cert file");
return reqwest::Certificate::from_der(&buf).expect("Could not load der root cert file");
}
fn get_http_client(&self) -> reqwest::Client { fn get_http_client(&self) -> reqwest::Client {
let mut client = reqwest::Client::builder().redirect(reqwest::RedirectPolicy::none());
let mut client = reqwest::Client::builder() if !&self.root_cert_file.is_empty() {
.redirect(reqwest::RedirectPolicy::none()); let cert = self.get_root_cert();
if !&self.root_cert.is_empty() {
let mut buf = Vec::new();
// read a local binary DER encoded certificate
File::open(&self.root_cert).expect("cannot open root cert").read_to_end(&mut buf).expect("cannot read root cert");
// create a certificate
let cert = reqwest::Certificate::from_der(&buf).expect("could not load der certificate");
// add the root cert
client = client.add_root_certificate(cert); client = client.add_root_certificate(cert);
} }
@ -74,9 +75,8 @@ impl Client {
/// Authenticate client /// Authenticate client
fn auth(&mut self) -> Response { fn auth(&mut self) -> Response {
let cookie_created = Instant::now(); let cookie_created = Instant::now();
let client = &self.get_http_client(); let client = self.get_http_client();
let result = client let result = client
.post(format!("{}{}", &self.url, "/admin/").as_str()) .post(format!("{}{}", &self.url, "/admin/").as_str())
.form(&[("token", &self.admin_token)]) .form(&[("token", &self.admin_token)])
@ -126,7 +126,8 @@ impl Client {
Some(cookie) => { Some(cookie) => {
let url = format!("{}/admin{}", &self.url, path); let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client(); let client = self.get_http_client();
let request = client.get(url.as_str()) let request = client
.get(url.as_str())
.header(reqwest::header::COOKIE, cookie.clone()); .header(reqwest::header::COOKIE, cookie.clone());
let response = request.send().unwrap_or_else(|e| { let response = request.send().unwrap_or_else(|e| {
panic!("Could not call with {}. {:?}", url, e); panic!("Could not call with {}. {:?}", url, e);
@ -150,7 +151,8 @@ impl Client {
Some(cookie) => { Some(cookie) => {
let url = format!("{}/admin{}", &self.url, path); let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client(); let client = self.get_http_client();
let request = client.post(url.as_str()) let request = client
.post(url.as_str())
.header("Cookie", cookie.clone()) .header("Cookie", cookie.clone())
.json(&json); .json(&json);
let response = request.send().unwrap_or_else(|e| { let response = request.send().unwrap_or_else(|e| {

View File

@ -38,13 +38,12 @@ pub struct Config {
// Bitwarden connection config // Bitwarden connection config
bitwarden_url: String, bitwarden_url: String,
bitwarden_admin_token: String, bitwarden_admin_token: String,
bitwarden_root_cert: Option<String>, bitwarden_root_cert_file: Option<String>,
// LDAP Connection config // LDAP Connection config
ldap_host: String, ldap_host: String,
ldap_scheme: Option<String>, ldap_scheme: Option<String>,
ldap_ssl: Option<bool>, ldap_ssl: Option<bool>,
ldap_port: Option<u16>, ldap_port: Option<u16>,
// LDAP skip tls verify
ldap_no_tls_verify: Option<bool>, ldap_no_tls_verify: Option<bool>,
// LDAP auth config // LDAP auth config
ldap_bind_dn: String, ldap_bind_dn: String,
@ -74,9 +73,9 @@ impl Config {
self.bitwarden_admin_token.clone() self.bitwarden_admin_token.clone()
} }
pub fn get_bitwarden_root_cert(&self) -> String { pub fn get_bitwarden_root_cert_file(&self) -> String {
match &self.bitwarden_root_cert { match &self.bitwarden_root_cert_file {
Some(bitwarden_root_cert) => bitwarden_root_cert.clone(), Some(bitwarden_root_cert_file) => bitwarden_root_cert_file.clone(),
None => String::new(), None => String::new(),
} }
} }

View File

@ -5,7 +5,7 @@ use std::error::Error;
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use ldap3::{DerefAliases, LdapConn, Scope, SearchEntry, SearchOptions, LdapConnSettings}; use ldap3::{DerefAliases, LdapConn, LdapConnSettings, Scope, SearchEntry, SearchOptions};
mod bw_admin; mod bw_admin;
mod config; mod config;
@ -15,7 +15,7 @@ fn main() {
let mut client = bw_admin::Client::new( let mut client = bw_admin::Client::new(
config.get_bitwarden_url().clone(), config.get_bitwarden_url().clone(),
config.get_bitwarden_admin_token().clone(), config.get_bitwarden_admin_token().clone(),
config.get_bitwarden_root_cert().clone() config.get_bitwarden_root_cert_file().clone(),
); );
if let Err(e) = invite_users(&config, &mut client, config.get_ldap_sync_loop()) { if let Err(e) = invite_users(&config, &mut client, config.get_ldap_sync_loop()) {
@ -65,12 +65,9 @@ fn ldap_client(
ldap_url: String, ldap_url: String,
bind_dn: String, bind_dn: String,
bind_pw: String, bind_pw: String,
no_tls_verify: bool no_tls_verify: bool,
) -> Result<LdapConn, Box<dyn Error>> { ) -> Result<LdapConn, Box<dyn Error>> {
let settings = LdapConnSettings::new().set_no_tls_verify(no_tls_verify);
let settings = LdapConnSettings::new()
.set_no_tls_verify(no_tls_verify);
let ldap = LdapConn::with_settings(settings, ldap_url.as_str())?; let ldap = LdapConn::with_settings(settings, ldap_url.as_str())?;
match ldap.simple_bind(bind_dn.as_str(), bind_pw.as_str()) { match ldap.simple_bind(bind_dn.as_str(), bind_pw.as_str()) {
_ => {} _ => {}
@ -85,7 +82,7 @@ fn search_entries(config: &config::Config) -> Result<Vec<SearchEntry>, Box<dyn E
config.get_ldap_url(), config.get_ldap_url(),
config.get_ldap_bind_dn(), config.get_ldap_bind_dn(),
config.get_ldap_bind_password(), config.get_ldap_bind_password(),
config.get_ldap_no_tls_verify() config.get_ldap_no_tls_verify(),
); );
if ldap.is_err() { if ldap.is_err() {