peach-workspace/peach-web/src/routes/authentication/login.rs

88 lines
3.5 KiB
Rust

use log::debug;
use maud::{html, PreEscaped};
use peach_lib::password_utils;
use rouille::{post_input, try_or_400, Request, Response};
use crate::{
templates,
utils::{
flash::{FlashRequest, FlashResponse},
theme,
},
SessionData,
};
// HELPER AND ROUTES FOR /auth/login (GET and POST)
/// Login form template builder.
pub fn build_template(request: &Request) -> PreEscaped<String> {
// check for flash cookies; will be (None, None) if no flash cookies are found
let (flash_name, flash_msg) = request.retrieve_flash();
let form_template = html! {
(PreEscaped("<!-- LOGIN FORM -->"))
div class="card center" {
form id="login_form" class="center" action="/auth/login" method="post" {
div style="display: flex; flex-direction: column; margin-bottom: 1rem;" {
(PreEscaped("<!-- input for password -->"))
label for="password" class="center label-small font-gray" style="width: 80%;" { "PASSWORD" }
input id="password" name="password" class="center input" type="password" title="Password for given username";
(PreEscaped("<!-- login (form submission) button -->"))
input id="loginUser" class="button button-primary center" title="Login" type="submit" value="Login";
div class="center-text" style="margin-top: 1rem;" {
a href="/auth/forgot" class="label-small link font-gray" { "Forgot Password?" }
}
}
}
// render flash message if cookies were found in the request
@if let (Some(name), Some(msg)) = (flash_name, flash_msg) {
(PreEscaped("<!-- FLASH MESSAGE -->"))
(templates::flash::build_template(name, msg))
}
}
};
// wrap the nav bars around the settings menu template content
// parameters are template, title and back url
let body = templates::nav::build_template(form_template, "Login", Some("/"));
// query the current theme so we can pass it into the base template builder
let theme = theme::get_theme();
// render the base template with the provided body
templates::base::build_template(body, theme)
}
/// Parse and verify the submitted password. If verification succeeds, set the
/// auth session cookie and redirect to the home page. If not, set a flash
/// message and redirect to the login page.
pub fn handle_form(request: &Request, session_data: &mut Option<SessionData>) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, { password: String }));
match password_utils::verify_password(&data.password) {
Ok(_) => {
debug!("Successful login attempt");
// if password verification is successful, write to `session_data`
// to authenticate the user
*session_data = Some(SessionData {
_login: "success".to_string(),
});
Response::redirect_303("/")
}
Err(err) => {
debug!("Unsuccessful login attempt");
let err_msg = format!("Invalid password: {}", err);
let (flash_name, flash_msg) = (
"flash_name=error".to_string(),
format!("flash_msg={}", err_msg),
);
// if unsuccessful login, render /login page again
Response::redirect_303("/auth/login").add_flash(flash_name, flash_msg)
}
}
}