2021-06-14 14:02:36 +00:00
|
|
|
use anyhow::{anyhow, Result};
|
2021-03-02 19:30:43 +00:00
|
|
|
use figment::{
|
|
|
|
providers::{Env, Format, Serialized, Toml},
|
|
|
|
Figment,
|
|
|
|
};
|
2021-06-14 14:02:36 +00:00
|
|
|
use lldap_model::{opaque, opaque::KeyPair};
|
2021-03-02 19:30:43 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2021-03-02 19:13:58 +00:00
|
|
|
|
2021-03-02 19:51:33 +00:00
|
|
|
use crate::infra::cli::CLIOpts;
|
|
|
|
|
2021-06-14 14:02:36 +00:00
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize, derive_builder::Builder)]
|
|
|
|
#[builder(
|
|
|
|
pattern = "owned",
|
|
|
|
default = "Configuration::default()",
|
|
|
|
build_fn(name = "private_build", validate = "Self::validate")
|
|
|
|
)]
|
2021-03-02 19:30:43 +00:00
|
|
|
pub struct Configuration {
|
2021-03-02 22:07:01 +00:00
|
|
|
pub ldap_port: u16,
|
|
|
|
pub ldaps_port: u16,
|
2021-03-07 11:36:12 +00:00
|
|
|
pub http_port: u16,
|
2021-05-12 18:42:15 +00:00
|
|
|
pub jwt_secret: String,
|
2021-03-16 17:27:31 +00:00
|
|
|
pub ldap_base_dn: String,
|
2021-03-12 08:33:43 +00:00
|
|
|
pub ldap_user_dn: String,
|
|
|
|
pub ldap_user_pass: String,
|
|
|
|
pub database_url: String,
|
2021-03-02 22:07:01 +00:00
|
|
|
pub verbose: bool,
|
2021-06-14 14:02:36 +00:00
|
|
|
pub key_file: String,
|
|
|
|
#[serde(skip)]
|
|
|
|
#[builder(field(private), setter(strip_option))]
|
|
|
|
server_keys: Option<KeyPair>,
|
2021-03-02 19:30:43 +00:00
|
|
|
}
|
|
|
|
|
2021-06-14 14:02:36 +00:00
|
|
|
impl ConfigurationBuilder {
|
|
|
|
#[cfg(test)]
|
|
|
|
pub fn build(self) -> Result<Configuration> {
|
2021-06-23 08:57:34 +00:00
|
|
|
let server_keys = get_server_keys(self.key_file.as_deref().unwrap_or("server_key"))?;
|
2021-06-14 14:02:36 +00:00
|
|
|
Ok(self.server_keys(server_keys).private_build()?)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn validate(&self) -> Result<(), String> {
|
|
|
|
if self.server_keys.is_none() {
|
|
|
|
Err("Don't use `private_build`, use `build` instead".to_string())
|
|
|
|
} else {
|
|
|
|
Ok(())
|
2021-03-02 19:30:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-02 20:43:26 +00:00
|
|
|
impl Configuration {
|
2021-06-14 14:02:36 +00:00
|
|
|
pub fn get_server_keys(&self) -> &KeyPair {
|
|
|
|
self.server_keys.as_ref().unwrap()
|
|
|
|
}
|
|
|
|
|
2021-03-02 22:07:01 +00:00
|
|
|
fn merge_with_cli(mut self: Configuration, cli_opts: CLIOpts) -> Configuration {
|
2021-03-02 21:03:58 +00:00
|
|
|
if cli_opts.verbose {
|
2021-03-02 22:07:01 +00:00
|
|
|
self.verbose = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(port) = cli_opts.ldap_port {
|
|
|
|
self.ldap_port = port;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(port) = cli_opts.ldaps_port {
|
|
|
|
self.ldaps_port = port;
|
2021-03-02 21:03:58 +00:00
|
|
|
}
|
2021-03-02 20:43:26 +00:00
|
|
|
|
2021-03-02 22:07:01 +00:00
|
|
|
self
|
2021-03-02 20:43:26 +00:00
|
|
|
}
|
2021-06-14 14:02:36 +00:00
|
|
|
|
|
|
|
pub(super) fn default() -> Self {
|
|
|
|
Configuration {
|
|
|
|
ldap_port: 3890,
|
|
|
|
ldaps_port: 6360,
|
|
|
|
http_port: 17170,
|
|
|
|
jwt_secret: String::from("secretjwtsecret"),
|
|
|
|
ldap_base_dn: String::from("dc=example,dc=com"),
|
|
|
|
// cn=admin,dc=example,dc=com
|
|
|
|
ldap_user_dn: String::from("admin"),
|
|
|
|
ldap_user_pass: String::from("password"),
|
|
|
|
database_url: String::from("sqlite://users.db?mode=rwc"),
|
|
|
|
verbose: false,
|
|
|
|
key_file: String::from("server_key"),
|
|
|
|
server_keys: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_server_keys(file_path: &str) -> Result<KeyPair> {
|
|
|
|
use opaque_ke::ciphersuite::CipherSuite;
|
|
|
|
use std::path::Path;
|
|
|
|
let path = Path::new(file_path);
|
|
|
|
if path.exists() {
|
|
|
|
let bytes = std::fs::read(file_path)
|
|
|
|
.map_err(|e| anyhow!("Could not read key file `{}`: {}", file_path, e))?;
|
|
|
|
Ok(KeyPair::from_private_key_slice(&bytes)?)
|
|
|
|
} else {
|
|
|
|
let mut rng = rand::rngs::OsRng;
|
|
|
|
let keypair = opaque::DefaultSuite::generate_random_keypair(&mut rng);
|
|
|
|
std::fs::write(path, keypair.private().as_slice()).map_err(|e| {
|
|
|
|
anyhow!(
|
|
|
|
"Could not write the generated server keys to file `{}`: {}",
|
|
|
|
file_path,
|
|
|
|
e
|
|
|
|
)
|
|
|
|
})?;
|
2021-06-15 21:07:22 +00:00
|
|
|
Ok(keypair)
|
2021-06-14 14:02:36 +00:00
|
|
|
}
|
2021-03-02 20:43:26 +00:00
|
|
|
}
|
|
|
|
|
2021-03-02 19:51:33 +00:00
|
|
|
pub fn init(cli_opts: CLIOpts) -> Result<Configuration> {
|
2021-03-02 20:43:26 +00:00
|
|
|
let config_file = cli_opts.config_file.clone();
|
|
|
|
|
|
|
|
let config: Configuration = Figment::from(Serialized::defaults(Configuration::default()))
|
|
|
|
.merge(Toml::file(config_file))
|
|
|
|
.merge(Env::prefixed("LLDAP_"))
|
|
|
|
.extract()?;
|
2021-03-02 19:30:43 +00:00
|
|
|
|
2021-06-14 14:02:36 +00:00
|
|
|
let mut config = config.merge_with_cli(cli_opts);
|
|
|
|
config.server_keys = Some(get_server_keys(&config.key_file)?);
|
2021-03-02 19:30:43 +00:00
|
|
|
Ok(config)
|
2021-03-02 19:13:58 +00:00
|
|
|
}
|