committed by
nitnelave
parent
f0bbcfd2c8
commit
d0cdfa97c7
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -2466,6 +2466,7 @@ dependencies = [
|
||||
"tracing-forest",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"uuid 1.3.1",
|
||||
"webpki-roots",
|
||||
@@ -4509,6 +4510,7 @@ dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna 0.3.0",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4538,6 +4540,7 @@ version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"getrandom 0.2.8",
|
||||
"md-5",
|
||||
]
|
||||
|
||||
@@ -96,7 +96,7 @@ features = ["full"]
|
||||
version = "1.25"
|
||||
|
||||
[dependencies.uuid]
|
||||
features = ["v3"]
|
||||
features = ["v1", "v3"]
|
||||
version = "*"
|
||||
|
||||
[dependencies.tracing-forest]
|
||||
@@ -126,6 +126,10 @@ features = ["rustls-tls-webpki-roots"]
|
||||
version = "0.20"
|
||||
features = ["dangerous_configuration"]
|
||||
|
||||
[dependencies.url]
|
||||
version = "2"
|
||||
features = ["serde"]
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0"
|
||||
mockall = "0.11.4"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use clap::{builder::EnumValueParser, Parser};
|
||||
use lettre::message::Mailbox;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
/// lldap is a lightweight LDAP server
|
||||
#[derive(Debug, Parser, Clone)]
|
||||
@@ -82,7 +83,7 @@ pub struct RunOpts {
|
||||
|
||||
/// URL of the server, for password reset links.
|
||||
#[clap(long, env = "LLDAP_HTTP_URL")]
|
||||
pub http_url: Option<String>,
|
||||
pub http_url: Option<Url>,
|
||||
|
||||
/// Database connection URL
|
||||
#[clap(short, long, env = "LLDAP_DATABASE_URL")]
|
||||
|
||||
@@ -11,6 +11,7 @@ use lettre::message::Mailbox;
|
||||
use lldap_auth::opaque::{server::ServerSetup, KeyPair};
|
||||
use secstr::SecUtf8;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, derive_builder::Builder)]
|
||||
#[builder(pattern = "owned")]
|
||||
@@ -100,8 +101,8 @@ pub struct Configuration {
|
||||
pub smtp_options: MailOptions,
|
||||
#[builder(default)]
|
||||
pub ldaps_options: LdapsOptions,
|
||||
#[builder(default = r#"String::from("http://localhost")"#)]
|
||||
pub http_url: String,
|
||||
#[builder(default = r#"Url::parse("http://localhost").unwrap()"#)]
|
||||
pub http_url: Url,
|
||||
#[serde(skip)]
|
||||
#[builder(field(private), default = "None")]
|
||||
server_setup: Option<ServerSetup>,
|
||||
@@ -237,7 +238,7 @@ impl ConfigOverrider for RunOpts {
|
||||
}
|
||||
|
||||
if let Some(url) = self.http_url.as_ref() {
|
||||
config.http_url = url.to_string();
|
||||
config.http_url = url.clone();
|
||||
}
|
||||
|
||||
if let Some(database_url) = self.database_url.as_ref() {
|
||||
|
||||
@@ -6,7 +6,13 @@ use lettre::{
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
async fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOptions) -> Result<()> {
|
||||
async fn send_email(
|
||||
to: Mailbox,
|
||||
subject: &str,
|
||||
body: String,
|
||||
options: &MailOptions,
|
||||
server_url: &url::Url,
|
||||
) -> Result<()> {
|
||||
let from = options
|
||||
.from
|
||||
.clone()
|
||||
@@ -17,6 +23,14 @@ async fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOpti
|
||||
&to, &from, &options.user, &options.server, options.port
|
||||
);
|
||||
let email = Message::builder()
|
||||
.message_id(Some(format!(
|
||||
"<{}@{}>",
|
||||
uuid::Uuid::new_v1(
|
||||
uuid::Timestamp::now(uuid::NoContext),
|
||||
"lldap!".as_bytes().try_into().unwrap()
|
||||
),
|
||||
server_url.domain().unwrap_or_default()
|
||||
)))
|
||||
.from(from)
|
||||
.reply_to(reply_to)
|
||||
.to(to)
|
||||
@@ -58,24 +72,34 @@ pub async fn send_password_reset_email(
|
||||
username: &str,
|
||||
to: &str,
|
||||
token: &str,
|
||||
domain: &str,
|
||||
server_url: &url::Url,
|
||||
options: &MailOptions,
|
||||
) -> Result<()> {
|
||||
let to = to.parse()?;
|
||||
let mut reset_url = server_url.clone();
|
||||
reset_url
|
||||
.path_segments_mut()
|
||||
.unwrap()
|
||||
.extend(["reset-password", "step2", token]);
|
||||
let body = format!(
|
||||
"Hello {},
|
||||
This email has been sent to you in order to validate your identity.
|
||||
If you did not initiate the process your credentials might have been
|
||||
compromised. You should reset your password and contact an administrator.
|
||||
|
||||
To reset your password please visit the following URL: {}/reset-password/step2/{}
|
||||
To reset your password please visit the following URL: {}
|
||||
|
||||
Please contact an administrator if you did not initiate the process.",
|
||||
username,
|
||||
domain.trim_end_matches('/'),
|
||||
token
|
||||
username, reset_url
|
||||
);
|
||||
send_email(to, "[LLDAP] Password reset requested", body, options).await
|
||||
send_email(
|
||||
to,
|
||||
"[LLDAP] Password reset requested",
|
||||
body,
|
||||
options,
|
||||
server_url,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
|
||||
@@ -84,6 +108,7 @@ pub async fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
|
||||
"LLDAP test email",
|
||||
"The test is successful! You can send emails from LLDAP".to_string(),
|
||||
options,
|
||||
&url::Url::parse("http://localhost").unwrap(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ fn http_config<Backend>(
|
||||
backend_handler: Backend,
|
||||
jwt_secret: secstr::SecUtf8,
|
||||
jwt_blacklist: HashSet<u64>,
|
||||
server_url: String,
|
||||
server_url: url::Url,
|
||||
mail_options: MailOptions,
|
||||
) where
|
||||
Backend: TcpBackendHandler + BackendHandler + LoginHandler + OpaqueHandler + Clone + 'static,
|
||||
@@ -132,7 +132,7 @@ pub(crate) struct AppState<Backend> {
|
||||
pub backend_handler: AccessControlledBackendHandler<Backend>,
|
||||
pub jwt_key: Hmac<Sha512>,
|
||||
pub jwt_blacklist: RwLock<HashSet<u64>>,
|
||||
pub server_url: String,
|
||||
pub server_url: url::Url,
|
||||
pub mail_options: MailOptions,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user