documentation tidy-up

This commit is contained in:
glyph 2021-11-03 11:52:02 +02:00
parent a48838ad1d
commit 5df88b81ce
14 changed files with 274 additions and 323 deletions

View File

@ -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};

View File

@ -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};

View File

@ -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)))
}
}
}
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)))
}
}
}
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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
}
}
}

View File

@ -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)))
}
}
}

View File

@ -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;

View File

@ -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>,

View File

@ -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()