From d9a7cf36226204b9592ad37e7cb6a92f83b0d00d Mon Sep 17 00:00:00 2001 From: glyph Date: Mon, 15 Nov 2021 20:56:22 +0200 Subject: [PATCH] update auth and admin routes --- peach-web/src/routes/authentication.rs | 76 +++++++++++--------------- peach-web/src/routes/settings/admin.rs | 47 ++++++++++++++-- peach-web/src/routes/settings/mod.rs | 1 + 3 files changed, 76 insertions(+), 48 deletions(-) diff --git a/peach-web/src/routes/authentication.rs b/peach-web/src/routes/authentication.rs index 7c71799f..1d1a9b61 100644 --- a/peach-web/src/routes/authentication.rs +++ b/peach-web/src/routes/authentication.rs @@ -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) -> 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="")] +#[post("/login", data = "")] pub fn login_post(login_form: Form, 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, cookies: &CookieJar<'_>) -> Templ } } - // HELPERS AND ROUTES FOR /logout #[get("/logout")] @@ -149,7 +140,6 @@ pub fn logout(cookies: &CookieJar<'_>) -> Flash { 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) -> 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) -> 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) -> 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 = "")] -pub fn reset_password_form_endpoint( - reset_password_form: Json, -) -> Value { +#[post("/reset_password", data = "")] +pub fn reset_password_form_endpoint(reset_password_form: Json) -> 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) -> 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, _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, _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 = "")] +#[post("/change_password", data = "")] pub fn change_password_post(password_form: Form, _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 = "")] -pub fn save_password_form_endpoint(password_form: Json, _auth: Authenticated) -> Value { +#[post("/change_password", data = "")] +pub fn save_password_form_endpoint( + password_form: Json, + _auth: Authenticated, +) -> Value { let result = save_password_form(password_form.into_inner()); match result { Ok(_) => { diff --git a/peach-web/src/routes/settings/admin.rs b/peach-web/src/routes/settings/admin.rs index 0171f078..118fa0a1 100644 --- a/peach-web/src/routes/settings/admin.rs +++ b/peach-web/src/routes/settings/admin.rs @@ -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, + pub title: Option, + pub flash_name: Option, + pub flash_msg: Option, +} + +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, _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, _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, _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 { diff --git a/peach-web/src/routes/settings/mod.rs b/peach-web/src/routes/settings/mod.rs index 530c15b5..1096c8d4 100644 --- a/peach-web/src/routes/settings/mod.rs +++ b/peach-web/src/routes/settings/mod.rs @@ -2,3 +2,4 @@ pub mod admin; pub mod dns; pub mod menu; pub mod network; +pub mod scuttlebutt;