From e8aeb37f314a202de6fc63dc5d23c2ded7b58c7a Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Sat, 3 Dec 2022 18:20:27 +0100 Subject: [PATCH] ldap configuration --- src/data/app_config.rs | 81 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/src/data/app_config.rs b/src/data/app_config.rs index f5298b5..da0fa23 100644 --- a/src/data/app_config.rs +++ b/src/data/app_config.rs @@ -1,9 +1,26 @@ use std::path::{Path, PathBuf}; -use clap::Parser; +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)] @@ -30,11 +47,54 @@ pub struct AppConfig { /// IP location service API /// - /// Up instance of IP location service : https://gitlab.com/pierre42100/iplocationserver + /// Up instance of IP location service : /// - /// Example: "https://api.geoip.rs" - #[arg(long, short, env)] + /// Example: "" + #[clap(long, short, env)] pub ip_location_service: Option, + + /// 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, + + /// LDAP user DN to bind as to perform searches + #[clap(long, env, group = "ldap-dn", requires = "ldap-server-uri")] + pub ldap_dn: Option, + + /// LDAP user DN to bind as to perform searches + #[clap(long, env, group = "ldap-password", requires = "ldap-server-uri")] + pub ldap_password: Option, + + // /// 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, + + /// 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! { @@ -83,6 +143,19 @@ impl AppConfig { 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)]