update auth and admin routes

This commit is contained in:
glyph 2021-11-15 20:56:22 +02:00
parent 61828082fd
commit d9a7cf3622
3 changed files with 76 additions and 48 deletions

View File

@ -1,23 +1,20 @@
use log::{info};
use rocket::request::{FlashMessage};
use log::info;
use rocket::form::{Form, FromForm};
use rocket::request::FlashMessage;
use rocket::response::{Flash, Redirect};
use rocket::{get, post};
use rocket::serde::json::Json;
use rocket_dyn_templates::Template;
use rocket::serde::{Deserialize, Serialize};
use rocket::{get, post};
use rocket_dyn_templates::Template;
use peach_lib::password_utils;
use peach_lib::error::PeachError;
use peach_lib::password_utils;
use crate::error::PeachWebError;
use crate::utils::{build_json_response, TemplateOrRedirect};
use rocket::serde::json::Value;
use rocket::http::{Cookie, CookieJar, Status};
use rocket::request::{self, FromRequest, Request};
use rocket::http::{Cookie, CookieJar, Status};
use rocket::serde::json::Value;
// HELPERS AND STRUCTS FOR AUTHENTICATION WITH COOKIES
@ -32,7 +29,7 @@ pub struct Authenticated;
#[derive(Debug)]
pub enum LoginError {
UserNotLoggedIn
UserNotLoggedIn,
}
/// Request guard which returns an empty Authenticated struct from the request
@ -49,14 +46,10 @@ impl<'r> FromRequest<'r> for Authenticated {
.cookies()
.get_private(AUTH_COOKIE_KEY)
.and_then(|cookie| cookie.value().parse().ok())
.map(|_value: String| { Authenticated { } });
.map(|_value: String| Authenticated {});
match authenticated {
Some(auth) => {
request::Outcome::Success(auth)
},
None => {
request::Outcome::Failure((Status::Forbidden, LoginError::UserNotLoggedIn))
}
Some(auth) => request::Outcome::Success(auth),
None => request::Outcome::Failure((Status::Forbidden, LoginError::UserNotLoggedIn)),
}
}
}
@ -96,7 +89,6 @@ pub fn login(flash: Option<FlashMessage>) -> Template {
Template::render("login", &context)
}
#[derive(Debug, Deserialize, FromForm)]
pub struct LoginForm {
pub username: String,
@ -112,7 +104,7 @@ pub fn verify_login_form(login_form: LoginForm) -> Result<(), PeachError> {
password_utils::verify_password(&login_form.password)
}
#[post("/login", data="<login_form>")]
#[post("/login", data = "<login_form>")]
pub fn login_post(login_form: Form<LoginForm>, cookies: &CookieJar<'_>) -> TemplateOrRedirect {
let result = verify_login_form(login_form.into_inner());
match result {
@ -138,7 +130,6 @@ pub fn login_post(login_form: Form<LoginForm>, cookies: &CookieJar<'_>) -> Templ
}
}
// HELPERS AND ROUTES FOR /logout
#[get("/logout")]
@ -149,7 +140,6 @@ pub fn logout(cookies: &CookieJar<'_>) -> Flash<Redirect> {
Flash::success(Redirect::to("/login"), "Logged out")
}
// HELPERS AND ROUTES FOR /reset_password
#[derive(Debug, Deserialize, FromForm)]
@ -228,7 +218,7 @@ pub fn reset_password(flash: Option<FlashMessage>) -> Template {
context.flash_name = Some(flash.kind().to_string());
context.flash_msg = Some(flash.message().to_string());
};
Template::render("password/reset_password", &context)
Template::render("settings/admin/reset_password", &context)
}
/// Password reset form request handler. This route is used by a user who is not logged in
@ -245,7 +235,7 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
context.flash_name = Some("success".to_string());
let flash_msg = "New password is now saved. Return home to login".to_string();
context.flash_msg = Some(flash_msg);
Template::render("password/reset_password", &context)
Template::render("settings/admin/reset_password", &context)
}
Err(err) => {
let mut context = ChangePasswordContext::build();
@ -254,18 +244,15 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
context.title = Some("Reset Password".to_string());
context.flash_name = Some("error".to_string());
context.flash_msg = Some(format!("Failed to reset password: {}", err));
Template::render("password/reset_password", &context)
Template::render("settings/admin/reset_password", &context)
}
}
}
/// JSON password reset form request handler. This route is used by a user who is not logged in
/// and is specifically for users who have forgotten their password.
/// All routes under /public/* are excluded from nginx basic auth via the nginx config.
#[post("/public/api/v1/reset_password", data = "<reset_password_form>")]
pub fn reset_password_form_endpoint(
reset_password_form: Json<ResetPasswordForm>,
) -> Value {
#[post("/reset_password", data = "<reset_password_form>")]
pub fn reset_password_form_endpoint(reset_password_form: Json<ResetPasswordForm>) -> Value {
let result = save_reset_password_form(reset_password_form.into_inner());
match result {
Ok(_) => {
@ -316,7 +303,7 @@ pub fn forgot_password_page(flash: Option<FlashMessage>) -> Template {
context.flash_name = Some(flash.kind().to_string());
context.flash_msg = Some(flash.message().to_string());
};
Template::render("password/forgot_password", &context)
Template::render("settings/admin/forgot_password", &context)
}
/// Send password reset request handler. This route is used by a user who is not logged in
@ -335,7 +322,7 @@ pub fn send_password_reset_post() -> Template {
let flash_msg =
"A password reset link has been sent to the admin of this device".to_string();
context.flash_msg = Some(flash_msg);
Template::render("password/forgot_password", &context)
Template::render("settings/admin/forgot_password", &context)
}
Err(err) => {
let mut context = ChangePasswordContext::build();
@ -343,7 +330,7 @@ pub fn send_password_reset_post() -> Template {
context.title = Some("Send Password Reset".to_string());
context.flash_name = Some("error".to_string());
context.flash_msg = Some(format!("Failed to send password reset link: {}", err));
Template::render("password/forgot_password", &context)
Template::render("settings/admin/forgot_password", &context)
}
}
}
@ -375,11 +362,11 @@ pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebErr
}
/// Change password request handler. This is used by a user who is already logged in.
#[get("/settings/change_password")]
#[get("/change_password")]
pub fn change_password(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".to_string());
context.back = Some("/settings/admin".to_string());
context.title = Some("Change Password".to_string());
// check to see if there is a flash message to display
if let Some(flash) = flash {
@ -387,39 +374,42 @@ pub fn change_password(flash: Option<FlashMessage>, _auth: Authenticated) -> Tem
context.flash_name = Some(flash.kind().to_string());
context.flash_msg = Some(flash.message().to_string());
};
Template::render("password/change_password", &context)
Template::render("settings/admin/change_password", &context)
}
/// Change password form request handler. This route is used by a user who is already logged in.
#[post("/settings/change_password", data = "<password_form>")]
#[post("/change_password", data = "<password_form>")]
pub fn change_password_post(password_form: Form<PasswordForm>, _auth: Authenticated) -> Template {
let result = save_password_form(password_form.into_inner());
match result {
Ok(_) => {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".to_string());
context.back = Some("/settings/admin".to_string());
context.title = Some("Change Password".to_string());
context.flash_name = Some("success".to_string());
context.flash_msg = Some("New password is now saved".to_string());
// template_dir is set in Rocket.toml
Template::render("password/change_password", &context)
Template::render("settings/admin/change_password", &context)
}
Err(err) => {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".to_string());
context.back = Some("/settings/admin".to_string());
context.title = Some("Configure DNS".to_string());
context.flash_name = Some("error".to_string());
context.flash_msg = Some(format!("Failed to save new password: {}", err));
Template::render("password/change_password", &context)
Template::render("settings/admin/change_password", &context)
}
}
}
/// JSON change password form request handler.
#[post("/api/v1/settings/change_password", data = "<password_form>")]
pub fn save_password_form_endpoint(password_form: Json<PasswordForm>, _auth: Authenticated) -> Value {
#[post("/change_password", data = "<password_form>")]
pub fn save_password_form_endpoint(
password_form: Json<PasswordForm>,
_auth: Authenticated,
) -> Value {
let result = save_password_form(password_form.into_inner());
match result {
Ok(_) => {

View File

@ -14,7 +14,44 @@ use peach_lib::config_manager::load_peach_config;
use crate::error::PeachWebError;
use crate::routes::authentication::Authenticated;
// HELPERS AND ROUTES FOR /settings/configure_admin
// HELPERS AND ROUTES FOR /settings/admin
#[derive(Debug, Serialize)]
pub struct AdminMenuContext {
pub back: Option<String>,
pub title: Option<String>,
pub flash_name: Option<String>,
pub flash_msg: Option<String>,
}
impl AdminMenuContext {
pub fn build() -> AdminMenuContext {
AdminMenuContext {
back: None,
title: None,
flash_name: None,
flash_msg: None,
}
}
}
/// Administrator settings menu.
#[get("/")]
pub fn admin_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
let mut context = AdminMenuContext::build();
// set back icon link to settings route
context.back = Some("/settings".to_string());
context.title = Some("Administrator Settings".to_string());
// check to see if there is a flash message to display
if let Some(flash) = flash {
// add flash message contents to the context object
context.flash_name = Some(flash.kind().to_string());
context.flash_msg = Some(flash.message().to_string());
};
Template::render("settings/admin/menu", &context)
}
// HELPERS AND ROUTES FOR /settings/admin/configure
#[derive(Debug, Serialize)]
pub struct ConfigureAdminContext {
@ -39,12 +76,12 @@ impl ConfigureAdminContext {
}
}
/// Administrator settings menu. View and delete currently configured admin.
#[get("/")]
/// View and delete currently configured admin.
#[get("/configure")]
pub fn configure_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
let mut context = ConfigureAdminContext::build();
// set back icon link to settings route
context.back = Some("/settings".to_string());
context.back = Some("/settings/admin".to_string());
context.title = Some("Configure Admin".to_string());
// check to see if there is a flash message to display
if let Some(flash) = flash {
@ -90,7 +127,7 @@ pub fn save_add_admin_form(admin_form: AddAdminForm) -> Result<(), PeachWebError
#[get("/add")]
pub fn add_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
let mut context = AddAdminContext::build();
context.back = Some("/settings/admin".to_string());
context.back = Some("/settings/admin/configure".to_string());
context.title = Some("Add Admin".to_string());
// check to see if there is a flash message to display
if let Some(flash) = flash {

View File

@ -2,3 +2,4 @@ pub mod admin;
pub mod dns;
pub mod menu;
pub mod network;
pub mod scuttlebutt;