mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	server: Send an email for password resets
This commit is contained in:
		
							parent
							
								
									fe8bbd6bf2
								
							
						
					
					
						commit
						ea8bc89483
					
				@ -23,6 +23,7 @@ use futures_util::{FutureExt, TryFutureExt};
 | 
			
		||||
use hmac::Hmac;
 | 
			
		||||
use jwt::{SignWithKey, VerifyWithKey};
 | 
			
		||||
use lldap_auth::{login, registration, JWTClaims};
 | 
			
		||||
use log::*;
 | 
			
		||||
use sha2::Sha512;
 | 
			
		||||
use std::collections::{hash_map::DefaultHasher, HashSet};
 | 
			
		||||
use std::hash::{Hash, Hasher};
 | 
			
		||||
@ -123,12 +124,27 @@ where
 | 
			
		||||
        None => return HttpResponse::BadRequest().body("Missing user ID"),
 | 
			
		||||
        Some(id) => id,
 | 
			
		||||
    };
 | 
			
		||||
    let _token = match data.backend_handler.start_password_reset(user_id).await {
 | 
			
		||||
    let token = match data.backend_handler.start_password_reset(user_id).await {
 | 
			
		||||
        Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
 | 
			
		||||
        Ok(None) => return HttpResponse::Ok().finish(),
 | 
			
		||||
        Ok(Some(token)) => token,
 | 
			
		||||
    };
 | 
			
		||||
    // TODO: Send email.
 | 
			
		||||
    let user = match data.backend_handler.get_user_details(user_id).await {
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            warn!("Error getting used details: {:#?}", e);
 | 
			
		||||
            return HttpResponse::Ok().finish();
 | 
			
		||||
        }
 | 
			
		||||
        Ok(u) => u,
 | 
			
		||||
    };
 | 
			
		||||
    if let Err(e) = super::mail::send_password_reset_email(
 | 
			
		||||
        &user.display_name,
 | 
			
		||||
        &user.email,
 | 
			
		||||
        &token,
 | 
			
		||||
        &data.server_url,
 | 
			
		||||
        &data.mail_options,
 | 
			
		||||
    ) {
 | 
			
		||||
        warn!("Error sending email: {:#?}", e);
 | 
			
		||||
    }
 | 
			
		||||
    HttpResponse::Ok().finish()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ use lettre::{
 | 
			
		||||
};
 | 
			
		||||
use log::debug;
 | 
			
		||||
 | 
			
		||||
pub fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
 | 
			
		||||
