mirror of https://github.com/lldap/lldap.git
server: Treat the database password as a secret
This commit is contained in:
parent
addd453287
commit
b82a2d5705
|
@ -3,6 +3,8 @@ use lettre::message::Mailbox;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::infra::database_string::DatabaseUrl;
|
||||
|
||||
/// lldap is a lightweight LDAP server
|
||||
#[derive(Debug, Parser, Clone)]
|
||||
#[clap(version, author)]
|
||||
|
@ -87,7 +89,7 @@ pub struct RunOpts {
|
|||
|
||||
/// Database connection URL
|
||||
#[clap(short, long, env = "LLDAP_DATABASE_URL")]
|
||||
pub database_url: Option<String>,
|
||||
pub database_url: Option<DatabaseUrl>,
|
||||
|
||||
/// Force admin password reset to the config value.
|
||||
#[clap(long, env = "LLDAP_FORCE_LADP_USER_PASS_RESET")]
|
||||
|
|
|
@ -3,7 +3,10 @@ use crate::{
|
|||
sql_tables::{ConfigLocation, PrivateKeyHash, PrivateKeyInfo, PrivateKeyLocation},
|
||||
types::{AttributeName, UserId},
|
||||
},
|
||||
infra::cli::{GeneralConfigOpts, LdapsOpts, RunOpts, SmtpEncryption, SmtpOpts, TestEmailOpts},
|
||||
infra::{
|
||||
cli::{GeneralConfigOpts, LdapsOpts, RunOpts, SmtpEncryption, SmtpOpts, TestEmailOpts},
|
||||
database_string::DatabaseUrl,
|
||||
},
|
||||
};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use figment::{
|
||||
|
@ -91,8 +94,8 @@ pub struct Configuration {
|
|||
pub force_ldap_user_pass_reset: bool,
|
||||
#[builder(default = "false")]
|
||||
pub force_update_private_key: bool,
|
||||
#[builder(default = r#"String::from("sqlite://users.db?mode=rwc")"#)]
|
||||
pub database_url: String,
|
||||
#[builder(default = r#"DatabaseUrl::from("sqlite://users.db?mode=rwc")"#)]
|
||||
pub database_url: DatabaseUrl,
|
||||
#[builder(default)]
|
||||
pub ignored_user_attributes: Vec<AttributeName>,
|
||||
#[builder(default)]
|
||||
|
@ -411,7 +414,7 @@ impl ConfigOverrider for RunOpts {
|
|||
}
|
||||
|
||||
if let Some(database_url) = self.database_url.as_ref() {
|
||||
config.database_url = database_url.to_string();
|
||||
config.database_url = database_url.clone();
|
||||
}
|
||||
|
||||
if let Some(force_ldap_user_pass_reset) = self.force_ldap_user_pass_reset {
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct DatabaseUrl(Url);
|
||||
|
||||
impl From<Url> for DatabaseUrl {
|
||||
fn from(url: Url) -> Self {
|
||||
Self(url)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for DatabaseUrl {
|
||||
fn from(url: &str) -> Self {
|
||||
Self(Url::parse(url).expect("Invalid database URL"))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for DatabaseUrl {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.0.password().is_some() {
|
||||
let mut url = self.0.clone();
|
||||
// It can fail for URLs that cannot have a password, like "mailto:bob@example".
|
||||
let _ = url.set_password(Some("***PASSWORD***"));
|
||||
f.write_fmt(format_args!("{}", url))
|
||||
} else {
|
||||
f.write_fmt(format_args!("{}", self.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for DatabaseUrl {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_database_url_debug() {
|
||||
let url = DatabaseUrl::from("postgres://user:pass@localhost:5432/dbname");
|
||||
assert_eq!(
|
||||
format!("{:?}", url),
|
||||
"postgres://user:***PASSWORD***@localhost:5432/dbname"
|
||||
);
|
||||
assert_eq!(
|
||||
url.to_string(),
|
||||
"postgres://user:pass@localhost:5432/dbname"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ pub mod access_control;
|
|||
pub mod auth_service;
|
||||
pub mod cli;
|
||||
pub mod configuration;
|
||||
pub mod database_string;
|
||||
pub mod db_cleaner;
|
||||
pub mod graphql;
|
||||
pub mod healthcheck;
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::{
|
|||
infra::{
|
||||
cli::*,
|
||||
configuration::{compare_private_key_hashes, Configuration},
|
||||
database_string::DatabaseUrl,
|
||||
db_cleaner::Scheduler,
|
||||
healthcheck, mail,
|
||||
},
|
||||
|
@ -84,7 +85,7 @@ async fn set_up_server(config: Configuration) -> Result<ServerBuilder> {
|
|||
info!("Starting LLDAP version {}", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
let sql_pool = {
|
||||
let mut sql_opt = sea_orm::ConnectOptions::new(config.database_url.clone());
|
||||
let mut sql_opt = sea_orm::ConnectOptions::new(config.database_url.to_string());
|
||||
sql_opt
|
||||
.max_connections(5)
|
||||
.sqlx_logging(true)
|
||||
|
@ -248,9 +249,9 @@ fn run_healthcheck(opts: RunOpts) -> Result<()> {
|
|||
std::process::exit(i32::from(failure))
|
||||
}
|
||||
|
||||
async fn create_schema(database_url: String) -> Result<()> {
|
||||
async fn create_schema(database_url: DatabaseUrl) -> Result<()> {
|
||||
let sql_pool = {
|
||||
let mut sql_opt = sea_orm::ConnectOptions::new(database_url.clone());
|
||||
let mut sql_opt = sea_orm::ConnectOptions::new(database_url.to_string());
|
||||
sql_opt
|
||||
.max_connections(1)
|
||||
.sqlx_logging(true)
|
||||
|
|
Loading…
Reference in New Issue