This commit is contained in:
mhfowler 2021-10-28 14:33:27 +02:00
parent 727a06cbba
commit f07f8be52f
9 changed files with 116 additions and 218 deletions

View File

@ -1,45 +1,17 @@
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use rocket_contrib::json::{Json}; use rocket_contrib::json::{Json};
use log::{debug, info}; use log::{debug, info};
use rocket::request::{FlashMessage, Form}; use rocket::request::{FlashMessage, Form};
use rocket::response::{Flash, Redirect}; use rocket::response::{Flash, Redirect};
use rocket::{get, post}; use rocket::{get, post};
use rocket::request::FromForm; use rocket::request::FromForm;
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use peach_lib::password_utils;
use crate::utils::{build_json_response, JsonResponse}; use crate::utils::{build_json_response, JsonResponse};
use crate::error::PeachWebError; use crate::error::PeachWebError;
use peach_lib::password_utils;
#[derive(Debug, Deserialize, FromForm)]
pub struct PasswordForm {
pub old_password: String,
pub new_password1: String,
pub new_password2: String,
}
/// this function is for use by a user who is already logged in to change their password
pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebError> {
info!(
"change password!: {} {} {}",
password_form.old_password, password_form.new_password1, password_form.new_password2
);
password_utils::verify_password(&password_form.old_password)?;
// if the previous line did not throw an error, then the old password is correct
password_utils::validate_new_passwords(
&password_form.new_password1,
&password_form.new_password2,
)?;
// if the previous line did not throw an error, then the new password is valid
password_utils::set_new_password(&password_form.new_password1)?;
Ok(())
}
/// # helpers and routes for /login /// # helpers and routes for /login
///////////////////////////////// /////////////////////////////////
@ -77,6 +49,9 @@ pub fn login(flash: Option<FlashMessage>) -> Template {
Template::render("login", &context) Template::render("login", &context)
} }
/// # helpers and routes for /logout
/////////////////////////////////
#[post("/logout")] #[post("/logout")]
pub fn logout() -> Flash<Redirect> { pub fn logout() -> Flash<Redirect> {
// logout authenticated user // logout authenticated user
@ -93,7 +68,7 @@ pub fn logout() -> Flash<Redirect> {
Flash::success(Redirect::to("/"), "Logged out") Flash::success(Redirect::to("/"), "Logged out")
} }
/// # helpers and routes for password reset /// # helpers and routes for /reset_password
////////////////////////////////////////// //////////////////////////////////////////
#[derive(Debug, Deserialize, FromForm)] #[derive(Debug, Deserialize, FromForm)]
@ -226,6 +201,10 @@ pub fn reset_password_form_endpoint(
} }
/// # helpers and routes for /send_password_reset
////////////////////////////////////////////////
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct SendPasswordResetContext { pub struct SendPasswordResetContext {
pub back: Option<String>, pub back: Option<String>,
@ -245,7 +224,6 @@ impl SendPasswordResetContext {
} }
} }
/// this route is used by a user who is not logged in to send a new password reset link /// this route is used by a user who is not logged in to send a new password reset link
#[get("/send_password_reset")] #[get("/send_password_reset")]
pub fn send_password_reset_page(flash: Option<FlashMessage>) -> Template { pub fn send_password_reset_page(flash: Option<FlashMessage>) -> Template {
@ -289,6 +267,76 @@ pub fn send_password_reset_post() -> Template {
} }
} }
/// # helpers and routes for /settings/change_password
//////////////////////////////////////////
#[derive(Debug, Deserialize, FromForm)]
pub struct PasswordForm {
pub old_password: String,
pub new_password1: String,
pub new_password2: String,
}
/// this function is for use by a user who is already logged in to change their password
pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebError> {
info!(
"change password!: {} {} {}",
password_form.old_password, password_form.new_password1, password_form.new_password2
);
password_utils::verify_password(&password_form.old_password)?;
// if the previous line did not throw an error, then the old password is correct
password_utils::validate_new_passwords(
&password_form.new_password1,
&password_form.new_password2,
)?;
// if the previous line did not throw an error, then the new password is valid
password_utils::set_new_password(&password_form.new_password1)?;
Ok(())
}
/// this change password route is used by a user who is already logged in
#[get("/settings/change_password")]
pub fn change_password(flash: Option<FlashMessage>) -> Template {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".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 {
// add flash message contents to the context object
context.flash_name = Some(flash.name().to_string());
context.flash_msg = Some(flash.msg().to_string());
};
Template::render("password/change_password", &context)
}
/// this change password route is used by a user who is already logged in
#[post("/settings/change_password", data = "<password_form>")]
pub fn change_password_post(password_form: Form<PasswordForm>) -> 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.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)
}
Err(err) => {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".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)
}
}
}
#[post("/api/v1/settings/change_password", data = "<password_form>")] #[post("/api/v1/settings/change_password", data = "<password_form>")]
pub fn save_password_form_endpoint(password_form: Json<PasswordForm>) -> Json<JsonResponse> { pub fn save_password_form_endpoint(password_form: Json<PasswordForm>) -> Json<JsonResponse> {
let result = save_password_form(password_form.into_inner()); let result = save_password_form(password_form.into_inner());

View File

@ -1,36 +1,22 @@
use serde::Serialize; use serde::Serialize;
use rocket_contrib::json::{Json}; use rocket_contrib::json::{Json};
use log::{debug, info, warn}; use log::{debug, info, warn};
use rocket::request::{FlashMessage}; use rocket::request::{FlashMessage};
use rocket::response::{Flash, Redirect}; use rocket::response::{Flash, Redirect};
use rocket::{get, post}; use rocket::{get, post};
use std::io;
use std::process::{Command, Output};
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use crate::utils::{build_json_response, JsonResponse};
use peach_lib::config_manager::load_peach_config; use peach_lib::config_manager::load_peach_config;
use peach_lib::dyndns_client; use peach_lib::dyndns_client;
use peach_lib::network_client; use peach_lib::network_client;
use peach_lib::oled_client; use peach_lib::oled_client;
use peach_lib::sbot_client; use peach_lib::sbot_client;
use peach_lib::stats_client; use peach_lib::stats_client;
use peach_lib::stats_client::{CpuStatPercentages, DiskUsage, LoadAverage, MemStat}; use peach_lib::stats_client::{CpuStatPercentages, DiskUsage, LoadAverage, MemStat};
use crate::utils::{build_json_response, JsonResponse};
use std::io;
use std::process::{Command, Output};
/// # helpers and routes for /device /// # helpers and routes for /device
///////////////////////////////// /////////////////////////////////

View File

@ -1,24 +1,16 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use log::{debug}; use log::{debug};
use rocket::response::{NamedFile}; use rocket::response::{NamedFile};
use rocket::{catch, get}; use rocket::{catch, get};
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::Serialize; use serde::Serialize;
#[get("/<file..>", rank = 2)] #[get("/<file..>", rank = 2)]
pub fn files(file: PathBuf) -> Option<NamedFile> { pub fn files(file: PathBuf) -> Option<NamedFile> {
NamedFile::open(Path::new("static/").join(file)).ok() NamedFile::open(Path::new("static/").join(file)).ok()
} }
/// # helpers and routes for /404 /// # helpers and routes for /404
///////////////////////////////// /////////////////////////////////
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]

View File

@ -1,10 +1,4 @@
use rocket::request::{FlashMessage}; use rocket::request::{FlashMessage};
use rocket::{get}; use rocket::{get};
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::Serialize; use serde::Serialize;

View File

@ -1,26 +1,14 @@
//! Helper routes for pinging services to check that they are active //! Helper routes for pinging services to check that they are active
use rocket_contrib::json::{Json}; use rocket_contrib::json::{Json};
use log::{debug, warn}; use log::{debug, warn};
use rocket::{get}; use rocket::{get};
use crate::utils::{build_json_response, JsonResponse};
use peach_lib::dyndns_client::{is_dns_updater_online}; use peach_lib::dyndns_client::{is_dns_updater_online};
use peach_lib::network_client; use peach_lib::network_client;
use peach_lib::oled_client; use peach_lib::oled_client;
use peach_lib::stats_client; use peach_lib::stats_client;
use crate::utils::{build_json_response, JsonResponse};
// status route: useful for checking connectivity from web client // status route: useful for checking connectivity from web client
#[get("/api/v1/ping")] #[get("/api/v1/ping")]

View File

@ -1,18 +1,11 @@
//! Routes for scuttlebutt related functionality. //! Routes for scuttlebutt related functionality.
use rocket::request::{FlashMessage}; use rocket::request::{FlashMessage};
use rocket::{get}; use rocket::{get};
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::Serialize; use serde::Serialize;
/// # helpers and routes for /messages
/////////////////////////////////
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct MessageContext { pub struct MessageContext {

View File

@ -1,128 +1,16 @@
use log::{info}; use log::{info};
use rocket::request::{FlashMessage, Form}; use rocket::request::{FlashMessage, Form};
use rocket::response::{Flash, Redirect}; use rocket::response::{Flash, Redirect};
use rocket::{get, post, uri}; use rocket::{get, post, uri};
use rocket::request::FromForm; use rocket::request::FromForm;
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use crate::error::PeachWebError;
use peach_lib::config_manager; use peach_lib::config_manager;
use peach_lib::config_manager::{load_peach_config}; use peach_lib::config_manager::{load_peach_config};
use peach_lib::password_utils; use peach_lib::password_utils;
use crate::error::PeachWebError;
#[derive(Debug, Deserialize, FromForm)]
pub struct AddAdminForm {
pub ssb_id: String,
}
#[derive(Debug, Deserialize, FromForm)]
pub struct DeleteAdminForm {
pub ssb_id: String,
}
/// # helpers and routes for /settings/change_password
/////////////////////////////////
#[derive(Debug, Serialize)]
pub struct ChangePasswordContext {
pub back: Option<String>,
pub title: Option<String>,
pub flash_name: Option<String>,
pub flash_msg: Option<String>,
}
impl ChangePasswordContext {
pub fn build() -> ChangePasswordContext {
ChangePasswordContext {
back: None,
title: None,
flash_name: None,
flash_msg: None,
}
}
}
#[derive(Debug, Deserialize, FromForm)]
pub struct PasswordForm {
pub old_password: String,
pub new_password1: String,
pub new_password2: String,
}
/// this function is for use by a user who is already logged in to change their password
pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebError> {
info!(
"change password!: {} {} {}",
password_form.old_password, password_form.new_password1, password_form.new_password2
);
password_utils::verify_password(&password_form.old_password)?;
// if the previous line did not throw an error, then the old password is correct
password_utils::validate_new_passwords(
&password_form.new_password1,
&password_form.new_password2,
)?;
// if the previous line did not throw an error, then the new password is valid
password_utils::set_new_password(&password_form.new_password1)?;
Ok(())
}
/// this change password route is used by a user who is already logged in
#[get("/settings/change_password")]
pub fn change_password(flash: Option<FlashMessage>) -> Template {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".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 {
// add flash message contents to the context object
context.flash_name = Some(flash.name().to_string());
context.flash_msg = Some(flash.msg().to_string());
};
Template::render("password/change_password", &context)
}
/// this change password route is used by a user who is already logged in
#[post("/settings/change_password", data = "<password_form>")]
pub fn change_password_post(password_form: Form<PasswordForm>) -> 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.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)
}
Err(err) => {
let mut context = ChangePasswordContext::build();
// set back icon link to network route
context.back = Some("/network".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)
}
}
}
pub fn save_add_admin_form(admin_form: AddAdminForm) -> Result<(), PeachWebError> {
let _result = config_manager::add_ssb_admin_id(&admin_form.ssb_id)?;
// if the previous line didn't throw an error then it was a success
Ok(())
}
/// # helpers and routes for /settings/configure_admin /// # helpers and routes for /settings/configure_admin
///////////////////////////////// /////////////////////////////////
@ -169,6 +57,11 @@ pub fn configure_admin(flash: Option<FlashMessage>) -> Template {
/// # helpers and routes for /settings/admin/add /// # helpers and routes for /settings/admin/add
///////////////////////////////// /////////////////////////////////
#[derive(Debug, Deserialize, FromForm)]
pub struct AddAdminForm {
pub ssb_id: String,
}
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct AddAdminContext { pub struct AddAdminContext {
pub back: Option<String>, pub back: Option<String>,
@ -188,6 +81,12 @@ impl AddAdminContext {
} }
} }
pub fn save_add_admin_form(admin_form: AddAdminForm) -> Result<(), PeachWebError> {
let _result = config_manager::add_ssb_admin_id(&admin_form.ssb_id)?;
// if the previous line didn't throw an error then it was a success
Ok(())
}
#[get("/settings/admin/add")] #[get("/settings/admin/add")]
pub fn add_admin(flash: Option<FlashMessage>) -> Template { pub fn add_admin(flash: Option<FlashMessage>) -> Template {
let mut context = AddAdminContext::build(); let mut context = AddAdminContext::build();
@ -213,6 +112,14 @@ pub fn add_admin_post(add_admin_form: Form<AddAdminForm>) -> Flash<Redirect> {
} }
} }
/// # helpers and routes for /settings/admin/delete
/////////////////////////////////
#[derive(Debug, Deserialize, FromForm)]
pub struct DeleteAdminForm {
pub ssb_id: String,
}
#[post("/settings/admin/delete", data = "<delete_admin_form>")] #[post("/settings/admin/delete", data = "<delete_admin_form>")]
pub fn delete_admin_post(delete_admin_form: Form<DeleteAdminForm>) -> Flash<Redirect> { pub fn delete_admin_post(delete_admin_form: Form<DeleteAdminForm>) -> Flash<Redirect> {
let result = config_manager::delete_ssb_admin_id(&delete_admin_form.ssb_id); let result = config_manager::delete_ssb_admin_id(&delete_admin_form.ssb_id);

View File

@ -1,19 +1,11 @@
use rocket_contrib::json::{Json}; use rocket_contrib::json::{Json};
use log::{info}; use log::{info};
use rocket::request::{FlashMessage, Form}; use rocket::request::{FlashMessage, Form};
use rocket::{get, post}; use rocket::{get, post};
use rocket::request::FromForm; use rocket::request::FromForm;
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use crate::error::PeachWebError;
use crate::utils::{build_json_response, JsonResponse};
use peach_lib::config_manager; use peach_lib::config_manager;
use peach_lib::config_manager::{load_peach_config}; use peach_lib::config_manager::{load_peach_config};
use peach_lib::dyndns_client; use peach_lib::dyndns_client;
@ -23,6 +15,9 @@ use peach_lib::error::PeachError;
use peach_lib::jsonrpc_client_core::{Error, ErrorKind}; use peach_lib::jsonrpc_client_core::{Error, ErrorKind};
use peach_lib::jsonrpc_core::types::error::ErrorCode; use peach_lib::jsonrpc_core::types::error::ErrorCode;
use crate::error::PeachWebError;
use crate::utils::{build_json_response, JsonResponse};
#[derive(Debug, Deserialize, FromForm)] #[derive(Debug, Deserialize, FromForm)]
pub struct DnsForm { pub struct DnsForm {
@ -81,9 +76,6 @@ pub fn save_dns_configuration(dns_form: DnsForm) -> Result<(), PeachWebError> {
} }
} }
/// # helpers and routes for /network/dns
/////////////////////////////////
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct ConfigureDNSContext { pub struct ConfigureDNSContext {
pub external_domain: String, pub external_domain: String,

View File

@ -1,5 +1,4 @@
use std::collections::HashMap; use std::collections::HashMap;
use rocket_contrib::json; use rocket_contrib::json;
use rocket_contrib::json::{Json}; use rocket_contrib::json::{Json};
use log::{debug, warn}; use log::{debug, warn};
@ -13,18 +12,15 @@ use rocket::UriDisplayQuery;
use rocket_contrib::templates::Template; use rocket_contrib::templates::Template;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use peach_lib::network_client;
use peach_lib::network_client::{AccessPoint, Networks, Scan};
use peach_lib::stats_client::{Traffic};
use crate::utils::{build_json_response, JsonResponse}; use crate::utils::{build_json_response, JsonResponse};
use crate::utils::monitor; use crate::utils::monitor;
use crate::utils::monitor::{Threshold, Data, Alert}; use crate::utils::monitor::{Threshold, Data, Alert};
use peach_lib::network_client;
use peach_lib::network_client::{AccessPoint, Networks, Scan};
use peach_lib::stats_client::{Traffic};
/// # structs used by network routes /// # structs used by network routes
//////////////////////////////////// ////////////////////////////////////
@ -585,6 +581,9 @@ pub fn deploy_client() -> Flash<Redirect> {
} }
} }
/// # helpers and routes for /network/wifi/add
/////////////////////////////////
#[get("/network/wifi/add")] #[get("/network/wifi/add")]
pub fn network_add_wifi(flash: Option<FlashMessage>) -> Template { pub fn network_add_wifi(flash: Option<FlashMessage>) -> Template {
let mut context = NetworkContext::build(); let mut context = NetworkContext::build();
@ -601,7 +600,6 @@ pub fn network_add_wifi(flash: Option<FlashMessage>) -> Template {
Template::render("network_add", &context) Template::render("network_add", &context)
} }
// used in /network/wifi/add?<ssid> // used in /network/wifi/add?<ssid>
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct NetworkAddContext { pub struct NetworkAddContext {