fn send_email(to: Mailbox, subject: &str, body: String, options: &MailOptions) -> Result<()> {
 | 
			
		||||
    let from = options
 | 
			
		||||
        .from
 | 
			
		||||
        .clone()
 | 
			
		||||
@ -20,8 +20,8 @@ pub fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
 | 
			
		||||
        .from(from)
 | 
			
		||||
        .reply_to(reply_to)
 | 
			
		||||
        .to(to)
 | 
			
		||||
        .subject("LLDAP test email")
 | 
			
		||||
        .body("The test is successful! You can send emails from LLDAP".to_string())?;
 | 
			
		||||
        .subject(subject)
 | 
			
		||||
        .body(body)?;
 | 
			
		||||
    let creds = Credentials::new(
 | 
			
		||||
        options.user.clone(),
 | 
			
		||||
        options.password.unsecure().to_string(),
 | 
			
		||||
@ -32,3 +32,34 @@ pub fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
 | 
			
		||||
    mailer.send(&email)?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn send_password_reset_email(
 | 
			
		||||
    username: &str,
 | 
			
		||||
    to: &str,
 | 
			
		||||
    token: &str,
 | 
			
		||||
    domain: &str,
 | 
			
		||||
    options: &MailOptions,
 | 
			
		||||
) -> Result<()> {
 | 
			
		||||
    let to = to.parse()?;
 | 
			
		||||
    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/{}
 | 
			
		||||
 | 
			
		||||
Please contact an administrator if you did not initiate the process.",
 | 
			
		||||
        username, domain, token
 | 
			
		||||
    );
 | 
			
		||||
    send_email(to, "[LLDAP] Password reset requested", body, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn send_test_email(to: Mailbox, options: &MailOptions) -> Result<()> {
 | 
			
		||||
    send_email(
 | 
			
		||||
        to,
 | 
			
		||||
        "LLDAP test email",
 | 
			
		||||
        "The test is successful! You can send emails from LLDAP".to_string(),
 | 
			
		||||
        options,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,11 @@ use crate::{
 | 
			
		||||
        handler::{BackendHandler, LoginHandler},
 | 
			
		||||
        opaque_handler::OpaqueHandler,
 | 
			
		||||
    },
 | 
			
		||||
    infra::{auth_service, configuration::Configuration, tcp_backend_handler::*},
 | 
			
		||||
    infra::{
 | 
			
		||||
        auth_service,
 | 
			
		||||
        configuration::{Configuration, MailOptions},
 | 
			
		||||
        tcp_backend_handler::*,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
use actix_files::{Files, NamedFile};
 | 
			
		||||
use actix_http::HttpServiceBuilder;
 | 
			
		||||
@ -46,6 +50,8 @@ fn http_config<Backend>(
 | 
			
		||||
    backend_handler: Backend,
 | 
			
		||||
    jwt_secret: secstr::SecUtf8,
 | 
			
		||||
    jwt_blacklist: HashSet<u64>,
 | 
			
		||||
    server_url: String,
 | 
			
		||||
    mail_options: MailOptions,
 | 
			
		||||
) where
 | 
			
		||||
    Backend: TcpBackendHandler + BackendHandler + LoginHandler + OpaqueHandler + Sync + 'static,
 | 
			
		||||
{
 | 
			
		||||
@ -53,6 +59,8 @@ fn http_config<Backend>(
 | 
			
		||||
        backend_handler,
 | 
			
		||||
        jwt_key: Hmac::new_varkey(jwt_secret.unsecure().as_bytes()).unwrap(),
 | 
			
		||||
        jwt_blacklist: RwLock::new(jwt_blacklist),
 | 
			
		||||
        server_url,
 | 
			
		||||
        mail_options,
 | 
			
		||||
    }))
 | 
			
		||||
    // Serve index.html and main.js, and default to index.html.
 | 
			
		||||
    .route(
 | 
			
		||||
@ -76,6 +84,8 @@ pub(crate) struct AppState<Backend> {
 | 
			
		||||
    pub backend_handler: Backend,
 | 
			
		||||
    pub jwt_key: Hmac<Sha512>,
 | 
			
		||||
    pub jwt_blacklist: RwLock<HashSet<u64>>,
 | 
			
		||||
    pub server_url: String,
 | 
			
		||||
    pub mail_options: MailOptions,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn build_tcp_server<Backend>(
 | 
			
		||||
@ -91,15 +101,26 @@ where
 | 
			
		||||
        .get_jwt_blacklist()
 | 
			
		||||
        .await
 | 
			
		||||
        .context("while getting the jwt blacklist")?;
 | 
			
		||||
    let server_url = config.http_url.clone();
 | 
			
		||||
    let mail_options = config.smtp_options.clone();
 | 
			
		||||
    server_builder
 | 
			
		||||
        .bind("http", ("0.0.0.0", config.http_port), move || {
 | 
			
		||||
            let backend_handler = backend_handler.clone();
 | 
			
		||||
            let jwt_secret = jwt_secret.clone();
 | 
			
		||||
            let jwt_blacklist = jwt_blacklist.clone();
 | 
			
		||||
            let server_url = server_url.clone();
 | 
			
		||||
            let mail_options = mail_options.clone();
 | 
			
		||||
            HttpServiceBuilder::new()
 | 
			
		||||
                .finish(map_config(
 | 
			
		||||
                    App::new().configure(move |cfg| {
 | 
			
		||||
                        http_config(cfg, backend_handler, jwt_secret, jwt_blacklist)
 | 
			
		||||
                        http_config(
 | 
			
		||||
                            cfg,
 | 
			
		||||
                            backend_handler,
 | 
			
		||||
                            jwt_secret,
 | 
			
		||||
                            jwt_blacklist,
 | 
			
		||||
                            server_url,
 | 
			
		||||
                            mail_options,
 | 
			
		||||
                        )
 | 
			
		||||
                    }),
 | 
			
		||||
                    |_| AppConfig::default(),
 | 
			
		||||
                ))
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user