Files
BasicOIDC/src/data/app_config.rs
Pierre Hubert e8aeb37f31
Some checks failed
continuous-integration/drone/push Build is failing
ldap configuration
2022-12-03 18:20:27 +01:00

171 lines
4.8 KiB
Rust

use std::path::{Path, PathBuf};
use clap::{Parser, ValueEnum};
use crate::constants::{APP_NAME, CLIENTS_LIST_FILE, USERS_LIST_FILE};
#[derive(ValueEnum, Default, Debug, Clone, Eq, PartialEq)]
pub enum UsersBackend {
#[default]
File,
Ldap,
}
#[derive(Debug, Clone)]
pub struct LdapConfiguration {
server_uri: &'static str,
bind_dn: &'static str,
bind_password: &'static str,
start_tls: bool,
root_dn: &'static str,
attr_map: &'static str,
}
/// Basic OIDC provider
#[derive(Parser, Debug, Clone)]
#[clap(author, version, about, long_about = None)]
pub struct AppConfig {
/// Listen address
#[clap(short, long, env, default_value = "0.0.0.0:8000")]
pub listen_address: String,
/// Storage path
#[clap(short, long, env)]
pub storage_path: String,
/// App token token
#[clap(short, long, env, default_value = "")]
pub token_key: String,
/// Website origin
#[clap(short, long, env, default_value = "http://localhost:8000")]
pub website_origin: String,
/// Proxy IP, might end with a star "*"
#[clap(short, long, env)]
pub proxy_ip: Option<String>,
/// IP location service API
///
/// Up instance of IP location service : <https://gitlab.com/pierre42100/iplocationserver>
///
/// Example: "<https://api.geoip.rs>"
#[clap(long, short, env)]
pub ip_location_service: Option<String>,
/// Users source backend
#[clap(value_enum, long, short, default_value = "file")]
pub backend: UsersBackend,
/// LDAP server URI
#[clap(
long,
env,
group = "ldap-server-uri",
requires = "ldap-dn",
requires = "ldap-password"
)]
pub ldap_server_uri: Option<String>,
/// LDAP user DN to bind as to perform searches
#[clap(long, env, group = "ldap-dn", requires = "ldap-server-uri")]
pub ldap_dn: Option<String>,
/// LDAP user DN to bind as to perform searches
#[clap(long, env, group = "ldap-password", requires = "ldap-server-uri")]
pub ldap_password: Option<String>,
// /// The LDAP user filter, using `{0}` as the username placeholder, e.g. `(|(cn={0})(mail={0}))`;
// /// uses standard LDAP search syntax. Default: `(uid={0})`.
// #[clap(long, env, default_value = "uid={0}")]
// pub ldap_search_filter: String,
/// Set this argument to enable LDAP StartTLS support. (disabled by default)
#[clap(long, env, default_value_t = false)]
pub ldap_start_tls: bool,
/// The LDAP search root DN, e.g. `dc=my,dc=domain,dc=com;` supports multiple entries in a
/// space-delimited list, e.g. `dc=users,dc=domain,dc=com dc=admins,dc=domain,dc=com.`
#[clap(long, env, requires = "ldap-server-uri")]
pub ldap_root_dn: Option<String>,
/// A mapping of user attributes to LDAP values
#[clap(
long,
env,
default_value = "first_name:givenName,last_name:sn,username:uid,email:mail"
)]
pub ldap_attr_map: String,
}
lazy_static::lazy_static! {
static ref ARGS: AppConfig = {
let mut config = AppConfig::parse();
// In debug mode only, use dummy token
if cfg!(debug_assertions) && config.token_key.is_empty() {
config.token_key = String::from_utf8_lossy(&[32; 64]).to_string();
}
config
};
}
impl AppConfig {
/// Get parsed command line arguments
pub fn get() -> &'static AppConfig {
&ARGS
}
pub fn secure_cookie(&self) -> bool {
self.website_origin.starts_with("https:")
}
pub fn storage_path(&self) -> &Path {
self.storage_path.as_ref()
}
pub fn users_file(&self) -> PathBuf {
self.storage_path().join(USERS_LIST_FILE)
}
pub fn clients_file(&self) -> PathBuf {
self.storage_path().join(CLIENTS_LIST_FILE)
}
pub fn full_url(&self, uri: &str) -> String {
if uri.starts_with('/') {
format!("{}{}", self.website_origin, uri)
} else {
format!("{}/{}", self.website_origin, uri)
}
}
pub fn domain_name(&self) -> &str {
self.website_origin.split('/').nth(2).unwrap_or(APP_NAME)
}
/// Get LDAP configuration, if available
pub fn ldap_config(&'static self) -> LdapConfiguration {
assert_eq!(self.backend, UsersBackend::Ldap);
LdapConfiguration {
server_uri: self.ldap_server_uri.as_deref().unwrap(),
bind_dn: self.ldap_dn.as_deref().unwrap(),
bind_password: self.ldap_password.as_deref().unwrap(),
start_tls: self.ldap_start_tls,
root_dn: self.ldap_root_dn.as_deref().unwrap(),
attr_map: self.ldap_attr_map.as_str(),
}
}
}
#[cfg(test)]
mod test {
use crate::data::app_config::AppConfig;
#[test]
fn verify_cli() {
use clap::CommandFactory;
AppConfig::command().debug_assert()
}
}