documentation tidy-up
This commit is contained in:
parent
a48838ad1d
commit
5df88b81ce
|
@ -1,4 +1,4 @@
|
|||
//!! different types of PeachWebError
|
||||
//! Custom error type representing all possible error variants for peach-web.
|
||||
|
||||
use peach_lib::error::PeachError;
|
||||
use peach_lib::{serde_json, serde_yaml};
|
||||
|
|
|
@ -24,15 +24,12 @@
|
|||
//! of the template to be rendered.
|
||||
|
||||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
// this is to ignore a clippy warning that suggests
|
||||
// to replace code with the same code that is already there (possibly a bug)
|
||||
#![allow(clippy::nonstandard_macro_braces)]
|
||||
|
||||
pub mod error;
|
||||
pub mod routes;
|
||||
pub mod utils;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
pub mod utils;
|
||||
mod ws;
|
||||
|
||||
use std::{env, thread};
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
use rocket_contrib::json::{Json};
|
||||
use log::{debug, info};
|
||||
use rocket::request::{FlashMessage, Form};
|
||||
use rocket::request::{FlashMessage, Form, FromForm};
|
||||
use rocket::response::{Flash, Redirect};
|
||||
use rocket::{get, post};
|
||||
use rocket::request::FromForm;
|
||||
use rocket_contrib::templates::Template;
|
||||
use rocket_contrib::{json::Json, templates::Template};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use peach_lib::password_utils;
|
||||
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
use crate::error::PeachWebError;
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
|
||||
|
||||
/// # helpers and routes for /login
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /login
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct LoginContext {
|
||||
|
@ -49,8 +45,7 @@ pub fn login(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("login", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /logout
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /logout
|
||||
|
||||
#[post("/logout")]
|
||||
pub fn logout() -> Flash<Redirect> {
|
||||
|
@ -68,8 +63,7 @@ pub fn logout() -> Flash<Redirect> {
|
|||
Flash::success(Redirect::to("/"), "Logged out")
|
||||
}
|
||||
|
||||
/// # helpers and routes for /reset_password
|
||||
//////////////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /reset_password
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm)]
|
||||
pub struct ResetPasswordForm {
|
||||
|
@ -116,7 +110,7 @@ impl ChangePasswordContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// this function is publicly exposed for users who have forgotten their password
|
||||
/// Verify, validate and save the submitted password. This function is publicly exposed for users who have forgotten their password.
|
||||
pub fn save_reset_password_form(password_form: ResetPasswordForm) -> Result<(), PeachWebError> {
|
||||
info!(
|
||||
"reset password!: {} {} {}",
|
||||
|
@ -133,9 +127,9 @@ pub fn save_reset_password_form(password_form: ResetPasswordForm) -> Result<(),
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// this reset password 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
|
||||
/// Password reset 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.
|
||||
#[get("/reset_password")]
|
||||
pub fn reset_password(flash: Option<FlashMessage>) -> Template {
|
||||
let mut context = ResetPasswordContext::build();
|
||||
|
@ -150,9 +144,9 @@ pub fn reset_password(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("password/reset_password", &context)
|
||||
}
|
||||
|
||||
/// this reset password route is used by a user who is not logged in
|
||||
/// and is specifically for users who have forgotten their password
|
||||
/// and is excluded from nginx basic auth via the nginx config
|
||||
/// 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.
|
||||
/// This route is excluded from nginx basic auth via the nginx config.
|
||||
#[post("/reset_password", data = "<reset_password_form>")]
|
||||
pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Template {
|
||||
let result = save_reset_password_form(reset_password_form.into_inner());
|
||||
|
@ -178,9 +172,9 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
|
|||
}
|
||||
}
|
||||
|
||||
/// this reset password 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
|
||||
/// 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>,
|
||||
|
@ -200,10 +194,7 @@ pub fn reset_password_form_endpoint(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /send_password_reset
|
||||
////////////////////////////////////////////////
|
||||
|
||||
// HELPERS AND ROUTES FOR /send_password_reset
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct SendPasswordResetContext {
|
||||
|
@ -224,7 +215,7 @@ impl SendPasswordResetContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// this route is used by a user who is not logged in to send a new password reset link
|
||||
/// Password reset request handler. This route is used by a user who is not logged in to send a new password reset link.
|
||||
#[get("/send_password_reset")]
|
||||
pub fn send_password_reset_page(flash: Option<FlashMessage>) -> Template {
|
||||
let mut context = SendPasswordResetContext::build();
|
||||
|
@ -239,8 +230,9 @@ pub fn send_password_reset_page(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("password/send_password_reset", &context)
|
||||
}
|
||||
|
||||
/// this send_password_reset route is used by a user who is not logged in
|
||||
/// and is specifically for users who have forgotten their password
|
||||
/// Send password reset request handler. This route is used by a user who is not logged in
|
||||
/// and is specifically for users who have forgotten their password. A successful request results
|
||||
/// in a Scuttlebutt private message being sent to the account of the device admin.
|
||||
#[post("/send_password_reset")]
|
||||
pub fn send_password_reset_post() -> Template {
|
||||
info!("++ send password reset post");
|
||||
|
@ -267,8 +259,7 @@ pub fn send_password_reset_post() -> Template {
|
|||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /settings/change_password
|
||||
//////////////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /settings/change_password
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm)]
|
||||
pub struct PasswordForm {
|
||||
|
@ -277,7 +268,7 @@ pub struct PasswordForm {
|
|||
pub new_password2: String,
|
||||
}
|
||||
|
||||
/// this function is for use by a user who is already logged in to change their password
|
||||
/// Password save form request handler. 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!: {} {} {}",
|
||||
|
@ -294,7 +285,7 @@ pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebErr
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// this change password route is used by a user who is already logged in
|
||||
/// Change password request handler. This 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();
|
||||
|
@ -310,7 +301,7 @@ pub fn change_password(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("password/change_password", &context)
|
||||
}
|
||||
|
||||
/// this change password route is used by a user who is already logged in
|
||||
/// Change password form request handler. This 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());
|
||||
|
@ -337,6 +328,7 @@ pub fn change_password_post(password_form: Form<PasswordForm>) -> Template {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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>) -> Json<JsonResponse> {
|
||||
let result = save_password_form(password_form.into_inner());
|
||||
|
@ -352,4 +344,4 @@ pub fn save_password_form_endpoint(password_form: Json<PasswordForm>) -> Json<Js
|
|||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
use serde::Serialize;
|
||||
use rocket_contrib::json::{Json};
|
||||
use log::{debug, info, warn};
|
||||
use rocket::request::{FlashMessage};
|
||||
use rocket::response::{Flash, Redirect};
|
||||
use rocket::{get, post};
|
||||
use std::io;
|
||||
use std::process::{Command, Output};
|
||||
use rocket_contrib::templates::Template;
|
||||
use rocket::{
|
||||
get, post,
|
||||
request::FlashMessage,
|
||||
response::{Flash, Redirect},
|
||||
};
|
||||
use rocket_contrib::{json::Json, templates::Template};
|
||||
use serde::Serialize;
|
||||
use std::{
|
||||
io,
|
||||
process::{Command, Output},
|
||||
};
|
||||
|
||||
use peach_lib::config_manager::load_peach_config;
|
||||
use peach_lib::dyndns_client;
|
||||
use peach_lib::network_client;
|
||||
use peach_lib::oled_client;
|
||||
use peach_lib::sbot_client;
|
||||
use peach_lib::stats_client;
|
||||
use peach_lib::stats_client::{CpuStatPercentages, DiskUsage, LoadAverage, MemStat};
|
||||
use peach_lib::{dyndns_client, network_client, oled_client, sbot_client, stats_client};
|
||||
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
|
||||
/// # helpers and routes for /device
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /device
|
||||
|
||||
// used in /device for system statistics
|
||||
/// System statistics data.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct DeviceContext {
|
||||
pub back: Option<String>,
|
||||
|
@ -165,8 +163,7 @@ pub fn device_stats(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("device", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /device/reboot
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /device/reboot
|
||||
|
||||
/// Executes a system command to reboot the device immediately.
|
||||
pub fn reboot() -> io::Result<Output> {
|
||||
|
@ -189,7 +186,7 @@ pub fn reboot_cmd() -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
// reboot the device
|
||||
/// JSON request handler for device reboot.
|
||||
#[post("/api/v1/device/reboot")]
|
||||
pub fn reboot_device() -> Json<JsonResponse> {
|
||||
match reboot() {
|
||||
|
@ -208,17 +205,15 @@ pub fn reboot_device() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /device/shutdown
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /device/shutdown
|
||||
|
||||
/// Executes a system command to shutdown the device immediately.
|
||||
pub fn shutdown() -> io::Result<Output> {
|
||||
info ! ("Shutting down the device");
|
||||
// ideally, we'd like to reboot after 5 seconds to allow time for JSON
|
||||
// response but this is not possible with the `shutdown` command alone.
|
||||
// TODO: send "shutting down..." message to `peach-oled` for display
|
||||
Command::new("sudo").arg("shutdown").arg("now").output()
|
||||
info!("Shutting down the device");
|
||||
// ideally, we'd like to reboot after 5 seconds to allow time for JSON
|
||||
// response but this is not possible with the `shutdown` command alone.
|
||||
// TODO: send "shutting down..." message to `peach-oled` for display
|
||||
Command::new("sudo").arg("shutdown").arg("now").output()
|
||||
}
|
||||
|
||||
#[get("/device/shutdown")]
|
||||
|
@ -248,9 +243,7 @@ pub fn shutdown_device() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /shutdown
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /shutdown
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ShutdownContext {
|
||||
|
@ -283,4 +276,4 @@ pub fn shutdown_menu(flash: Option<FlashMessage>) -> Template {
|
|||
context.flash_msg = Some(flash.msg().to_string());
|
||||
};
|
||||
Template::render("shutdown", &context)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
use log::{debug};
|
||||
use rocket::response::{NamedFile};
|
||||
use rocket::{catch, get};
|
||||
use log::debug;
|
||||
use rocket::{catch, get, response::NamedFile};
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::Serialize;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[get("/<file..>", rank = 2)]
|
||||
pub fn files(file: PathBuf) -> Option<NamedFile> {
|
||||
NamedFile::open(Path::new("static/").join(file)).ok()
|
||||
}
|
||||
|
||||
/// # helpers and routes for /404
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR 404 ERROR
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ErrorContext {
|
||||
pub back: Option<String>,
|
||||
|
@ -44,8 +42,7 @@ pub fn not_found() -> Template {
|
|||
Template::render("not_found", context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for 500
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR 500 ERROR
|
||||
|
||||
#[catch(500)]
|
||||
pub fn internal_error() -> Template {
|
||||
|
@ -58,4 +55,3 @@ pub fn internal_error() -> Template {
|
|||
|
||||
Template::render("internal_error", context)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use rocket::request::{FlashMessage};
|
||||
use rocket::{get};
|
||||
use rocket::{get, request::FlashMessage};
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::Serialize;
|
||||
|
||||
|
||||
/// # helpers and routes for / (home page)
|
||||
/////////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR / (HOME PAGE)
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct HomeContext {
|
||||
|
@ -34,8 +31,7 @@ pub fn index() -> Template {
|
|||
Template::render("index", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /help
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /help
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct HelpContext {
|
||||
|
@ -69,5 +65,3 @@ pub fn help(flash: Option<FlashMessage>) -> Template {
|
|||
};
|
||||
Template::render("help", &context)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
//! Helper routes for pinging services to check that they are active
|
||||
use rocket_contrib::json::{Json};
|
||||
use log::{debug, warn};
|
||||
use rocket::{get};
|
||||
use rocket::get;
|
||||
use rocket_contrib::json::Json;
|
||||
|
||||
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::oled_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")]
|
||||
pub fn ping_pong() -> Json<JsonResponse> {
|
||||
// ping pong
|
||||
|
@ -19,7 +19,7 @@ pub fn ping_pong() -> Json<JsonResponse> {
|
|||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
|
||||
// test route: useful for ad hoc testing
|
||||
/// Test route: useful for ad hoc testing.
|
||||
#[get("/api/v1/test")]
|
||||
pub fn test_route() -> Json<JsonResponse> {
|
||||
let val = is_dns_updater_online().unwrap();
|
||||
|
@ -28,7 +28,7 @@ pub fn test_route() -> Json<JsonResponse> {
|
|||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
|
||||
// status route: check availability of `peach-network` microservice
|
||||
/// Status route: check availability of `peach-network` microservice.
|
||||
#[get("/api/v1/ping/network")]
|
||||
pub fn ping_network() -> Json<JsonResponse> {
|
||||
match network_client::ping() {
|
||||
|
@ -47,7 +47,7 @@ pub fn ping_network() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
// status route: check availability of `peach-oled` microservice
|
||||
/// Status route: check availability of `peach-oled` microservice.
|
||||
#[get("/api/v1/ping/oled")]
|
||||
pub fn ping_oled() -> Json<JsonResponse> {
|
||||
match oled_client::ping() {
|
||||
|
@ -66,7 +66,7 @@ pub fn ping_oled() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
// status route: check availability of `peach-stats` microservice
|
||||
/// Status route: check availability of `peach-stats` microservice.
|
||||
#[get("/api/v1/ping/stats")]
|
||||
pub fn ping_stats() -> Json<JsonResponse> {
|
||||
match stats_client::ping() {
|
||||
|
@ -83,4 +83,4 @@ pub fn ping_stats() -> Json<JsonResponse> {
|
|||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
//! Routes for scuttlebutt related functionality.
|
||||
use rocket::request::{FlashMessage};
|
||||
use rocket::{get};
|
||||
//! Routes for ScuttleButt related functionality.
|
||||
|
||||
use rocket::{get, request::FlashMessage};
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::Serialize;
|
||||
|
||||
/// # helpers and routes for /messages
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /messages
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct MessageContext {
|
||||
|
@ -40,8 +39,7 @@ pub fn messages(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("messages", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /peers
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /peers
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct PeerContext {
|
||||
|
@ -76,9 +74,7 @@ pub fn peers(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("peers", &context)
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /profile
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /profile
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ProfileContext {
|
||||
|
@ -111,4 +107,4 @@ pub fn profile(flash: Option<FlashMessage>) -> Template {
|
|||
context.flash_msg = Some(flash.msg().to_string());
|
||||
};
|
||||
Template::render("profile", &context)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
|
||||
use rocket::request::{FlashMessage, Form};
|
||||
use rocket::response::{Flash, Redirect};
|
||||
use rocket::{get, post, uri};
|
||||
use rocket::request::FromForm;
|
||||
use rocket::{
|
||||
get, post,
|
||||
request::{FlashMessage, Form, FromForm},
|
||||
response::{Flash, Redirect},
|
||||
uri,
|
||||
};
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use peach_lib::config_manager;
|
||||
use peach_lib::config_manager::{load_peach_config};
|
||||
|
||||
use peach_lib::config_manager::load_peach_config;
|
||||
|
||||
use crate::error::PeachWebError;
|
||||
|
||||
/// # helpers and routes for /settings/configure_admin
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /settings/configure_admin
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ConfigureAdminContext {
|
||||
|
@ -38,7 +37,7 @@ impl ConfigureAdminContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// this is a route for viewing and deleting currently configured admin
|
||||
/// View and delete currently configured admin.
|
||||
#[get("/settings/configure_admin")]
|
||||
pub fn configure_admin(flash: Option<FlashMessage>) -> Template {
|
||||
let mut context = ConfigureAdminContext::build();
|
||||
|
@ -54,8 +53,7 @@ pub fn configure_admin(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("admin/configure_admin", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /settings/admin/add
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /settings/admin/add
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm)]
|
||||
pub struct AddAdminForm {
|
||||
|
@ -112,8 +110,7 @@ pub fn add_admin_post(add_admin_form: Form<AddAdminForm>) -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /settings/admin/delete
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /settings/admin/delete
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm)]
|
||||
pub struct DeleteAdminForm {
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
use rocket_contrib::json::{Json};
|
||||
use log::{info};
|
||||
use rocket::request::{FlashMessage, Form};
|
||||
use rocket::{get, post};
|
||||
use rocket::request::FromForm;
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use log::info;
|
||||
use rocket::{
|
||||
get, post,
|
||||
request::{FlashMessage, Form, FromForm},
|
||||
};
|
||||
use rocket_contrib::{json::Json, templates::Template};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
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::{check_is_new_dyndns_domain, get_full_dynamic_domain};
|
||||
use peach_lib::dyndns_client::{get_dyndns_subdomain, is_dns_updater_online};
|
||||
use peach_lib::dyndns_client::{
|
||||
check_is_new_dyndns_domain, get_dyndns_subdomain, get_full_dynamic_domain,
|
||||
is_dns_updater_online,
|
||||
};
|
||||
use peach_lib::error::PeachError;
|
||||
use peach_lib::jsonrpc_client_core::{Error, ErrorKind};
|
||||
use peach_lib::jsonrpc_core::types::error::ErrorCode;
|
||||
|
@ -18,7 +20,6 @@ use peach_lib::jsonrpc_core::types::error::ErrorCode;
|
|||
use crate::error::PeachWebError;
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm)]
|
||||
pub struct DnsForm {
|
||||
pub external_domain: String,
|
||||
|
@ -164,5 +165,3 @@ pub fn save_dns_configuration_endpoint(dns_form: Json<DnsForm>) -> Json<JsonResp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
use std::collections::HashMap;
|
||||
use rocket_contrib::json;
|
||||
use rocket_contrib::json::{Json};
|
||||
use log::{debug, warn};
|
||||
use percent_encoding::percent_decode;
|
||||
use rocket::http::RawStr;
|
||||
use rocket::request::{FlashMessage, Form};
|
||||
use rocket::response::{Flash, Redirect};
|
||||
use rocket::{get, post, uri};
|
||||
use rocket::request::FromForm;
|
||||
use rocket::UriDisplayQuery;
|
||||
use rocket_contrib::templates::Template;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use rocket::{
|
||||
get,
|
||||
http::RawStr,
|
||||
post,
|
||||
request::{FlashMessage, Form, FromForm},
|
||||
response::{Flash, Redirect},
|
||||
uri, UriDisplayQuery,
|
||||
};
|
||||
use rocket_contrib::{json, json::Json, templates::Template};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use peach_lib::network_client;
|
||||
use peach_lib::network_client::{AccessPoint, Networks, Scan};
|
||||
use peach_lib::stats_client::{Traffic};
|
||||
use peach_lib::stats_client::Traffic;
|
||||
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
use crate::utils::monitor;
|
||||
use crate::utils::monitor::{Threshold, Data, Alert};
|
||||
use crate::utils::monitor::{Alert, Data, Threshold};
|
||||
use crate::utils::{build_json_response, JsonResponse};
|
||||
|
||||
|
||||
/// # structs used by network routes
|
||||
////////////////////////////////////
|
||||
// STRUCTS USED BY NETWORK ROUTES
|
||||
|
||||
#[derive(Debug, Deserialize, FromForm, UriDisplayQuery)]
|
||||
pub struct Ssid {
|
||||
|
@ -35,9 +33,7 @@ pub struct WiFi {
|
|||
pub pass: String,
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /network/wifi/usage/reset
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/wifi/usage/reset
|
||||
|
||||
#[get("/network/wifi/usage/reset")]
|
||||
pub fn wifi_usage_reset() -> Flash<Redirect> {
|
||||
|
@ -122,8 +118,7 @@ pub fn wifi_set_password(wifi: Form<WiFi>) -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /network
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct NetworkContext {
|
||||
|
@ -295,8 +290,7 @@ pub fn network_home(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("network_card", &context)
|
||||
}
|
||||
|
||||
/// # helpers and routes for /network/ap/activate
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/ap/activate
|
||||
|
||||
#[get("/network/ap/activate")]
|
||||
pub fn deploy_ap() -> Flash<Redirect> {
|
||||
|
@ -311,8 +305,7 @@ pub fn deploy_ap() -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /network/wifi
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/wifi
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct NetworkListContext {
|
||||
|
@ -397,9 +390,7 @@ pub fn wifi_list(flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("network_list", &context)
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /network/wifi<ssid>
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/wifi<ssid>
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct NetworkDetailContext {
|
||||
|
@ -567,9 +558,7 @@ pub fn network_detail(ssid: &RawStr, flash: Option<FlashMessage>) -> Template {
|
|||
Template::render("network_detail", &context)
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /network/wifi/activate
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/wifi/activate
|
||||
|
||||
#[get("/network/wifi/activate")]
|
||||
pub fn deploy_client() -> Flash<Redirect> {
|
||||
|
@ -581,8 +570,7 @@ pub fn deploy_client() -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /network/wifi/add
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR /network/wifi/add
|
||||
|
||||
#[get("/network/wifi/add")]
|
||||
pub fn network_add_wifi(flash: Option<FlashMessage>) -> Template {
|
||||
|
@ -686,9 +674,7 @@ pub fn add_credentials(wifi: Form<WiFi>) -> Template {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// # helpers and routes for /network/wifi/usage
|
||||
/////////////////////////////////
|
||||
// HELPERS AND ROUTES FOR WIFI USAGE
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct NetworkAlertContext {
|
||||
|
@ -772,9 +758,55 @@ pub fn wifi_usage_alerts(thresholds: Form<Threshold>) -> Flash<Redirect> {
|
|||
}
|
||||
}
|
||||
|
||||
#[post("/api/v1/network/wifi/usage", data = "<thresholds>")]
|
||||
pub fn update_wifi_alerts(thresholds: Json<Threshold>) -> Json<JsonResponse> {
|
||||
match monitor::update_store(thresholds.into_inner()) {
|
||||
Ok(_) => {
|
||||
debug!("WiFi data usage thresholds updated.");
|
||||
let status = "success".to_string();
|
||||
let msg = "Updated alert threshold and flags.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Failed to update WiFi data usage thresholds.");
|
||||
let status = "error".to_string();
|
||||
let msg = "Failed to update WiFi data usage thresholds.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # helpers and routes for /network/activate_ap
|
||||
//////////////////////////////////
|
||||
#[post("/api/v1/network/wifi/usage/reset")]
|
||||
pub fn reset_data_total() -> Json<JsonResponse> {
|
||||
match monitor::reset_data() {
|
||||
Ok(_) => {
|
||||
debug!("Reset network data usage total.");
|
||||
let traffic = match network_client::traffic("wlan0") {
|
||||
Ok(t) => t,
|
||||
Err(_) => Traffic {
|
||||
received: 0,
|
||||
transmitted: 0,
|
||||
rx_unit: None,
|
||||
tx_unit: None,
|
||||
},
|
||||
};
|
||||
// current wifi traffic values as bytes
|
||||
let current_traffic = traffic.received + traffic.transmitted;
|
||||
let data = json!(current_traffic);
|
||||
let status = "success".to_string();
|
||||
let msg = "Reset network data usage total.".to_string();
|
||||
Json(build_json_response(status, Some(data), Some(msg)))
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Failed to reset network data usage total.");
|
||||
let status = "error".to_string();
|
||||
let msg = "Failed to reset network data usage total.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HELPERS AND ROUTES FOR ACCESS POINT ACTIVATION
|
||||
|
||||
#[post("/api/v1/network/activate_ap")]
|
||||
pub fn activate_ap() -> Json<JsonResponse> {
|
||||
|
@ -793,6 +825,8 @@ pub fn activate_ap() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
// HELPERS AND ROUTES FOR WIFI CLIENT MANAGEMENT
|
||||
|
||||
#[post("/api/v1/network/activate_client")]
|
||||
pub fn activate_client() -> Json<JsonResponse> {
|
||||
// activate the wireless client
|
||||
|
@ -810,114 +844,6 @@ pub fn activate_client() -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/ip")]
|
||||
pub fn return_ip() -> Json<JsonResponse> {
|
||||
// retrieve ip for wlan0 or set to x.x.x.x if not found
|
||||
let wlan_ip = match network_client::ip("wlan0") {
|
||||
Ok(ip) => ip,
|
||||
Err(_) => "x.x.x.x".to_string(),
|
||||
};
|
||||
// retrieve ip for ap0 or set to x.x.x.x if not found
|
||||
let ap_ip = match network_client::ip("ap0") {
|
||||
Ok(ip) => ip,
|
||||
Err(_) => "x.x.x.x".to_string(),
|
||||
};
|
||||
let data = json!({
|
||||
"wlan0": wlan_ip,
|
||||
"ap0": ap_ip
|
||||
});
|
||||
let status = "success".to_string();
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/rssi")]
|
||||
pub fn return_rssi() -> Json<JsonResponse> {
|
||||
// retrieve rssi for connected network
|
||||
match network_client::rssi("wlan0") {
|
||||
Ok(rssi) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(rssi);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/ssid")]
|
||||
pub fn return_ssid() -> Json<JsonResponse> {
|
||||
// retrieve ssid for connected network
|
||||
match network_client::ssid("wlan0") {
|
||||
Ok(network) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(network);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/state")]
|
||||
pub fn return_state() -> Json<JsonResponse> {
|
||||
// retrieve state of wlan0 or set to x.x.x.x if not found
|
||||
let wlan_state = match network_client::state("wlan0") {
|
||||
Ok(state) => state,
|
||||
Err(_) => "unavailable".to_string(),
|
||||
};
|
||||
// retrieve state for ap0 or set to x.x.x.x if not found
|
||||
let ap_state = match network_client::state("ap0") {
|
||||
Ok(state) => state,
|
||||
Err(_) => "unavailable".to_string(),
|
||||
};
|
||||
let data = json!({
|
||||
"wlan0": wlan_state,
|
||||
"ap0": ap_state
|
||||
});
|
||||
let status = "success".to_string();
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/status")]
|
||||
pub fn return_status() -> Json<JsonResponse> {
|
||||
// retrieve status info for wlan0 interface
|
||||
match network_client::status("wlan0") {
|
||||
Ok(network) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(network);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/wifi")]
|
||||
pub fn scan_networks() -> Json<JsonResponse> {
|
||||
// retrieve scan results for access-points within range of wlan0
|
||||
match network_client::available_networks("wlan0") {
|
||||
Ok(networks) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(networks);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Unable to scan for networks. Interface may be deactivated.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/api/v1/network/wifi", data = "<wifi>")]
|
||||
pub fn add_wifi(wifi: Json<WiFi>) -> Json<JsonResponse> {
|
||||
// generate and write wifi config to wpa_supplicant
|
||||
|
@ -1028,51 +954,112 @@ pub fn modify_password(wifi: Json<WiFi>) -> Json<JsonResponse> {
|
|||
}
|
||||
}
|
||||
|
||||
#[post("/api/v1/network/wifi/usage", data = "<thresholds>")]
|
||||
pub fn update_wifi_alerts(thresholds: Json<Threshold>) -> Json<JsonResponse> {
|
||||
match monitor::update_store(thresholds.into_inner()) {
|
||||
Ok(_) => {
|
||||
debug!("WiFi data usage thresholds updated.");
|
||||
// HELPERS AND ROUTES FOR NETWORK STATE QUERIES
|
||||
|
||||
#[get("/api/v1/network/ip")]
|
||||
pub fn return_ip() -> Json<JsonResponse> {
|
||||
// retrieve ip for wlan0 or set to x.x.x.x if not found
|
||||
let wlan_ip = match network_client::ip("wlan0") {
|
||||
Ok(ip) => ip,
|
||||
Err(_) => "x.x.x.x".to_string(),
|
||||
};
|
||||
// retrieve ip for ap0 or set to x.x.x.x if not found
|
||||
let ap_ip = match network_client::ip("ap0") {
|
||||
Ok(ip) => ip,
|
||||
Err(_) => "x.x.x.x".to_string(),
|
||||
};
|
||||
let data = json!({
|
||||
"wlan0": wlan_ip,
|
||||
"ap0": ap_ip
|
||||
});
|
||||
let status = "success".to_string();
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/rssi")]
|
||||
pub fn return_rssi() -> Json<JsonResponse> {
|
||||
// retrieve rssi for connected network
|
||||
match network_client::rssi("wlan0") {
|
||||
Ok(rssi) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Updated alert threshold and flags.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
let data = json!(rssi);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Failed to update WiFi data usage thresholds.");
|
||||
let status = "error".to_string();
|
||||
let msg = "Failed to update WiFi data usage thresholds.".to_string();
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/api/v1/network/wifi/usage/reset")]
|
||||
pub fn reset_data_total() -> Json<JsonResponse> {
|
||||
match monitor::reset_data() {
|
||||
Ok(_) => {
|
||||
debug!("Reset network data usage total.");
|
||||
let traffic = match network_client::traffic("wlan0") {
|
||||
Ok(t) => t,
|
||||
Err(_) => Traffic {
|
||||
received: 0,
|
||||
transmitted: 0,
|
||||
rx_unit: None,
|
||||
tx_unit: None,
|
||||
},
|
||||
};
|
||||
// current wifi traffic values as bytes
|
||||
let current_traffic = traffic.received + traffic.transmitted;
|
||||
let data = json!(current_traffic);
|
||||
#[get("/api/v1/network/ssid")]
|
||||
pub fn return_ssid() -> Json<JsonResponse> {
|
||||
// retrieve ssid for connected network
|
||||
match network_client::ssid("wlan0") {
|
||||
Ok(network) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Reset network data usage total.".to_string();
|
||||
Json(build_json_response(status, Some(data), Some(msg)))
|
||||
let data = json!(network);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("Failed to reset network data usage total.");
|
||||
let status = "error".to_string();
|
||||
let msg = "Failed to reset network data usage total.".to_string();
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/state")]
|
||||
pub fn return_state() -> Json<JsonResponse> {
|
||||
// retrieve state of wlan0 or set to x.x.x.x if not found
|
||||
let wlan_state = match network_client::state("wlan0") {
|
||||
Ok(state) => state,
|
||||
Err(_) => "unavailable".to_string(),
|
||||
};
|
||||
// retrieve state for ap0 or set to x.x.x.x if not found
|
||||
let ap_state = match network_client::state("ap0") {
|
||||
Ok(state) => state,
|
||||
Err(_) => "unavailable".to_string(),
|
||||
};
|
||||
let data = json!({
|
||||
"wlan0": wlan_state,
|
||||
"ap0": ap_state
|
||||
});
|
||||
let status = "success".to_string();
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/status")]
|
||||
pub fn return_status() -> Json<JsonResponse> {
|
||||
// retrieve status info for wlan0 interface
|
||||
match network_client::status("wlan0") {
|
||||
Ok(network) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(network);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Not currently connected to an access point.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/v1/network/wifi")]
|
||||
pub fn scan_networks() -> Json<JsonResponse> {
|
||||
// retrieve scan results for access-points within range of wlan0
|
||||
match network_client::available_networks("wlan0") {
|
||||
Ok(networks) => {
|
||||
let status = "success".to_string();
|
||||
let data = json!(networks);
|
||||
Json(build_json_response(status, Some(data), None))
|
||||
}
|
||||
Err(_) => {
|
||||
let status = "success".to_string();
|
||||
let msg = "Unable to scan for networks. Interface may be deactivated.".to_string();
|
||||
Json(build_json_response(status, None, Some(msg)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use rocket::http::{ContentType, Status};
|
|||
use rocket::local::Client;
|
||||
use rocket_contrib::json;
|
||||
|
||||
use crate::utils::{build_json_response};
|
||||
use crate::utils::build_json_response;
|
||||
|
||||
use super::rocket;
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
pub mod monitor;
|
||||
|
||||
use rocket_contrib::json::{JsonValue};
|
||||
use rocket_contrib::json::JsonValue;
|
||||
use serde::Serialize;
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct JsonResponse {
|
||||
pub status: String,
|
||||
|
@ -21,7 +22,6 @@ pub fn build_json_response(
|
|||
JsonResponse { status, data, msg }
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct FlashContext {
|
||||
pub flash_name: Option<String>,
|
||||
|
|
|
@ -9,12 +9,12 @@ use websocket::sync::Server;
|
|||
use websocket::{Message, OwnedMessage};
|
||||
|
||||
pub fn websocket_server(address: String) -> io::Result<()> {
|
||||
// Start listening for WebSocket connections
|
||||
// start listening for WebSocket connections
|
||||
let ws_server = Server::bind(address)?;
|
||||
|
||||
info!("Listening for WebSocket connections.");
|
||||
for connection in ws_server.filter_map(Result::ok) {
|
||||
// Spawn a new thread for each connection.
|
||||
// spawn a new thread for each connection
|
||||
thread::spawn(move || {
|
||||
if !connection
|
||||
.protocols()
|
||||
|
|
Loading…
Reference in New Issue