Refactor route and template organisation #28
|
@ -12,62 +12,30 @@ The peach-web stack currently consists of [Rocket](https://rocket.rs/) (Rust web
|
||||||
|
|
||||||
_Note: This is a work-in-progress._
|
_Note: This is a work-in-progress._
|
||||||
|
|
||||||
### WEB ROUTES (`src/routes.rs`)
|
### Setup
|
||||||
|
|
||||||
| Endpoint | Method | Parameters | Description |
|
Clone the `peach-workspace` repo:
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| `/` | GET | | Home |
|
|
||||||
| `/device` | GET | | Device status overview |
|
|
||||||
| `/device/reboot` | GET | | Reboot device |
|
|
||||||
| `/device/shutdown` | GET | | Shutdown device |
|
|
||||||
| `/login` | GET | | Login form |
|
|
||||||
| `/network` | GET | | Network status overview |
|
|
||||||
| `/network/ap/activate` | GET | | Activate WiFi access point mode |
|
|
||||||
| `/network/wifi` | GET | | List of networks |
|
|
||||||
| `/network/wifi?<ssid>` | GET | `ssid` | Details of a single network |
|
|
||||||
| `/network/wifi/activate` | GET | | Activate WiFi client mode |
|
|
||||||
| `/network/wifi/add` | GET | `ssid` (optional - prepopulation value of SSID in form) | Add a WiFi network |
|
|
||||||
| `/network/wifi/add` | POST | `ssid` & `pass` | Submit form to add a WiFi network |
|
|
||||||
| `/network/wifi/connect` | POST | `ssid` | Connect to the given WiFi network |
|
|
||||||
| `/network/wifi/disconnect` | POST | `ssid` | Disconnect from currently associated WiFi network |
|
|
||||||
| `/network/wifi/forget` | POST | `ssid` | Submit form to forget a saved WiFi network |
|
|
||||||
| `/network/wifi/modify?<ssid>` | GET | `ssid` | Form for updating a WiFi network password |
|
|
||||||
| `/network/wifi/modify` | POST | `ssid` & `pass` | Submit form to update a WiFi network password |
|
|
||||||
| `/network/wifi/usage` | GET | | Network data usage values and a form to update alert thresholds |
|
|
||||||
| `/network/wifi/usage` | POST | `rx_warn`, `rx_cut`, `tx_warn`, `tx_cut`, `rx_warn_flag`, `rx_cut_flag`, `tx_warn_flag`, `tx_cut_flag` | Submit form to update alert thresholds & set flags |
|
|
||||||
| `/network/wifi/usage/reset` | GET | | Reset the stored network data usage total to zero |
|
|
||||||
| `/network/dns` | GET | | View current DNS configurations |
|
|
||||||
| `/network/dns` | POST | | Modify DNS configurations |
|
|
||||||
| `/shutdown` | GET | | Shutdown menu |
|
|
||||||
|
|
||||||
### JSON API (`src/json_api.rs`)
|
`git clone https://git.coopcloud.tech/PeachCloud/peach-workspace`
|
||||||
|
|
||||||
All JSON API calls are prefixed by `/api/v1/`. This has been excluded from the table below to keep the table compact.
|
Move into the repo and compile:
|
||||||
|
|
||||||
| Endpoint | Method | Parameters | Description |
|
`cd peach-workspace/peach-web`
|
||||||
| --- | --- | --- | --- |
|
`cargo build --release`
|
||||||
| `device/reboot` | POST | | Reboot device |
|
|
||||||
| `device/shutdown` | POST | | Shutdown device |
|
Run the tests:
|
||||||
| `network/activate_ap` | POST | | Activate WiFi access point mode |
|
|
||||||
| `network/activate_client` | POST | | Activate WiFi client mode |
|
`cargo test`
|
||||||
| `network/ip` | GET | | Returns IP address values for wlan0 & ap0 interfaces |
|
|
||||||
| `network/rssi` | GET | | Returns RSSI for connected WiFi network |
|
Move back to the `peach-workspace` directory:
|
||||||
| `network/ssid` | GET | | Returns SSID for connected WiFi network |
|
|
||||||
| `network/state` | GET | | Returns state of wlan0 & ap0 interfaces |
|
`cd ..`
|
||||||
| `network/status` | GET | | Returns status object for connected WiFi network |
|
|
||||||
| `network/wifi` | GET | | Returns scan results for in-range access-points |
|
Run the binary:
|
||||||
| `network/wifi` | POST | `ssid` & `pass` | Submit SSID & password to create new WiFi connection |
|
|
||||||
| `network/wifi/connect` | POST | `ssid` | Submit SSID to connect to a given WiFi network |
|
`./target/release/peach-web`
|
||||||
| `network/wifi/disconnect` | POST | `ssid` | Disconnect from the currently associated WiFi network |
|
|
||||||
| `network/wifi/forget` | POST | `ssid` | Submit SSID to delete credentials for given WiFi network |
|
_Note: Networking functionality requires peach-network microservice to be running._
|
||||||
| `network/wifi/modify` | POST | `ssid` & `pass` | Submit SSID & password to update the credentials for given WiFi network |
|
|
||||||
| `/network/wifi/usage` | POST | `rx_warn`, `rx_cut`, `tx_warn`, `tx_cut`, `rx_warn_flag`, `rx_cut_flag`, `tx_warn_flag`, `tx_cut_flag` | Submit form to update alert thresholds & set flags |
|
|
||||||
| `/network/wifi/usage/reset` | POST | | Reset network data usage total |
|
|
||||||
| `ping` | GET | | Returns `pong!` if `peach-web` is running |
|
|
||||||
| `ping/network` | GET | | Returns `pong!` if `peach-network` microservice is running |
|
|
||||||
| `ping/oled` | GET | | Returns `pong!` if `peach-oled` microservice is running |
|
|
||||||
| `ping/stats` | GET | | Returns `pong!` if `peach-stats` microservice is running |
|
|
||||||
| `dns/configure` | POST | | Modify dns configurations |
|
|
||||||
|
|
||||||
### Environment
|
### Environment
|
||||||
|
|
||||||
|
@ -75,13 +43,7 @@ The web application deployment mode is configured with the `ROCKET_ENV` environm
|
||||||
|
|
||||||
`export ROCKET_ENV=stage`
|
`export ROCKET_ENV=stage`
|
||||||
|
|
||||||
Other deployment modes are `dev` and `prod`. Read the [Rocket Environment Configurations docs](https://rocket.rs/v0.4/guide/configuration/#environment) for further information.
|
Other deployment modes are `dev` and `prod`. Read the [Rocket Environment Configurations docs](https://rocket.rs/v0.5-rc/guide/configuration/#environment-variables) for further information.
|
||||||
|
|
||||||
The WebSocket server port can be configured with `PEACH_WEB_WS` environment variable:
|
|
||||||
|
|
||||||
`export PEACH_WEB_WS=2333`
|
|
||||||
|
|
||||||
When not set, the value defaults to `5115`.
|
|
||||||
|
|
||||||
Logging is made available with `env_logger`:
|
Logging is made available with `env_logger`:
|
||||||
|
|
||||||
|
@ -89,27 +51,6 @@ Logging is made available with `env_logger`:
|
||||||
|
|
||||||
Other logging levels include `debug`, `warn` and `error`.
|
Other logging levels include `debug`, `warn` and `error`.
|
||||||
|
|
||||||
### Setup
|
|
||||||
|
|
||||||
Clone this repo:
|
|
||||||
|
|
||||||
`git clone https://github.com/peachcloud/peach-web.git`
|
|
||||||
|
|
||||||
Move into the repo and compile:
|
|
||||||
|
|
||||||
`cd peach-web`
|
|
||||||
`cargo build --release`
|
|
||||||
|
|
||||||
Run the tests:
|
|
||||||
|
|
||||||
`cargo test`
|
|
||||||
|
|
||||||
Run the binary:
|
|
||||||
|
|
||||||
`./target/release/peach-web`
|
|
||||||
|
|
||||||
_Note: Networking functionality requires peach-network microservice to be running._
|
|
||||||
|
|
||||||
### Debian Packaging
|
### Debian Packaging
|
||||||
|
|
||||||
A `systemd` service file and Debian maintainer scripts are included in the `debian` directory, allowing `peach-web` to be easily bundled as a Debian package (`.deb`). The `cargo-deb` [crate](https://crates.io/crates/cargo-deb) can be used to achieve this.
|
A `systemd` service file and Debian maintainer scripts are included in the `debian` directory, allowing `peach-web` to be easily bundled as a Debian package (`.deb`). The `cargo-deb` [crate](https://crates.io/crates/cargo-deb) can be used to achieve this.
|
||||||
|
@ -144,7 +85,7 @@ Remove configuration files (not removed with `apt-get remove`):
|
||||||
|
|
||||||
### Design
|
### Design
|
||||||
|
|
||||||
`peach-web` is built on the Rocket webserver and Tera templating engine. It presents a web interface for interacting with the device. HTML is rendered server-side. Request handlers call JSON-RPC microservices and serve HTML and assets. A JSON API is exposed for remote calls and dynamic client-side content updates (via vanilla JavaScript following unobstructive design principles). Each Tera template is passed a context object. In the case of Rust, this object is a `struct` and must implement `Serialize`. The fields of the context object are available in the context of the template to be rendered.
|
`peach-web` is built on the Rocket webserver and Tera templating engine. It presents a web interface for interacting with the device. HTML is rendered server-side. Request handlers call JSON-RPC microservices and serve HTML and assets. A JSON API is exposed for remote calls and dynamic client-side content updates (via plain JavaScript following unobstructive design principles). Each Tera template is passed a context object. In the case of Rust, this object is a `struct` and must implement `Serialize`. The fields of the context object are available in the context of the template to be rendered.
|
||||||
|
|
||||||
### Licensing
|
### Licensing
|
||||||
|
|
||||||
|
|
|
@ -38,100 +38,124 @@ use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
use crate::routes::authentication::*;
|
use crate::routes::authentication::*;
|
||||||
use crate::routes::catchers::*;
|
use crate::routes::catchers::*;
|
||||||
use crate::routes::device::*;
|
|
||||||
use crate::routes::index::*;
|
use crate::routes::index::*;
|
||||||
use crate::routes::ping::*;
|
|
||||||
use crate::routes::scuttlebutt::*;
|
use crate::routes::scuttlebutt::*;
|
||||||
|
use crate::routes::status::device::*;
|
||||||
|
use crate::routes::status::ping::*;
|
||||||
|
|
||||||
use crate::routes::settings::admin::*;
|
use crate::routes::settings::admin::*;
|
||||||
use crate::routes::settings::dns::*;
|
use crate::routes::settings::dns::*;
|
||||||
|
use crate::routes::settings::menu::*;
|
||||||
use crate::routes::settings::network::*;
|
use crate::routes::settings::network::*;
|
||||||
|
use crate::routes::settings::scuttlebutt::*;
|
||||||
|
|
||||||
pub type BoxError = Box<dyn std::error::Error>;
|
pub type BoxError = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
/// Create rocket instance & mount all routes.
|
/// Create rocket instance & mount all routes.
|
||||||
fn init_rocket() -> Rocket<Build> {
|
fn init_rocket() -> Rocket<Build> {
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.mount(
|
// GENERAL HTML ROUTES
|
||||||
"/scuttlebutt",
|
|
||||||
routes![
|
|
||||||
peers, // WEB ROUTE
|
|
||||||
friends, // WEB ROUTE
|
|
||||||
follows, // WEB ROUTE
|
|
||||||
followers, // WEB ROUTE
|
|
||||||
blocks, // WEB ROUTE
|
|
||||||
profile, // WEB ROUTE
|
|
||||||
private, // WEB ROUTE
|
|
||||||
follow, // WEB ROUTE
|
|
||||||
unfollow, // WEB ROUTE
|
|
||||||
block, // WEB ROUTE
|
|
||||||
publish, // WEB ROUTE
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.mount(
|
.mount(
|
||||||
"/",
|
"/",
|
||||||
routes![
|
routes![
|
||||||
add_credentials, // WEB ROUTE
|
device_status,
|
||||||
connect_wifi, // WEB ROUTE
|
help,
|
||||||
disconnect_wifi, // WEB ROUTE
|
home,
|
||||||
deploy_ap, // WEB ROUTE
|
login,
|
||||||
deploy_client, // WEB ROUTE
|
login_post,
|
||||||
device_stats, // WEB ROUTE
|
logout,
|
||||||
forget_wifi, // WEB ROUTE
|
reboot_cmd,
|
||||||
help, // WEB ROUTE
|
shutdown_cmd,
|
||||||
index, // WEB ROUTE
|
power_menu,
|
||||||
login, // WEB ROUTE
|
settings_menu,
|
||||||
login_post, // WEB ROUTE
|
],
|
||||||
logout, // WEB ROUTE
|
)
|
||||||
network_home, // WEB ROUTE
|
// ADMIN SETTINGS HTML ROUTES
|
||||||
network_add_ssid, // WEB ROUTE
|
.mount(
|
||||||
network_add_wifi, // WEB ROUTE
|
"/settings/admin",
|
||||||
network_detail, // WEB ROUTE
|
routes![
|
||||||
reboot_cmd, // WEB ROUTE
|
admin_menu,
|
||||||
shutdown_cmd, // WEB ROUTE
|
configure_admin,
|
||||||
shutdown_menu, // WEB ROUTE
|
add_admin,
|
||||||
wifi_list, // WEB ROUTE
|
add_admin_post,
|
||||||
wifi_password, // WEB ROUTE
|
delete_admin_post,
|
||||||
wifi_set_password, // WEB ROUTE
|
change_password,
|
||||||
wifi_usage, // WEB ROUTE
|
change_password_post,
|
||||||
wifi_usage_alerts, // WEB ROUTE
|
reset_password,
|
||||||
wifi_usage_reset, // WEB ROUTE
|
reset_password_post,
|
||||||
configure_dns, // WEB ROUTE
|
forgot_password_page,
|
||||||
configure_dns_post, // WEB ROUTE
|
send_password_reset_post,
|
||||||
change_password, // WEB ROUTE
|
],
|
||||||
change_password_post, // WEB ROUTE
|
)
|
||||||
reset_password, // WEB ROUTE
|
// NETWORK SETTINGS HTML ROUTES
|
||||||
reset_password_post, // WEB ROUTE
|
.mount(
|
||||||
forgot_password_page, // WEB ROUTE
|
"/settings/network",
|
||||||
send_password_reset_post, // WEB ROUTE
|
routes![
|
||||||
configure_admin, // WEB ROUTE
|
add_credentials,
|
||||||
add_admin, // WEB ROUTE
|
connect_wifi,
|
||||||
add_admin_post, // WEB ROUTE
|
configure_dns,
|
||||||
delete_admin_post, // WEB ROUTE
|
configure_dns_post,
|
||||||
activate_ap, // JSON API
|
disconnect_wifi,
|
||||||
activate_client, // JSON API
|
deploy_ap,
|
||||||
add_wifi, // JSON API
|
deploy_client,
|
||||||
connect_ap, // JSON API
|
forget_wifi,
|
||||||
disconnect_ap, // JSON API
|
network_home,
|
||||||
forget_ap, // JSON API
|
add_ssid,
|
||||||
modify_password, // JSON API
|
add_wifi,
|
||||||
ping_pong, // JSON API
|
network_detail,
|
||||||
ping_network, // JSON API
|
wifi_list,
|
||||||
ping_oled, // JSON API
|
wifi_password,
|
||||||
ping_stats, // JSON API
|
wifi_set_password,
|
||||||
reset_data_total, // JSON API
|
wifi_usage,
|
||||||
return_ip, // JSON API
|
wifi_usage_alerts,
|
||||||
return_rssi, // JSON API
|
wifi_usage_reset,
|
||||||
return_ssid, // JSON API
|
],
|
||||||
return_state, // JSON API
|
)
|
||||||
return_status, // JSON API
|
// SCUTTLEBUTT SETTINGS HTML ROUTES
|
||||||
reboot_device, // JSON API
|
.mount("/settings/scuttlebutt", routes![ssb_settings_menu])
|
||||||
scan_networks, // JSON API
|
// SCUTTLEBUTT SOCIAL HTML ROUTES
|
||||||
shutdown_device, // JSON API
|
.mount(
|
||||||
update_wifi_alerts, // JSON API
|
"/scuttlebutt",
|
||||||
save_dns_configuration_endpoint, // JSON API
|
routes![
|
||||||
save_password_form_endpoint, // JSON API
|
peers, friends, follows, followers, blocks, profile, private, follow, unfollow,
|
||||||
reset_password_form_endpoint, // JSON API
|
block, publish,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
// GENERAL JSON API ROUTES
|
||||||
|
.mount(
|
||||||
|
"/api/v1",
|
||||||
|
routes![ping_pong, ping_network, ping_oled, ping_stats,],
|
||||||
|
)
|
||||||
|
// ADMIN JSON API ROUTES
|
||||||
|
.mount(
|
||||||
|
"/api/v1/admin",
|
||||||
|
routes![
|
||||||
|
save_password_form_endpoint,
|
||||||
|
reset_password_form_endpoint,
|
||||||
|
reboot_device,
|
||||||
|
shutdown_device,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
// NETWORK JSON API ROUTES
|
||||||
|
.mount(
|
||||||
|
"/api/v1/network",
|
||||||
|
routes![
|
||||||
|
activate_ap,
|
||||||
|
activate_client,
|
||||||
|
add_wifi_credentials,
|
||||||
|
connect_ap,
|
||||||
|
disconnect_ap,
|
||||||
|
forget_ap,
|
||||||
|
modify_password,
|
||||||
|
reset_data_total,
|
||||||
|
return_ip,
|
||||||
|
return_rssi,
|
||||||
|
return_ssid,
|
||||||
|
return_state,
|
||||||
|
return_status,
|
||||||
|
scan_networks,
|
||||||
|
update_wifi_alerts,
|
||||||
|
save_dns_configuration_endpoint,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.mount("/", FileServer::from("static"))
|
.mount("/", FileServer::from("static"))
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
use log::{info};
|
use log::info;
|
||||||
use rocket::request::{FlashMessage};
|
|
||||||
use rocket::form::{Form, FromForm};
|
use rocket::form::{Form, FromForm};
|
||||||
|
use rocket::request::FlashMessage;
|
||||||
use rocket::response::{Flash, Redirect};
|
use rocket::response::{Flash, Redirect};
|
||||||
use rocket::{get, post};
|
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use rocket_dyn_templates::Template;
|
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
|
use rocket::{get, post};
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
use peach_lib::password_utils;
|
|
||||||
use peach_lib::error::PeachError;
|
use peach_lib::error::PeachError;
|
||||||
|
use peach_lib::password_utils;
|
||||||
|
|
||||||
use crate::error::PeachWebError;
|
use crate::error::PeachWebError;
|
||||||
use crate::utils::{build_json_response, TemplateOrRedirect};
|
use crate::utils::{build_json_response, TemplateOrRedirect};
|
||||||
use rocket::serde::json::Value;
|
use rocket::http::{Cookie, CookieJar, Status};
|
||||||
use rocket::request::{self, FromRequest, Request};
|
use rocket::request::{self, FromRequest, Request};
|
||||||
use rocket::http::{Cookie, CookieJar, Status};
|
use rocket::serde::json::Value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// HELPERS AND STRUCTS FOR AUTHENTICATION WITH COOKIES
|
// HELPERS AND STRUCTS FOR AUTHENTICATION WITH COOKIES
|
||||||
|
|
||||||
|
@ -32,7 +29,7 @@ pub struct Authenticated;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LoginError {
|
pub enum LoginError {
|
||||||
UserNotLoggedIn
|
UserNotLoggedIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request guard which returns an empty Authenticated struct from the request
|
/// Request guard which returns an empty Authenticated struct from the request
|
||||||
|
@ -49,14 +46,10 @@ impl<'r> FromRequest<'r> for Authenticated {
|
||||||
.cookies()
|
.cookies()
|
||||||
.get_private(AUTH_COOKIE_KEY)
|
.get_private(AUTH_COOKIE_KEY)
|
||||||
.and_then(|cookie| cookie.value().parse().ok())
|
.and_then(|cookie| cookie.value().parse().ok())
|
||||||
.map(|_value: String| { Authenticated { } });
|
.map(|_value: String| Authenticated {});
|
||||||
match authenticated {
|
match authenticated {
|
||||||
Some(auth) => {
|
Some(auth) => request::Outcome::Success(auth),
|
||||||
request::Outcome::Success(auth)
|
None => request::Outcome::Failure((Status::Forbidden, LoginError::UserNotLoggedIn)),
|
||||||
},
|
|
||||||
None => {
|
|
||||||
request::Outcome::Failure((Status::Forbidden, LoginError::UserNotLoggedIn))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +89,6 @@ pub fn login(flash: Option<FlashMessage>) -> Template {
|
||||||
Template::render("login", &context)
|
Template::render("login", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm)]
|
#[derive(Debug, Deserialize, FromForm)]
|
||||||
pub struct LoginForm {
|
pub struct LoginForm {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
@ -112,7 +104,7 @@ pub fn verify_login_form(login_form: LoginForm) -> Result<(), PeachError> {
|
||||||
password_utils::verify_password(&login_form.password)
|
password_utils::verify_password(&login_form.password)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/login", data="<login_form>")]
|
#[post("/login", data = "<login_form>")]
|
||||||
pub fn login_post(login_form: Form<LoginForm>, cookies: &CookieJar<'_>) -> TemplateOrRedirect {
|
pub fn login_post(login_form: Form<LoginForm>, cookies: &CookieJar<'_>) -> TemplateOrRedirect {
|
||||||
let result = verify_login_form(login_form.into_inner());
|
let result = verify_login_form(login_form.into_inner());
|
||||||
match result {
|
match result {
|
||||||
|
@ -138,7 +130,6 @@ pub fn login_post(login_form: Form<LoginForm>, cookies: &CookieJar<'_>) -> Templ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /logout
|
// HELPERS AND ROUTES FOR /logout
|
||||||
|
|
||||||
#[get("/logout")]
|
#[get("/logout")]
|
||||||
|
@ -149,7 +140,6 @@ pub fn logout(cookies: &CookieJar<'_>) -> Flash<Redirect> {
|
||||||
Flash::success(Redirect::to("/login"), "Logged out")
|
Flash::success(Redirect::to("/login"), "Logged out")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /reset_password
|
// HELPERS AND ROUTES FOR /reset_password
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm)]
|
#[derive(Debug, Deserialize, FromForm)]
|
||||||
|
@ -228,7 +218,7 @@ pub fn reset_password(flash: Option<FlashMessage>) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("password/reset_password", &context)
|
Template::render("settings/admin/reset_password", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Password reset form request handler. This route is used by a user who is not logged in
|
/// Password reset form request handler. This route is used by a user who is not logged in
|
||||||
|
@ -245,7 +235,7 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
|
||||||
context.flash_name = Some("success".to_string());
|
context.flash_name = Some("success".to_string());
|
||||||
let flash_msg = "New password is now saved. Return home to login".to_string();
|
let flash_msg = "New password is now saved. Return home to login".to_string();
|
||||||
context.flash_msg = Some(flash_msg);
|
context.flash_msg = Some(flash_msg);
|
||||||
Template::render("password/reset_password", &context)
|
Template::render("settings/admin/reset_password", &context)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut context = ChangePasswordContext::build();
|
let mut context = ChangePasswordContext::build();
|
||||||
|
@ -254,18 +244,15 @@ pub fn reset_password_post(reset_password_form: Form<ResetPasswordForm>) -> Temp
|
||||||
context.title = Some("Reset Password".to_string());
|
context.title = Some("Reset Password".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some(format!("Failed to reset password: {}", err));
|
context.flash_msg = Some(format!("Failed to reset password: {}", err));
|
||||||
Template::render("password/reset_password", &context)
|
Template::render("settings/admin/reset_password", &context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON password reset form request handler. This route is used by a user who is not logged in
|
/// 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.
|
/// 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("/reset_password", data = "<reset_password_form>")]
|
||||||
#[post("/public/api/v1/reset_password", data = "<reset_password_form>")]
|
pub fn reset_password_form_endpoint(reset_password_form: Json<ResetPasswordForm>) -> Value {
|
||||||
pub fn reset_password_form_endpoint(
|
|
||||||
reset_password_form: Json<ResetPasswordForm>,
|
|
||||||
) -> Value {
|
|
||||||
let result = save_reset_password_form(reset_password_form.into_inner());
|
let result = save_reset_password_form(reset_password_form.into_inner());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -316,7 +303,7 @@ pub fn forgot_password_page(flash: Option<FlashMessage>) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("password/forgot_password", &context)
|
Template::render("settings/admin/forgot_password", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send password reset request handler. This route is used by a user who is not logged in
|
/// Send password reset request handler. This route is used by a user who is not logged in
|
||||||
|
@ -335,7 +322,7 @@ pub fn send_password_reset_post() -> Template {
|
||||||
let flash_msg =
|
let flash_msg =
|
||||||
"A password reset link has been sent to the admin of this device".to_string();
|
"A password reset link has been sent to the admin of this device".to_string();
|
||||||
context.flash_msg = Some(flash_msg);
|
context.flash_msg = Some(flash_msg);
|
||||||
Template::render("password/forgot_password", &context)
|
Template::render("settings/admin/forgot_password", &context)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut context = ChangePasswordContext::build();
|
let mut context = ChangePasswordContext::build();
|
||||||
|
@ -343,7 +330,7 @@ pub fn send_password_reset_post() -> Template {
|
||||||
context.title = Some("Send Password Reset".to_string());
|
context.title = Some("Send Password Reset".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some(format!("Failed to send password reset link: {}", err));
|
context.flash_msg = Some(format!("Failed to send password reset link: {}", err));
|
||||||
Template::render("password/forgot_password", &context)
|
Template::render("settings/admin/forgot_password", &context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,11 +362,11 @@ pub fn save_password_form(password_form: PasswordForm) -> Result<(), PeachWebErr
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change password request handler. This is used by a user who is already logged in.
|
/// Change password request handler. This is used by a user who is already logged in.
|
||||||
#[get("/settings/change_password")]
|
#[get("/change_password")]
|
||||||
pub fn change_password(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn change_password(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = ChangePasswordContext::build();
|
let mut context = ChangePasswordContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/admin".to_string());
|
||||||
context.title = Some("Change Password".to_string());
|
context.title = Some("Change Password".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -387,39 +374,42 @@ pub fn change_password(flash: Option<FlashMessage>, _auth: Authenticated) -> Tem
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("password/change_password", &context)
|
Template::render("settings/admin/change_password", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change password form request handler. This route is used by a user who is already logged in.
|
/// Change password form request handler. This route is used by a user who is already logged in.
|
||||||
#[post("/settings/change_password", data = "<password_form>")]
|
#[post("/change_password", data = "<password_form>")]
|
||||||
pub fn change_password_post(password_form: Form<PasswordForm>, _auth: Authenticated) -> Template {
|
pub fn change_password_post(password_form: Form<PasswordForm>, _auth: Authenticated) -> Template {
|
||||||
let result = save_password_form(password_form.into_inner());
|
let result = save_password_form(password_form.into_inner());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut context = ChangePasswordContext::build();
|
let mut context = ChangePasswordContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/admin".to_string());
|
||||||
context.title = Some("Change Password".to_string());
|
context.title = Some("Change Password".to_string());
|
||||||
context.flash_name = Some("success".to_string());
|
context.flash_name = Some("success".to_string());
|
||||||
context.flash_msg = Some("New password is now saved".to_string());
|
context.flash_msg = Some("New password is now saved".to_string());
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("password/change_password", &context)
|
Template::render("settings/admin/change_password", &context)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut context = ChangePasswordContext::build();
|
let mut context = ChangePasswordContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/admin".to_string());
|
||||||
context.title = Some("Configure DNS".to_string());
|
context.title = Some("Configure DNS".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some(format!("Failed to save new password: {}", err));
|
context.flash_msg = Some(format!("Failed to save new password: {}", err));
|
||||||
Template::render("password/change_password", &context)
|
Template::render("settings/admin/change_password", &context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON change password form request handler.
|
/// JSON change password form request handler.
|
||||||
#[post("/api/v1/settings/change_password", data = "<password_form>")]
|
#[post("/change_password", data = "<password_form>")]
|
||||||
pub fn save_password_form_endpoint(password_form: Json<PasswordForm>, _auth: Authenticated) -> Value {
|
pub fn save_password_form_endpoint(
|
||||||
|
password_form: Json<PasswordForm>,
|
||||||
|
_auth: Authenticated,
|
||||||
|
) -> Value {
|
||||||
let result = save_password_form(password_form.into_inner());
|
let result = save_password_form(password_form.into_inner());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rocket::{catch};
|
use rocket::catch;
|
||||||
use rocket_dyn_templates::Template;
|
|
||||||
use rocket::response::Redirect;
|
use rocket::response::Redirect;
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR 404 ERROR
|
// HELPERS AND ROUTES FOR 404 ERROR
|
||||||
|
@ -34,7 +34,7 @@ pub fn not_found() -> Template {
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some("No resource found for given URL".to_string());
|
context.flash_msg = Some("No resource found for given URL".to_string());
|
||||||
|
|
||||||
Template::render("not_found", context)
|
Template::render("catchers/not_found", context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR 500 ERROR
|
// HELPERS AND ROUTES FOR 500 ERROR
|
||||||
|
@ -48,7 +48,7 @@ pub fn internal_error() -> Template {
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some("Internal server error".to_string());
|
context.flash_msg = Some("Internal server error".to_string());
|
||||||
|
|
||||||
Template::render("internal_error", context)
|
Template::render("catchers/internal_error", context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR 403 FORBIDDEN
|
// HELPERS AND ROUTES FOR 403 FORBIDDEN
|
||||||
|
@ -57,4 +57,4 @@ pub fn internal_error() -> Template {
|
||||||
pub fn forbidden() -> Redirect {
|
pub fn forbidden() -> Redirect {
|
||||||
debug!("403 Forbidden");
|
debug!("403 Forbidden");
|
||||||
Redirect::to("/login")
|
Redirect::to("/login")
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,13 @@ impl HomeContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub fn index(_auth: Authenticated) -> Template {
|
pub fn home(_auth: Authenticated) -> Template {
|
||||||
let context = HomeContext {
|
let context = HomeContext {
|
||||||
flash_name: None,
|
flash_name: None,
|
||||||
flash_msg: None,
|
flash_msg: None,
|
||||||
title: None,
|
title: None,
|
||||||
};
|
};
|
||||||
Template::render("index", &context)
|
Template::render("home", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /help
|
// HELPERS AND ROUTES FOR /help
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
pub mod authentication;
|
pub mod authentication;
|
||||||
pub mod device;
|
|
||||||
pub mod catchers;
|
pub mod catchers;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
pub mod ping;
|
|
||||||
pub mod scuttlebutt;
|
pub mod scuttlebutt;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
|
pub mod status;
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub fn private(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("messages", &context)
|
Template::render("scuttlebutt/messages", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /peers
|
// HELPERS AND ROUTES FOR /peers
|
||||||
|
@ -81,7 +81,7 @@ pub fn peers(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("peers", &context)
|
Template::render("scuttlebutt/peers", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /post/publish
|
// HELPERS AND ROUTES FOR /post/publish
|
||||||
|
@ -209,7 +209,7 @@ pub fn profile(
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("profile", &context)
|
Template::render("scuttlebutt/profile", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /friends
|
// HELPERS AND ROUTES FOR /friends
|
||||||
|
@ -247,7 +247,7 @@ pub fn friends(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("peers_list", &context)
|
Template::render("scuttlebutt/peers_list", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /follows
|
// HELPERS AND ROUTES FOR /follows
|
||||||
|
@ -285,7 +285,7 @@ pub fn follows(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("peers_list", &context)
|
Template::render("scuttlebutt/peers_list", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /followers
|
// HELPERS AND ROUTES FOR /followers
|
||||||
|
@ -323,7 +323,7 @@ pub fn followers(flash: Option<FlashMessage>, _auth: Authenticated) -> Template
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("peers_list", &context)
|
Template::render("scuttlebutt/peers_list", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /blocks
|
// HELPERS AND ROUTES FOR /blocks
|
||||||
|
@ -361,5 +361,5 @@ pub fn blocks(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("peers_list", &context)
|
Template::render("scuttlebutt/peers_list", &context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
|
form::{Form, FromForm},
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
form::{Form, FromForm},
|
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
uri,
|
uri,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -14,7 +14,44 @@ use peach_lib::config_manager::load_peach_config;
|
||||||
use crate::error::PeachWebError;
|
use crate::error::PeachWebError;
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/configure_admin
|
// HELPERS AND ROUTES FOR /settings/admin
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct AdminMenuContext {
|
||||||
|
pub back: Option<String>,
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub flash_name: Option<String>,
|
||||||
|
pub flash_msg: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AdminMenuContext {
|
||||||
|
pub fn build() -> AdminMenuContext {
|
||||||
|
AdminMenuContext {
|
||||||
|
back: None,
|
||||||
|
title: None,
|
||||||
|
flash_name: None,
|
||||||
|
flash_msg: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Administrator settings menu.
|
||||||
|
#[get("/")]
|
||||||
|
pub fn admin_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
|
let mut context = AdminMenuContext::build();
|
||||||
|
// set back icon link to settings route
|
||||||
|
context.back = Some("/settings".to_string());
|
||||||
|
context.title = Some("Administrator Settings".to_string());
|
||||||
|
// check to see if there is a flash message to display
|
||||||
|
if let Some(flash) = flash {
|
||||||
|
// add flash message contents to the context object
|
||||||
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
|
};
|
||||||
|
Template::render("settings/admin/menu", &context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HELPERS AND ROUTES FOR /settings/admin/configure
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct ConfigureAdminContext {
|
pub struct ConfigureAdminContext {
|
||||||
|
@ -40,11 +77,11 @@ impl ConfigureAdminContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View and delete currently configured admin.
|
/// View and delete currently configured admin.
|
||||||
#[get("/settings/configure_admin")]
|
#[get("/configure")]
|
||||||
pub fn configure_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn configure_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = ConfigureAdminContext::build();
|
let mut context = ConfigureAdminContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to settings route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/admin".to_string());
|
||||||
context.title = Some("Configure Admin".to_string());
|
context.title = Some("Configure Admin".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -52,7 +89,7 @@ pub fn configure_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Tem
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("admin/configure_admin", &context)
|
Template::render("settings/admin/configure_admin", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/admin/add
|
// HELPERS AND ROUTES FOR /settings/admin/add
|
||||||
|
@ -83,14 +120,14 @@ impl AddAdminContext {
|
||||||
|
|
||||||
pub fn save_add_admin_form(admin_form: AddAdminForm) -> Result<(), PeachWebError> {
|
pub fn save_add_admin_form(admin_form: AddAdminForm) -> Result<(), PeachWebError> {
|
||||||
let _result = config_manager::add_ssb_admin_id(&admin_form.ssb_id)?;
|
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
|
// if the previous line didn't throw an error then it was a success
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/settings/admin/add")]
|
#[get("/add")]
|
||||||
pub fn add_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn add_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = AddAdminContext::build();
|
let mut context = AddAdminContext::build();
|
||||||
context.back = Some("/settings/configure_admin".to_string());
|
context.back = Some("/settings/admin/configure".to_string());
|
||||||
context.title = Some("Add Admin".to_string());
|
context.title = Some("Add Admin".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -99,10 +136,10 @@ pub fn add_admin(flash: Option<FlashMessage>, _auth: Authenticated) -> Template
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("admin/add_admin", &context)
|
Template::render("settings/admin/add_admin", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/settings/admin/add", data = "<add_admin_form>")]
|
#[post("/add", data = "<add_admin_form>")]
|
||||||
pub fn add_admin_post(add_admin_form: Form<AddAdminForm>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn add_admin_post(add_admin_form: Form<AddAdminForm>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let result = save_add_admin_form(add_admin_form.into_inner());
|
let result = save_add_admin_form(add_admin_form.into_inner());
|
||||||
let url = uri!(configure_admin);
|
let url = uri!(configure_admin);
|
||||||
|
@ -119,8 +156,11 @@ pub struct DeleteAdminForm {
|
||||||
pub ssb_id: String,
|
pub ssb_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/settings/admin/delete", data = "<delete_admin_form>")]
|
#[post("/delete", data = "<delete_admin_form>")]
|
||||||
pub fn delete_admin_post(delete_admin_form: Form<DeleteAdminForm>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn delete_admin_post(
|
||||||
|
delete_admin_form: Form<DeleteAdminForm>,
|
||||||
|
_auth: Authenticated,
|
||||||
|
) -> 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);
|
||||||
let url = uri!(configure_admin);
|
let url = uri!(configure_admin);
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use log::info;
|
use log::info;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
|
form::{Form, FromForm},
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
form::{Form, FromForm}
|
serde::{
|
||||||
|
json::{Json, Value},
|
||||||
|
Deserialize, Serialize,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use rocket::serde::json::Json;
|
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -22,7 +24,6 @@ use peach_lib::jsonrpc_core::types::error::ErrorCode;
|
||||||
use crate::error::PeachWebError;
|
use crate::error::PeachWebError;
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
use crate::utils::build_json_response;
|
use crate::utils::build_json_response;
|
||||||
use rocket::serde::json::Value;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm)]
|
#[derive(Debug, Deserialize, FromForm)]
|
||||||
pub struct DnsForm {
|
pub struct DnsForm {
|
||||||
|
@ -113,11 +114,11 @@ impl ConfigureDNSContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/dns")]
|
#[get("/dns")]
|
||||||
pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = ConfigureDNSContext::build();
|
let mut context = ConfigureDNSContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("Configure DNS".to_string());
|
context.title = Some("Configure DNS".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -125,35 +126,35 @@ pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Templ
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("configure_dns", &context)
|
Template::render("settings/network/configure_dns", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/dns", data = "<dns>")]
|
#[post("/dns", data = "<dns>")]
|
||||||
pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template {
|
pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template {
|
||||||
let result = save_dns_configuration(dns.into_inner());
|
let result = save_dns_configuration(dns.into_inner());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut context = ConfigureDNSContext::build();
|
let mut context = ConfigureDNSContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("Configure DNS".to_string());
|
context.title = Some("Configure DNS".to_string());
|
||||||
context.flash_name = Some("success".to_string());
|
context.flash_name = Some("success".to_string());
|
||||||
context.flash_msg = Some("New dynamic dns configuration is now enabled".to_string());
|
context.flash_msg = Some("New dynamic dns configuration is now enabled".to_string());
|
||||||
Template::render("configure_dns", &context)
|
Template::render("settings/network/configure_dns", &context)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut context = ConfigureDNSContext::build();
|
let mut context = ConfigureDNSContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("Configure DNS".to_string());
|
context.title = Some("Configure DNS".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some(format!("Failed to save dns configurations: {}", err));
|
context.flash_msg = Some(format!("Failed to save dns configurations: {}", err));
|
||||||
Template::render("configure_dns", &context)
|
Template::render("settings/network/configure_dns", &context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/dns/configure", data = "<dns_form>")]
|
#[post("/dns/configure", data = "<dns_form>")]
|
||||||
pub fn save_dns_configuration_endpoint(dns_form: Json<DnsForm>, _auth: Authenticated) -> Value {
|
pub fn save_dns_configuration_endpoint(dns_form: Json<DnsForm>, _auth: Authenticated) -> Value {
|
||||||
let result = save_dns_configuration(dns_form.into_inner());
|
let result = save_dns_configuration(dns_form.into_inner());
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
use rocket::{get, request::FlashMessage, serde::Serialize};
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
use crate::routes::authentication::Authenticated;
|
||||||
|
|
||||||
|
// HELPERS AND ROUTES FOR /settings
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct SettingsMenuContext {
|
||||||
|
pub back: Option<String>,
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub flash_name: Option<String>,
|
||||||
|
pub flash_msg: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SettingsMenuContext {
|
||||||
|
pub fn build() -> SettingsMenuContext {
|
||||||
|
SettingsMenuContext {
|
||||||
|
back: None,
|
||||||
|
title: None,
|
||||||
|
flash_name: None,
|
||||||
|
flash_msg: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// View and delete currently configured admin.
|
||||||
|
#[get("/settings")]
|
||||||
|
pub fn settings_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
|
let mut context = SettingsMenuContext::build();
|
||||||
|
// set back icon link to network route
|
||||||
|
context.back = Some("/".to_string());
|
||||||
|
context.title = Some("Settings".to_string());
|
||||||
|
// check to see if there is a flash message to display
|
||||||
|
if let Some(flash) = flash {
|
||||||
|
// add flash message contents to the context object
|
||||||
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
|
};
|
||||||
|
Template::render("settings/menu", &context)
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
pub mod dns;
|
pub mod dns;
|
||||||
pub mod network;
|
pub mod menu;
|
||||||
|
pub mod network;
|
||||||
|
pub mod scuttlebutt;
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
|
|
||||||
use rocket::{
|
use rocket::{
|
||||||
get,
|
|
||||||
post,
|
|
||||||
request::FlashMessage,
|
|
||||||
form::{Form, FromForm},
|
form::{Form, FromForm},
|
||||||
|
get, post,
|
||||||
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
|
serde::{
|
||||||
|
json::{json, Json, Value},
|
||||||
|
Deserialize, Serialize,
|
||||||
|
},
|
||||||
uri, UriDisplayQuery,
|
uri, UriDisplayQuery,
|
||||||
};
|
};
|
||||||
use rocket::serde::json::{json, Json};
|
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use peach_lib::network_client;
|
use peach_lib::network_client;
|
||||||
use peach_lib::network_client::{AccessPoint, Networks, Scan};
|
use peach_lib::network_client::{AccessPoint, Networks, Scan};
|
||||||
use peach_lib::stats_client::Traffic;
|
use peach_lib::stats_client::Traffic;
|
||||||
|
|
||||||
|
use crate::routes::authentication::Authenticated;
|
||||||
|
use crate::utils::build_json_response;
|
||||||
use crate::utils::monitor;
|
use crate::utils::monitor;
|
||||||
use crate::utils::monitor::{Alert, Data, Threshold};
|
use crate::utils::monitor::{Alert, Data, Threshold};
|
||||||
use crate::utils::build_json_response;
|
|
||||||
use crate::routes::authentication::Authenticated;
|
|
||||||
use rocket::serde::json::Value;
|
|
||||||
|
|
||||||
// STRUCTS USED BY NETWORK ROUTES
|
// STRUCTS USED BY NETWORK ROUTES
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ pub struct WiFi {
|
||||||
pub pass: String,
|
pub pass: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/wifi/usage/reset
|
// HELPERS AND ROUTES FOR /settings/network/wifi/usage/reset
|
||||||
|
|
||||||
#[get("/network/wifi/usage/reset")]
|
#[get("/wifi/usage/reset")]
|
||||||
pub fn wifi_usage_reset(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn wifi_usage_reset(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
let url = uri!(wifi_usage);
|
let url = uri!(wifi_usage);
|
||||||
match monitor::reset_data() {
|
match monitor::reset_data() {
|
||||||
|
@ -50,7 +50,7 @@ pub fn wifi_usage_reset(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/connect", data = "<network>")]
|
#[post("/wifi/connect", data = "<network>")]
|
||||||
pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_detail(ssid = ssid));
|
let url = uri!(network_detail(ssid = ssid));
|
||||||
|
@ -63,7 +63,7 @@ pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/disconnect", data = "<network>")]
|
#[post("/wifi/disconnect", data = "<network>")]
|
||||||
pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_home);
|
let url = uri!(network_home);
|
||||||
|
@ -73,7 +73,7 @@ pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/forget", data = "<network>")]
|
#[post("/wifi/forget", data = "<network>")]
|
||||||
pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_home);
|
let url = uri!(network_home);
|
||||||
|
@ -86,10 +86,10 @@ pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/wifi/modify?<ssid>")]
|
#[get("/wifi/modify?<ssid>")]
|
||||||
pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAddContext {
|
let mut context = NetworkAddContext {
|
||||||
back: Some("/network/wifi".to_string()),
|
back: Some("/settings/network/wifi".to_string()),
|
||||||
flash_name: None,
|
flash_name: None,
|
||||||
flash_msg: None,
|
flash_msg: None,
|
||||||
selected: Some(ssid.to_string()),
|
selected: Some(ssid.to_string()),
|
||||||
|
@ -102,10 +102,10 @@ pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticat
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_modify", &context)
|
Template::render("settings/network/network_modify", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/modify", data = "<wifi>")]
|
#[post("/wifi/modify", data = "<wifi>")]
|
||||||
pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &wifi.ssid;
|
let ssid = &wifi.ssid;
|
||||||
let pass = &wifi.pass;
|
let pass = &wifi.pass;
|
||||||
|
@ -119,7 +119,7 @@ pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redire
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network
|
// HELPERS AND ROUTES FOR /settings/network
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct NetworkContext {
|
pub struct NetworkContext {
|
||||||
|
@ -273,12 +273,12 @@ impl NetworkContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network")]
|
#[get("/")]
|
||||||
pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context through context_builder call
|
||||||
let mut context = NetworkContext::build();
|
let mut context = NetworkContext::build();
|
||||||
// set back button (nav) url
|
// set back button (nav) url
|
||||||
context.back = Some("/".to_string());
|
context.back = Some("/settings".to_string());
|
||||||
// set page title
|
// set page title
|
||||||
context.title = Some("Network Configuration".to_string());
|
context.title = Some("Network Configuration".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
|
@ -288,25 +288,28 @@ pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Templa
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_card", &context)
|
Template::render("settings/network/network_card", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/ap/activate
|
// HELPERS AND ROUTES FOR /settings/network/ap/activate
|
||||||
|
|
||||||
#[get("/network/ap/activate")]
|
#[get("/ap/activate")]
|
||||||
pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
// activate the wireless access point
|
// activate the wireless access point
|
||||||
debug!("Activating WiFi access point.");
|
debug!("Activating WiFi access point.");
|
||||||
match network_client::activate_ap() {
|
match network_client::activate_ap() {
|
||||||
Ok(_) => Flash::success(Redirect::to("/network"), "Activated WiFi access point"),
|
Ok(_) => Flash::success(
|
||||||
|
Redirect::to("/settings/network"),
|
||||||
|
"Activated WiFi access point",
|
||||||
|
),
|
||||||
Err(_) => Flash::error(
|
Err(_) => Flash::error(
|
||||||
Redirect::to("/network"),
|
Redirect::to("/settings/network"),
|
||||||
"Failed to activate WiFi access point",
|
"Failed to activate WiFi access point",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/wifi
|
// HELPERS AND ROUTES FOR /settings/network/wifi
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct NetworkListContext {
|
pub struct NetworkListContext {
|
||||||
|
@ -375,11 +378,11 @@ impl NetworkListContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/wifi")]
|
#[get("/wifi")]
|
||||||
pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context through context_builder call
|
||||||
let mut context = NetworkListContext::build();
|
let mut context = NetworkListContext::build();
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("WiFi Networks".to_string());
|
context.title = Some("WiFi Networks".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -388,10 +391,10 @@ pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_list", &context)
|
Template::render("settings/network/network_list", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/wifi<ssid>
|
// HELPERS AND ROUTES FOR /settings/network/wifi<ssid>
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct NetworkDetailContext {
|
pub struct NetworkDetailContext {
|
||||||
|
@ -540,11 +543,11 @@ impl NetworkDetailContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/wifi?<ssid>")]
|
#[get("/wifi?<ssid>")]
|
||||||
pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context through context_builder call
|
||||||
let mut context = NetworkDetailContext::build();
|
let mut context = NetworkDetailContext::build();
|
||||||
context.back = Some("/network/wifi".to_string());
|
context.back = Some("/settings/network/wifi".to_string());
|
||||||
context.title = Some("WiFi Network".to_string());
|
context.title = Some("WiFi Network".to_string());
|
||||||
context.selected = Some(ssid.to_string());
|
context.selected = Some(ssid.to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
|
@ -554,28 +557,31 @@ pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authentica
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_detail", &context)
|
Template::render("settings/network/network_detail", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/wifi/activate
|
// HELPERS AND ROUTES FOR /settings/network/wifi/activate
|
||||||
|
|
||||||
#[get("/network/wifi/activate")]
|
#[get("/wifi/activate")]
|
||||||
pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
// activate the wireless client
|
// activate the wireless client
|
||||||
debug!("Activating WiFi client mode.");
|
debug!("Activating WiFi client mode.");
|
||||||
match network_client::activate_client() {
|
match network_client::activate_client() {
|
||||||
Ok(_) => Flash::success(Redirect::to("/network"), "Activated WiFi client"),
|
Ok(_) => Flash::success(Redirect::to("/settings/network"), "Activated WiFi client"),
|
||||||
Err(_) => Flash::error(Redirect::to("/network"), "Failed to activate WiFi client"),
|
Err(_) => Flash::error(
|
||||||
|
Redirect::to("/settings/network"),
|
||||||
|
"Failed to activate WiFi client",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /network/wifi/add
|
// HELPERS AND ROUTES FOR /settings/network/wifi/add
|
||||||
|
|
||||||
#[get("/network/wifi/add")]
|
#[get("/wifi/add")]
|
||||||
pub fn network_add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkContext::build();
|
let mut context = NetworkContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.title = Some("Add WiFi Network".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -584,10 +590,10 @@ pub fn network_add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Te
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_add", &context)
|
Template::render("settings/network/network_add", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// used in /network/wifi/add?<ssid>
|
// used in /settings/network/wifi/add?<ssid>
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct NetworkAddContext {
|
pub struct NetworkAddContext {
|
||||||
pub back: Option<String>,
|
pub back: Option<String>,
|
||||||
|
@ -609,10 +615,10 @@ impl NetworkAddContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/wifi/add?<ssid>")]
|
#[get("/wifi/add?<ssid>")]
|
||||||
pub fn network_add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAddContext::build();
|
let mut context = NetworkAddContext::build();
|
||||||
context.back = Some("/network/wifi".to_string());
|
context.back = Some("/settings/network/wifi".to_string());
|
||||||
context.selected = Some(ssid.to_string());
|
context.selected = Some(ssid.to_string());
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.title = Some("Add WiFi Network".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
|
@ -622,10 +628,10 @@ pub fn network_add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenti
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_add", &context)
|
Template::render("settings/network/network_add", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/add", data = "<wifi>")]
|
#[post("/wifi/add", data = "<wifi>")]
|
||||||
pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
||||||
// check if the credentials already exist for this access point
|
// check if the credentials already exist for this access point
|
||||||
// note: this is nicer but it's an unstable feature:
|
// note: this is nicer but it's an unstable feature:
|
||||||
|
@ -634,13 +640,13 @@ pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
||||||
let creds_exist = network_client::saved_ap(&wifi.ssid).unwrap_or(false);
|
let creds_exist = network_client::saved_ap(&wifi.ssid).unwrap_or(false);
|
||||||
if creds_exist {
|
if creds_exist {
|
||||||
let mut context = NetworkAddContext::build();
|
let mut context = NetworkAddContext::build();
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg =
|
context.flash_msg =
|
||||||
Some("Network credentials already exist for this access point".to_string());
|
Some("Network credentials already exist for this access point".to_string());
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.title = Some("Add WiFi Network".to_string());
|
||||||
// return early from handler with "creds already exist" message
|
// return early from handler with "creds already exist" message
|
||||||
return Template::render("network_add", &context);
|
return Template::render("settings/network/network_add", &context);
|
||||||
};
|
};
|
||||||
|
|
||||||
// if credentials not found, generate and write wifi config to wpa_supplicant
|
// if credentials not found, generate and write wifi config to wpa_supplicant
|
||||||
|
@ -653,20 +659,20 @@ pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
||||||
Err(_) => warn!("Failed to reconfigure wpa_supplicant"),
|
Err(_) => warn!("Failed to reconfigure wpa_supplicant"),
|
||||||
}
|
}
|
||||||
let mut context = NetworkAddContext::build();
|
let mut context = NetworkAddContext::build();
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.flash_name = Some("success".to_string());
|
context.flash_name = Some("success".to_string());
|
||||||
context.flash_msg = Some("Added WiFi credentials".to_string());
|
context.flash_msg = Some("Added WiFi credentials".to_string());
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.title = Some("Add WiFi Network".to_string());
|
||||||
Template::render("network_add", &context)
|
Template::render("settings/network/network_add", &context)
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
debug!("Failed to add WiFi credentials.");
|
debug!("Failed to add WiFi credentials.");
|
||||||
let mut context = NetworkAddContext::build();
|
let mut context = NetworkAddContext::build();
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some("Failed to add WiFi credentials".to_string());
|
context.flash_msg = Some("Failed to add WiFi credentials".to_string());
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.title = Some("Add WiFi Network".to_string());
|
||||||
Template::render("network_add", &context)
|
Template::render("settings/network/network_add", &context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,11 +725,11 @@ impl NetworkAlertContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/network/wifi/usage")]
|
#[get("/wifi/usage")]
|
||||||
pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAlertContext::build();
|
let mut context = NetworkAlertContext::build();
|
||||||
// set back icon link to network route
|
// set back icon link to network route
|
||||||
context.back = Some("/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("Network Data Usage".to_string());
|
context.title = Some("Network Data Usage".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
|
@ -732,30 +738,32 @@ pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("network_usage", &context)
|
Template::render("settings/network/network_usage", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/network/wifi/usage", data = "<thresholds>")]
|
#[post("/wifi/usage", data = "<thresholds>")]
|
||||||
pub fn wifi_usage_alerts(thresholds: Form<Threshold>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn wifi_usage_alerts(thresholds: Form<Threshold>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
match monitor::update_store(thresholds.into_inner()) {
|
match monitor::update_store(thresholds.into_inner()) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
debug!("WiFi data usage thresholds updated.");
|
debug!("WiFi data usage thresholds updated.");
|
||||||
Flash::success(
|
Flash::success(
|
||||||
Redirect::to("/network/wifi/usage"),
|
Redirect::to("/settings/network/wifi/usage"),
|
||||||
"Updated alert thresholds and flags",
|
"Updated alert thresholds and flags",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
warn!("Failed to update WiFi data usage thresholds.");
|
warn!("Failed to update WiFi data usage thresholds.");
|
||||||
Flash::error(
|
Flash::error(
|
||||||
Redirect::to("/network/wifi/usage"),
|
Redirect::to("/settings/network/wifi/usage"),
|
||||||
"Failed to update alert thresholds and flags",
|
"Failed to update alert thresholds and flags",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/usage", data = "<thresholds>")]
|
// JSON ROUTES FOR NETWORK SETTINGS
|
||||||
|
|
||||||
|
#[post("/wifi/usage", data = "<thresholds>")]
|
||||||
pub fn update_wifi_alerts(thresholds: Json<Threshold>, _auth: Authenticated) -> Value {
|
pub fn update_wifi_alerts(thresholds: Json<Threshold>, _auth: Authenticated) -> Value {
|
||||||
match monitor::update_store(thresholds.into_inner()) {
|
match monitor::update_store(thresholds.into_inner()) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -773,7 +781,7 @@ pub fn update_wifi_alerts(thresholds: Json<Threshold>, _auth: Authenticated) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/usage/reset")]
|
#[post("/wifi/usage/reset")]
|
||||||
pub fn reset_data_total(_auth: Authenticated) -> Value {
|
pub fn reset_data_total(_auth: Authenticated) -> Value {
|
||||||
match monitor::reset_data() {
|
match monitor::reset_data() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -805,7 +813,7 @@ pub fn reset_data_total(_auth: Authenticated) -> Value {
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR ACCESS POINT ACTIVATION
|
// HELPERS AND ROUTES FOR ACCESS POINT ACTIVATION
|
||||||
|
|
||||||
#[post("/api/v1/network/activate_ap")]
|
#[post("/activate_ap")]
|
||||||
pub fn activate_ap(_auth: Authenticated) -> Value {
|
pub fn activate_ap(_auth: Authenticated) -> Value {
|
||||||
// activate the wireless access point
|
// activate the wireless access point
|
||||||
debug!("Activating WiFi access point.");
|
debug!("Activating WiFi access point.");
|
||||||
|
@ -824,7 +832,7 @@ pub fn activate_ap(_auth: Authenticated) -> Value {
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR WIFI CLIENT MANAGEMENT
|
// HELPERS AND ROUTES FOR WIFI CLIENT MANAGEMENT
|
||||||
|
|
||||||
#[post("/api/v1/network/activate_client")]
|
#[post("/activate_client")]
|
||||||
pub fn activate_client(_auth: Authenticated) -> Value {
|
pub fn activate_client(_auth: Authenticated) -> Value {
|
||||||
// activate the wireless client
|
// activate the wireless client
|
||||||
debug!("Activating WiFi client mode.");
|
debug!("Activating WiFi client mode.");
|
||||||
|
@ -841,8 +849,8 @@ pub fn activate_client(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi", data = "<wifi>")]
|
#[post("/wifi", data = "<wifi>")]
|
||||||
pub fn add_wifi(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
pub fn add_wifi_credentials(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
||||||
// generate and write wifi config to wpa_supplicant
|
// generate and write wifi config to wpa_supplicant
|
||||||
match network_client::add(&wifi.ssid, &wifi.pass) {
|
match network_client::add(&wifi.ssid, &wifi.pass) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -867,7 +875,7 @@ pub fn add_wifi(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/connect", data = "<ssid>")]
|
#[post("/wifi/connect", data = "<ssid>")]
|
||||||
pub fn connect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
pub fn connect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
// retrieve the id for the given network ssid
|
// retrieve the id for the given network ssid
|
||||||
match network_client::id("wlan0", &ssid.ssid) {
|
match network_client::id("wlan0", &ssid.ssid) {
|
||||||
|
@ -892,7 +900,7 @@ pub fn connect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/disconnect", data = "<ssid>")]
|
#[post("/wifi/disconnect", data = "<ssid>")]
|
||||||
pub fn disconnect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
pub fn disconnect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
// attempt to disable the current network for wlan0 interface
|
// attempt to disable the current network for wlan0 interface
|
||||||
match network_client::disable("wlan0", &ssid.ssid) {
|
match network_client::disable("wlan0", &ssid.ssid) {
|
||||||
|
@ -909,7 +917,7 @@ pub fn disconnect_ap(ssid: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/forget", data = "<network>")]
|
#[post("/wifi/forget", data = "<network>")]
|
||||||
pub fn forget_ap(network: Json<Ssid>, _auth: Authenticated) -> Value {
|
pub fn forget_ap(network: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
match network_client::forget("wlan0", ssid) {
|
match network_client::forget("wlan0", ssid) {
|
||||||
|
@ -928,7 +936,7 @@ pub fn forget_ap(network: Json<Ssid>, _auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/api/v1/network/wifi/modify", data = "<wifi>")]
|
#[post("/wifi/modify", data = "<wifi>")]
|
||||||
pub fn modify_password(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
pub fn modify_password(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
||||||
let ssid = &wifi.ssid;
|
let ssid = &wifi.ssid;
|
||||||
let pass = &wifi.pass;
|
let pass = &wifi.pass;
|
||||||
|
@ -953,7 +961,7 @@ pub fn modify_password(wifi: Json<WiFi>, _auth: Authenticated) -> Value {
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR NETWORK STATE QUERIES
|
// HELPERS AND ROUTES FOR NETWORK STATE QUERIES
|
||||||
|
|
||||||
#[get("/api/v1/network/ip")]
|
#[get("/ip")]
|
||||||
pub fn return_ip(_auth: Authenticated) -> Value {
|
pub fn return_ip(_auth: Authenticated) -> Value {
|
||||||
// retrieve ip for wlan0 or set to x.x.x.x if not found
|
// retrieve ip for wlan0 or set to x.x.x.x if not found
|
||||||
let wlan_ip = match network_client::ip("wlan0") {
|
let wlan_ip = match network_client::ip("wlan0") {
|
||||||
|
@ -973,7 +981,7 @@ pub fn return_ip(_auth: Authenticated) -> Value {
|
||||||
build_json_response(status, Some(data), None)
|
build_json_response(status, Some(data), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/api/v1/network/rssi")]
|
#[get("/rssi")]
|
||||||
pub fn return_rssi(_auth: Authenticated) -> Value {
|
pub fn return_rssi(_auth: Authenticated) -> Value {
|
||||||
// retrieve rssi for connected network
|
// retrieve rssi for connected network
|
||||||
match network_client::rssi("wlan0") {
|
match network_client::rssi("wlan0") {
|
||||||
|
@ -990,7 +998,7 @@ pub fn return_rssi(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/api/v1/network/ssid")]
|
#[get("/ssid")]
|
||||||
pub fn return_ssid(_auth: Authenticated) -> Value {
|
pub fn return_ssid(_auth: Authenticated) -> Value {
|
||||||
// retrieve ssid for connected network
|
// retrieve ssid for connected network
|
||||||
match network_client::ssid("wlan0") {
|
match network_client::ssid("wlan0") {
|
||||||
|
@ -1007,7 +1015,7 @@ pub fn return_ssid(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/api/v1/network/state")]
|
#[get("/state")]
|
||||||
pub fn return_state(_auth: Authenticated) -> Value {
|
pub fn return_state(_auth: Authenticated) -> Value {
|
||||||
// retrieve state of wlan0 or set to x.x.x.x if not found
|
// retrieve state of wlan0 or set to x.x.x.x if not found
|
||||||
let wlan_state = match network_client::state("wlan0") {
|
let wlan_state = match network_client::state("wlan0") {
|
||||||
|
@ -1027,7 +1035,7 @@ pub fn return_state(_auth: Authenticated) -> Value {
|
||||||
build_json_response(status, Some(data), None)
|
build_json_response(status, Some(data), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/api/v1/network/status")]
|
#[get("/status")]
|
||||||
pub fn return_status(_auth: Authenticated) -> Value {
|
pub fn return_status(_auth: Authenticated) -> Value {
|
||||||
// retrieve status info for wlan0 interface
|
// retrieve status info for wlan0 interface
|
||||||
match network_client::status("wlan0") {
|
match network_client::status("wlan0") {
|
||||||
|
@ -1044,7 +1052,7 @@ pub fn return_status(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/api/v1/network/wifi")]
|
#[get("/wifi")]
|
||||||
pub fn scan_networks(_auth: Authenticated) -> Value {
|
pub fn scan_networks(_auth: Authenticated) -> Value {
|
||||||
// retrieve scan results for access-points within range of wlan0
|
// retrieve scan results for access-points within range of wlan0
|
||||||
match network_client::available_networks("wlan0") {
|
match network_client::available_networks("wlan0") {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
use rocket::{get, request::FlashMessage, serde::Serialize};
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
use crate::routes::authentication::Authenticated;
|
||||||
|
|
||||||
|
// HELPERS AND ROUTES FOR /settings/scuttlebutt
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct ScuttlebuttSettingsContext {
|
||||||
|
pub back: Option<String>,
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub flash_name: Option<String>,
|
||||||
|
pub flash_msg: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScuttlebuttSettingsContext {
|
||||||
|
pub fn build() -> ScuttlebuttSettingsContext {
|
||||||
|
ScuttlebuttSettingsContext {
|
||||||
|
back: None,
|
||||||
|
title: None,
|
||||||
|
flash_name: None,
|
||||||
|
flash_msg: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scuttlebutt settings menu.
|
||||||
|
#[get("/")]
|
||||||
|
pub fn ssb_settings_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
|
let mut context = ScuttlebuttSettingsContext::build();
|
||||||
|
// set back icon link to network route
|
||||||
|
context.back = Some("/settings".to_string());
|
||||||
|
context.title = Some("Scuttlebutt Settings".to_string());
|
||||||
|
// check to see if there is a flash message to display
|
||||||
|
if let Some(flash) = flash {
|
||||||
|
// add flash message contents to the context object
|
||||||
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
|
};
|
||||||
|
Template::render("settings/scuttlebutt", &context)
|
||||||
|
}
|
|
@ -16,15 +16,15 @@ use peach_lib::config_manager::load_peach_config;
|
||||||
use peach_lib::stats_client::{CpuStatPercentages, DiskUsage, LoadAverage, MemStat};
|
use peach_lib::stats_client::{CpuStatPercentages, DiskUsage, LoadAverage, MemStat};
|
||||||
use peach_lib::{dyndns_client, network_client, oled_client, sbot_client, stats_client};
|
use peach_lib::{dyndns_client, network_client, oled_client, sbot_client, stats_client};
|
||||||
|
|
||||||
use crate::utils::build_json_response;
|
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
|
use crate::utils::build_json_response;
|
||||||
use rocket::serde::json::Value;
|
use rocket::serde::json::Value;
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /device
|
// HELPERS AND ROUTES FOR /status
|
||||||
|
|
||||||
/// System statistics data.
|
/// System statistics data.
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct DeviceContext {
|
pub struct StatusContext {
|
||||||
pub back: Option<String>,
|
pub back: Option<String>,
|
||||||
pub cpu_stat_percent: Option<CpuStatPercentages>,
|
pub cpu_stat_percent: Option<CpuStatPercentages>,
|
||||||
pub disk_stats: Vec<DiskUsage>,
|
pub disk_stats: Vec<DiskUsage>,
|
||||||
|
@ -43,8 +43,8 @@ pub struct DeviceContext {
|
||||||
pub uptime: Option<i32>,
|
pub uptime: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceContext {
|
impl StatusContext {
|
||||||
pub fn build() -> DeviceContext {
|
pub fn build() -> StatusContext {
|
||||||
// convert result to Option<CpuStatPercentages>, discard any error
|
// convert result to Option<CpuStatPercentages>, discard any error
|
||||||
let cpu_stat_percent = stats_client::cpu_stats_percent().ok();
|
let cpu_stat_percent = stats_client::cpu_stats_percent().ok();
|
||||||
let load_average = stats_client::load_average().ok();
|
let load_average = stats_client::load_average().ok();
|
||||||
|
@ -129,7 +129,7 @@ impl DeviceContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceContext {
|
StatusContext {
|
||||||
back: None,
|
back: None,
|
||||||
cpu_stat_percent,
|
cpu_stat_percent,
|
||||||
disk_stats,
|
disk_stats,
|
||||||
|
@ -150,10 +150,10 @@ impl DeviceContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/device")]
|
#[get("/status")]
|
||||||
pub fn device_stats(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn device_status(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context through context_builder call
|
||||||
let mut context = DeviceContext::build();
|
let mut context = StatusContext::build();
|
||||||
context.back = Some("/".to_string());
|
context.back = Some("/".to_string());
|
||||||
context.title = Some("Device Status".to_string());
|
context.title = Some("Device Status".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
|
@ -166,7 +166,7 @@ pub fn device_stats(flash: Option<FlashMessage>, _auth: Authenticated) -> Templa
|
||||||
Template::render("device", &context)
|
Template::render("device", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /device/reboot
|
// HELPERS AND ROUTES FOR /power/reboot
|
||||||
|
|
||||||
/// Executes a system command to reboot the device immediately.
|
/// Executes a system command to reboot the device immediately.
|
||||||
pub fn reboot() -> io::Result<Output> {
|
pub fn reboot() -> io::Result<Output> {
|
||||||
|
@ -181,16 +181,16 @@ pub fn reboot() -> io::Result<Output> {
|
||||||
.output()
|
.output()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/device/reboot")]
|
#[get("/power/reboot")]
|
||||||
pub fn reboot_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn reboot_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
match reboot() {
|
match reboot() {
|
||||||
Ok(_) => Flash::success(Redirect::to("/shutdown"), "Rebooting the device"),
|
Ok(_) => Flash::success(Redirect::to("/power"), "Rebooting the device"),
|
||||||
Err(_) => Flash::error(Redirect::to("/shutdown"), "Failed to reboot the device"),
|
Err(_) => Flash::error(Redirect::to("/power"), "Failed to reboot the device"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSON request handler for device reboot.
|
/// JSON request handler for device reboot.
|
||||||
#[post("/api/v1/device/reboot")]
|
#[post("/api/v1/admin/reboot")]
|
||||||
pub fn reboot_device(_auth: Authenticated) -> Value {
|
pub fn reboot_device(_auth: Authenticated) -> Value {
|
||||||
match reboot() {
|
match reboot() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -208,7 +208,7 @@ pub fn reboot_device(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /device/shutdown
|
// HELPERS AND ROUTES FOR /power/shutdown
|
||||||
|
|
||||||
/// Executes a system command to shutdown the device immediately.
|
/// Executes a system command to shutdown the device immediately.
|
||||||
pub fn shutdown() -> io::Result<Output> {
|
pub fn shutdown() -> io::Result<Output> {
|
||||||
|
@ -219,16 +219,16 @@ pub fn shutdown() -> io::Result<Output> {
|
||||||
Command::new("sudo").arg("shutdown").arg("now").output()
|
Command::new("sudo").arg("shutdown").arg("now").output()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/device/shutdown")]
|
#[get("/power/shutdown")]
|
||||||
pub fn shutdown_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn shutdown_cmd(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
match shutdown() {
|
match shutdown() {
|
||||||
Ok(_) => Flash::success(Redirect::to("/shutdown"), "Shutting down the device"),
|
Ok(_) => Flash::success(Redirect::to("/power"), "Shutting down the device"),
|
||||||
Err(_) => Flash::error(Redirect::to("/shutdown"), "Failed to shutdown the device"),
|
Err(_) => Flash::error(Redirect::to("/power"), "Failed to shutdown the device"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown the device
|
// shutdown the device
|
||||||
#[post("/api/v1/device/shutdown")]
|
#[post("/power/shutdown")]
|
||||||
pub fn shutdown_device(_auth: Authenticated) -> Value {
|
pub fn shutdown_device(_auth: Authenticated) -> Value {
|
||||||
match shutdown() {
|
match shutdown() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -246,19 +246,19 @@ pub fn shutdown_device(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /shutdown
|
// HELPERS AND ROUTES FOR /power
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct ShutdownContext {
|
pub struct PowerContext {
|
||||||
pub back: Option<String>,
|
pub back: Option<String>,
|
||||||
pub flash_name: Option<String>,
|
pub flash_name: Option<String>,
|
||||||
pub flash_msg: Option<String>,
|
pub flash_msg: Option<String>,
|
||||||
pub title: Option<String>,
|
pub title: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShutdownContext {
|
impl PowerContext {
|
||||||
pub fn build() -> ShutdownContext {
|
pub fn build() -> PowerContext {
|
||||||
ShutdownContext {
|
PowerContext {
|
||||||
back: None,
|
back: None,
|
||||||
flash_name: None,
|
flash_name: None,
|
||||||
flash_msg: None,
|
flash_msg: None,
|
||||||
|
@ -267,16 +267,16 @@ impl ShutdownContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/shutdown")]
|
#[get("/power")]
|
||||||
pub fn shutdown_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn power_menu(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = ShutdownContext::build();
|
let mut context = PowerContext::build();
|
||||||
context.back = Some("/".to_string());
|
context.back = Some("/".to_string());
|
||||||
context.title = Some("Shutdown Device".to_string());
|
context.title = Some("Power Menu".to_string());
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
Template::render("shutdown", &context)
|
Template::render("power", &context)
|
||||||
}
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod device;
|
||||||
|
pub mod ping;
|
|
@ -1,19 +1,19 @@
|
||||||
//! Helper routes for pinging services to check that they are active
|
//! Helper routes for pinging services to check that they are active
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use rocket::get;
|
use rocket::get;
|
||||||
use rocket::serde::json::{Value};
|
use rocket::serde::json::Value;
|
||||||
|
|
||||||
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;
|
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
|
use crate::utils::build_json_response;
|
||||||
|
|
||||||
/// Status route: useful for checking connectivity from web client.
|
/// Status route: useful for checking connectivity from web client.
|
||||||
#[get("/api/v1/ping")]
|
#[get("/ping")]
|
||||||
pub fn ping_pong(_auth: Authenticated) -> Value {
|
pub fn ping_pong(_auth: Authenticated) -> Value {
|
||||||
//pub fn ping_pong() -> Value {
|
//pub fn ping_pong() -> Value {
|
||||||
// ping pong
|
// ping pong
|
||||||
let status = "success".to_string();
|
let status = "success".to_string();
|
||||||
let msg = "pong!".to_string();
|
let msg = "pong!".to_string();
|
||||||
|
@ -21,7 +21,7 @@ pub fn ping_pong(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Status route: check availability of `peach-network` microservice.
|
/// Status route: check availability of `peach-network` microservice.
|
||||||
#[get("/api/v1/ping/network")]
|
#[get("/ping/network")]
|
||||||
pub fn ping_network(_auth: Authenticated) -> Value {
|
pub fn ping_network(_auth: Authenticated) -> Value {
|
||||||
match network_client::ping() {
|
match network_client::ping() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -40,7 +40,7 @@ pub fn ping_network(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Status route: check availability of `peach-oled` microservice.
|
/// Status route: check availability of `peach-oled` microservice.
|
||||||
#[get("/api/v1/ping/oled")]
|
#[get("/ping/oled")]
|
||||||
pub fn ping_oled(_auth: Authenticated) -> Value {
|
pub fn ping_oled(_auth: Authenticated) -> Value {
|
||||||
match oled_client::ping() {
|
match oled_client::ping() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -59,7 +59,7 @@ pub fn ping_oled(_auth: Authenticated) -> Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Status route: check availability of `peach-stats` microservice.
|
/// Status route: check availability of `peach-stats` microservice.
|
||||||
#[get("/api/v1/ping/stats")]
|
#[get("/ping/stats")]
|
||||||
pub fn ping_stats(_auth: Authenticated) -> Value {
|
pub fn ping_stats(_auth: Authenticated) -> Value {
|
||||||
match stats_client::ping() {
|
match stats_client::ping() {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
|
@ -47,15 +47,15 @@ fn index_html() {
|
||||||
assert!(body.contains("/peers"));
|
assert!(body.contains("/peers"));
|
||||||
assert!(body.contains("/profile"));
|
assert!(body.contains("/profile"));
|
||||||
assert!(body.contains("/private"));
|
assert!(body.contains("/private"));
|
||||||
assert!(body.contains("/device"));
|
assert!(body.contains("/status"));
|
||||||
assert!(body.contains("/help"));
|
assert!(body.contains("/help"));
|
||||||
assert!(body.contains("/network"));
|
assert!(body.contains("/settings"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn network_card_html() {
|
fn network_card_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network").dispatch();
|
let response = client.get("/settings/network").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -73,7 +73,7 @@ fn network_card_html() {
|
||||||
#[test]
|
#[test]
|
||||||
fn network_list_html() {
|
fn network_list_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi").dispatch();
|
let response = client.get("/settings/network/wifi").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -85,7 +85,7 @@ fn network_list_html() {
|
||||||
#[test]
|
#[test]
|
||||||
fn network_detail_html() {
|
fn network_detail_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi?ssid=Home").dispatch();
|
let response = client.get("/settings/network/wifi?ssid=Home").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
//let body = response.into_string().unwrap();
|
//let body = response.into_string().unwrap();
|
||||||
|
@ -95,7 +95,7 @@ fn network_detail_html() {
|
||||||
#[test]
|
#[test]
|
||||||
fn network_add_html() {
|
fn network_add_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi/add").dispatch();
|
let response = client.get("/settings/network/wifi/add").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -109,7 +109,9 @@ fn network_add_html() {
|
||||||
#[test]
|
#[test]
|
||||||
fn network_add_ssid_html() {
|
fn network_add_ssid_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi/add?ssid=Home").dispatch();
|
let response = client
|
||||||
|
.get("/settings/network/wifi/add?ssid=Home")
|
||||||
|
.dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -121,9 +123,9 @@ fn network_add_ssid_html() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn device_html() {
|
fn status_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/device").dispatch();
|
let response = client.get("/status").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -269,9 +271,9 @@ fn profile_html() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn shutdown_html() {
|
fn power_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/shutdown").dispatch();
|
let response = client.get("/power").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -281,7 +283,7 @@ fn shutdown_html() {
|
||||||
#[test]
|
#[test]
|
||||||
fn network_usage_html() {
|
fn network_usage_html() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi/usage").dispatch();
|
let response = client.get("/settings/network/wifi/usage").dispatch();
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
assert_eq!(response.content_type(), Some(ContentType::HTML));
|
||||||
let body = response.into_string().unwrap();
|
let body = response.into_string().unwrap();
|
||||||
|
@ -295,7 +297,7 @@ fn network_usage_html() {
|
||||||
fn add_credentials() {
|
fn add_credentials() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client
|
let response = client
|
||||||
.post("/network/wifi/add")
|
.post("/settings/network/wifi/add")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("ssid=Home&pass=Password")
|
.body("ssid=Home&pass=Password")
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
@ -307,7 +309,7 @@ fn add_credentials() {
|
||||||
fn forget_wifi() {
|
fn forget_wifi() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client
|
let response = client
|
||||||
.post("/network/wifi/forget")
|
.post("/settings/network/wifi/forget")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("ssid=Home")
|
.body("ssid=Home")
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
@ -319,7 +321,7 @@ fn forget_wifi() {
|
||||||
fn modify_password() {
|
fn modify_password() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client
|
let response = client
|
||||||
.post("/network/wifi/modify")
|
.post("/settings/network/wifi/modify")
|
||||||
.header(ContentType::Form)
|
.header(ContentType::Form)
|
||||||
.body("ssid=Home&pass=Password")
|
.body("ssid=Home&pass=Password")
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
@ -330,7 +332,7 @@ fn modify_password() {
|
||||||
#[test]
|
#[test]
|
||||||
fn deploy_ap() {
|
fn deploy_ap() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/ap/activate").dispatch();
|
let response = client.get("/settings/network/ap/activate").dispatch();
|
||||||
// check for 303 status (redirect)
|
// check for 303 status (redirect)
|
||||||
assert_eq!(response.status(), Status::SeeOther);
|
assert_eq!(response.status(), Status::SeeOther);
|
||||||
assert_eq!(response.content_type(), None);
|
assert_eq!(response.content_type(), None);
|
||||||
|
@ -339,7 +341,7 @@ fn deploy_ap() {
|
||||||
#[test]
|
#[test]
|
||||||
fn deploy_client() {
|
fn deploy_client() {
|
||||||
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
let client = Client::tracked(init_rocket()).expect("valid rocket instance");
|
||||||
let response = client.get("/network/wifi/activate").dispatch();
|
let response = client.get("/settings/network/wifi/activate").dispatch();
|
||||||
// check for 303 status (redirect)
|
// check for 303 status (redirect)
|
||||||
assert_eq!(response.status(), Status::SeeOther);
|
assert_eq!(response.status(), Status::SeeOther);
|
||||||
assert_eq!(response.content_type(), None);
|
assert_eq!(response.content_type(), None);
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 984 B After Width: | Height: | Size: 984 B |
|
@ -23,7 +23,7 @@ PEACH.add = function() {
|
||||||
// write in-progress status message to ui
|
// write in-progress status message to ui
|
||||||
PEACH.flashMsg("info", "Saving new password.");
|
PEACH.flashMsg("info", "Saving new password.");
|
||||||
// send add_wifi POST request
|
// send add_wifi POST request
|
||||||
fetch("/api/v1/settings/change_password", {
|
fetch("/api/v1/admin/change_password", {
|
||||||
method: "post",
|
method: "post",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
@ -38,7 +38,7 @@ PEACH_DNS.add = function() {
|
||||||
// write in-progress status message to ui
|
// write in-progress status message to ui
|
||||||
PEACH_DNS.flashMsg("info", "Saving new DNS configurations");
|
PEACH_DNS.flashMsg("info", "Saving new DNS configurations");
|
||||||
// send add_wifi POST request
|
// send add_wifi POST request
|
||||||
fetch("/api/v1/dns/configure", {
|
fetch("/api/v1/network/dns/configure", {
|
||||||
method: "post",
|
method: "post",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
behavioural layer for the `shutdown.html.tera` template,
|
behavioural layer for the `power.html.tera` template,
|
||||||
corresponding to the web route `/shutdown`
|
corresponding to the web route `/power`
|
||||||
|
|
||||||
- intercept button clicks for reboot & shutdown
|
- intercept button clicks for reboot & shutdown
|
||||||
- perform json api calls
|
- perform json api calls
|
||||||
|
@ -28,7 +28,7 @@ PEACH_DEVICE.reboot = function() {
|
||||||
// write reboot flash message
|
// write reboot flash message
|
||||||
PEACH_DEVICE.flashMsg("success", "Rebooting the device...");
|
PEACH_DEVICE.flashMsg("success", "Rebooting the device...");
|
||||||
// send reboot_device POST request
|
// send reboot_device POST request
|
||||||
fetch("/api/v1/device/reboot", {
|
fetch("/api/v1/admin/reboot", {
|
||||||
method: "post",
|
method: "post",
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
|
@ -59,7 +59,7 @@ PEACH_DEVICE.shutdown = function() {
|
||||||
// write shutdown flash message
|
// write shutdown flash message
|
||||||
PEACH_DEVICE.flashMsg("success", "Shutting down the device...");
|
PEACH_DEVICE.flashMsg("success", "Shutting down the device...");
|
||||||
// send shutdown_device POST request
|
// send shutdown_device POST request
|
||||||
fetch("/api/v1/device/shutdown", {
|
fetch("/api/v1/shutdown", {
|
||||||
method: "post",
|
method: "post",
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
|
@ -23,7 +23,7 @@ PEACH.add = function() {
|
||||||
// write in-progress status message to ui
|
// write in-progress status message to ui
|
||||||
PEACH.flashMsg("info", "Saving new password.");
|
PEACH.flashMsg("info", "Saving new password.");
|
||||||
// send add_wifi POST request
|
// send add_wifi POST request
|
||||||
fetch("/public/api/v1/reset_password", {
|
fetch("/api/v1/admin/reset_password", {
|
||||||
method: "post",
|
method: "post",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<div class="three-grid" style="padding-top: 1rem;">
|
<div class="three-grid" style="padding-top: 1rem;">
|
||||||
<!-- PEACH-NETWORK STATUS STACK -->
|
<!-- PEACH-NETWORK STATUS STACK -->
|
||||||
<div class="stack capsule{% if network_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if network_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="networkIcon" class="icon{% if network_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Network" title="Network microservice status" src="icons/wifi.svg">
|
<img id="networkIcon" class="icon{% if network_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Network" title="Network microservice status" src="/icons/wifi.svg">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Networking</label>
|
<label class="label-small font-near-black">Networking</label>
|
||||||
<label class="label-small font-near-black">{{ network_ping }}</label>
|
<label class="label-small font-near-black">{{ network_ping }}</label>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- PEACH-OLED STATUS STACK -->
|
<!-- PEACH-OLED STATUS STACK -->
|
||||||
<div class="stack capsule{% if oled_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if oled_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="oledIcon" class="icon{% if oled_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Display" title="OLED display microservice status" src="icons/lcd.svg">
|
<img id="oledIcon" class="icon{% if oled_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Display" title="OLED display microservice status" src="/icons/lcd.svg">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Display</label>
|
<label class="label-small font-near-black">Display</label>
|
||||||
<label class="label-small font-near-black">{{ oled_ping }}</label>
|
<label class="label-small font-near-black">{{ oled_ping }}</label>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- PEACH-STATS STATUS STACK -->
|
<!-- PEACH-STATS STATUS STACK -->
|
||||||
<div class="stack capsule{% if stats_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if stats_ping == "ONLINE" %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="statsIcon" class="icon{% if stats_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Stats" title="System statistics microservice status" src="icons/chart.svg">
|
<img id="statsIcon" class="icon{% if stats_ping == "OFFLINE" %} icon-inactive{% endif %} icon-medium" alt="Stats" title="System statistics microservice status" src="/icons/chart.svg">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Statistics</label>
|
<label class="label-small font-near-black">Statistics</label>
|
||||||
<label class="label-small font-near-black">{{ stats_ping }}</label>
|
<label class="label-small font-near-black">{{ stats_ping }}</label>
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<div class="three-grid" style="padding-bottom: 1rem; margin-top: 0px;">
|
<div class="three-grid" style="padding-bottom: 1rem; margin-top: 0px;">
|
||||||
<!-- DYNDNS STATUS STACK -->
|
<!-- DYNDNS STATUS STACK -->
|
||||||
<div class="stack capsule{% if dyndns_is_online %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if dyndns_is_online %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="networkIcon" class="icon{% if dyndns_is_online != true %} icon-inactive {% endif %} icon-medium" alt="Dyndns" title="Dyndns status" src="icons/wifi.svg">
|
<img id="networkIcon" class="icon{% if dyndns_is_online != true %} icon-inactive{% endif %} icon-medium" alt="Dyndns" title="Dyndns status" src="/icons/dns.png">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Dyn DNS</label>
|
<label class="label-small font-near-black">Dyn DNS</label>
|
||||||
<label class="label-small font-near-black">{% if dyndns_is_online %} ONLINE {% else %} OFFLINE {% endif %} </label>
|
<label class="label-small font-near-black">{% if dyndns_is_online %} ONLINE {% else %} OFFLINE {% endif %} </label>
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- CONFIG STATUS STACK -->
|
<!-- CONFIG STATUS STACK -->
|
||||||
<div class="stack capsule{% if config_is_valid %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if config_is_valid %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="networkIcon" class="icon{% if config_is_valid != true %} icon-inactive {% endif %} icon-medium" alt="Config" title="Config status" src="icons/wifi.svg">
|
<img id="networkIcon" class="icon{% if config_is_valid != true %} icon-inactive{% endif %} icon-medium" alt="Config" title="Config status" src="/icons/clipboard.png">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Config</label>
|
<label class="label-small font-near-black">Config</label>
|
||||||
<label class="label-small font-near-black">{% if config_is_valid %} LOADED {% else %} INVALID {% endif %} </label>
|
<label class="label-small font-near-black">{% if config_is_valid %} LOADED {% else %} INVALID {% endif %} </label>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- SBOT STATUS STACK -->
|
<!-- SBOT STATUS STACK -->
|
||||||
<div class="stack capsule{% if sbot_is_online %} success-border{% else %} warning-border{% endif %}">
|
<div class="stack capsule{% if sbot_is_online %} success-border{% else %} warning-border{% endif %}">
|
||||||
<img id="networkIcon" class="icon{% if sbot_is_online != true %} icon-inactive {% endif %} icon-medium" alt="Sbot" title="Sbot status" src="icons/wifi.svg">
|
<img id="networkIcon" class="icon{% if sbot_is_online != true %} icon-inactive{% endif %} icon-medium" alt="Sbot" title="Sbot status" src="/icons/hermies.svg">
|
||||||
<div class="stack" style="padding-top: 0.5rem;">
|
<div class="stack" style="padding-top: 0.5rem;">
|
||||||
<label class="label-small font-near-black">Sbot</label>
|
<label class="label-small font-near-black">Sbot</label>
|
||||||
<label class="label-small font-near-black">{% if sbot_is_online %} ONLINE {% else %} OFFLINE {% endif %} </label>
|
<label class="label-small font-near-black">{% if sbot_is_online %} ONLINE {% else %} OFFLINE {% endif %} </label>
|
||||||
|
|
|
@ -6,21 +6,21 @@
|
||||||
<!-- PEERS LINK AND ICON -->
|
<!-- PEERS LINK AND ICON -->
|
||||||
<a class="top-left" href="/scuttlebutt/peers" title="Scuttlebutt Peers">
|
<a class="top-left" href="/scuttlebutt/peers" title="Scuttlebutt Peers">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/users.svg">
|
<img class="icon-medium" src="/icons/users.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- top-middle -->
|
<!-- top-middle -->
|
||||||
<!-- CURRENT USER LINK AND ICON -->
|
<!-- CURRENT USER LINK AND ICON -->
|
||||||
<a class="top-middle" href="/scuttlebutt/profile" title="Profile">
|
<a class="top-middle" href="/scuttlebutt/profile" title="Profile">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/user.svg">
|
<img class="icon-medium" src="/icons/user.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- top-right -->
|
<!-- top-right -->
|
||||||
<!-- MESSAGES LINK AND ICON -->
|
<!-- MESSAGES LINK AND ICON -->
|
||||||
<a class="top-right" href="/scuttlebutt/private" title="Private Messages">
|
<a class="top-right" href="/scuttlebutt/private" title="Private Messages">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/envelope.svg">
|
<img class="icon-medium" src="/icons/envelope.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- middle -->
|
<!-- middle -->
|
||||||
|
@ -30,23 +30,23 @@
|
||||||
</a>
|
</a>
|
||||||
<!-- bottom-left -->
|
<!-- bottom-left -->
|
||||||
<!-- SYSTEM STATUS LINK AND ICON -->
|
<!-- SYSTEM STATUS LINK AND ICON -->
|
||||||
<a class="bottom-left" href="/device" title="Device Status">
|
<a class="bottom-left" href="/status" title="Status">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/heart-pulse.svg">
|
<img class="icon-medium" src="/icons/heart-pulse.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- bottom-middle -->
|
<!-- bottom-middle -->
|
||||||
<!-- PEACHCLOUD GUIDEBOOK LINK AND ICON -->
|
<!-- PEACHCLOUD GUIDEBOOK LINK AND ICON -->
|
||||||
<a class="bottom-middle" href="/help" title="Help Menu">
|
<a class="bottom-middle" href="/help" title="Help Menu">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/book.svg">
|
<img class="icon-medium" src="/icons/book.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- bottom-right -->
|
<!-- bottom-right -->
|
||||||
<!-- SYSTEM SETTINGS LINK AND ICON -->
|
<!-- SYSTEM SETTINGS LINK AND ICON -->
|
||||||
<a class="bottom-right" href="/network" title="Network Configuration">
|
<a class="bottom-right" href="/settings" title="Settings Menu">
|
||||||
<div class="circle circle-small">
|
<div class="circle circle-small">
|
||||||
<img class="icon-medium" src="icons/cog.svg">
|
<img class="icon-medium" src="/icons/cog.svg">
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
|
@ -17,7 +17,7 @@
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
|
|
||||||
<div class="center-text" style="margin-top: 25px;">
|
<div class="center-text" style="margin-top: 25px;">
|
||||||
<a href="/forgot_password" class="label-small link">Forgot Password?</a>
|
<a href="/settings/admin/forgot_password" class="label-small link">Forgot Password?</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
<a class="nav-item" href="/">
|
<a class="nav-item" href="/">
|
||||||
<img class="icon nav-icon-left" src="/icons/peach-icon.png" alt="PeachCloud" title="Home">
|
<img class="icon nav-icon-left" src="/icons/peach-icon.png" alt="PeachCloud" title="Home">
|
||||||
</a>
|
</a>
|
||||||
<a class="nav-item" href="/help">
|
<a class="nav-item" href="/power">
|
||||||
<img class="icon-medium nav-icon-right icon-active" title="Help" src="/icons/question-circle.svg" alt="Question mark">
|
<img class="icon-medium nav-icon-right icon-active" title="Shutdown" src="/icons/power.svg" alt="Power switch">
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
{%- endblock nav -%}
|
{%- endblock nav -%}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<div class="card-container">
|
<div class="card-container">
|
||||||
<!-- BUTTONS -->
|
<!-- BUTTONS -->
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
<a id="rebootBtn" class="button button-primary center" href="/device/reboot" title="Reboot Device">Reboot</a>
|
<a id="rebootBtn" class="button button-primary center" href="/power/reboot" title="Reboot Device">Reboot</a>
|
||||||
<a id="shutdownBtn" class="button button-warning center" href="/device/shutdown" title="Shutdown Device">Shutdown</a>
|
<a id="shutdownBtn" class="button button-warning center" href="/power/shutdown" title="Shutdown Device">Shutdown</a>
|
||||||
<a id="cancelBtn" class="button button-secondary center" href="/" title="Cancel">Cancel</a>
|
<a id="cancelBtn" class="button button-secondary center" href="/" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
|
@ -15,5 +15,5 @@
|
||||||
{% include "snippets/noscript" %}
|
{% include "snippets/noscript" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="/js/shutdown_menu.js"></script>
|
<script type="text/javascript" src="/js/power_menu.js"></script>
|
||||||
{%- endblock card -%}
|
{%- endblock card -%}
|
|
@ -7,7 +7,7 @@
|
||||||
<input id="ssb_id" name="ssb_id" class="center input" type="text" placeholder="SSB ID" title="SSB ID of Admin" value=""/>
|
<input id="ssb_id" name="ssb_id" class="center input" type="text" placeholder="SSB ID" title="SSB ID of Admin" value=""/>
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
<input id="addAdmin" class="button button-primary center" title="Add" type="submit" value="Add">
|
<input id="addAdmin" class="button button-primary center" title="Add" type="submit" value="Add">
|
||||||
<a class="button button-secondary center" href="/settings/configure_admin" title="Cancel">Cancel</a>
|
<a class="button button-secondary center" href="/settings/admin/configure" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
{%- extends "nav" -%}
|
||||||
|
{%- block card %}
|
||||||
|
<!-- ADMIN SETTINGS MENU -->
|
||||||
|
<div class="card center">
|
||||||
|
<div class="card-container">
|
||||||
|
<!-- BUTTONS -->
|
||||||
|
<div id="settingsButtons">
|
||||||
|
<a id="change" class="button button-primary center" href="/settings/admin/change_password" title="Change Password">Change Password</a>
|
||||||
|
<a id="configure" class="button button-primary center" href="/settings/admin/configure" title="Configure Admin">Configure Admin</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{%- endblock card -%}
|
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<form id="configureDNS" action="/network/dns" method="post">
|
<form id="configureDNS" action="/settings/network/dns" method="post">
|
||||||
<div class="input-wrapper">
|
<div class="input-wrapper">
|
||||||
<!-- input for externaldomain -->
|
<!-- input for externaldomain -->
|
||||||
<label id="external_domain" class="label-small input-label font-near-black">
|
<label id="external_domain" class="label-small input-label font-near-black">
|
|
@ -10,7 +10,7 @@
|
||||||
<input id="pass" name="pass" class="center input" type="password" placeholder="Password" title="Password for WiFi access point">
|
<input id="pass" name="pass" class="center input" type="password" placeholder="Password" title="Password for WiFi access point">
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
<input id="addWifi" class="button button-primary center" title="Add" type="submit" value="Add">
|
<input id="addWifi" class="button button-primary center" title="Add" type="submit" value="Add">
|
||||||
<a class="button button-secondary center" href="/network" title="Cancel">Cancel</a>
|
<a class="button button-secondary center" href="/settings/network" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
|
@ -11,7 +11,7 @@
|
||||||
<!-- left column -->
|
<!-- left column -->
|
||||||
<!-- network mode icon with label -->
|
<!-- network mode icon with label -->
|
||||||
<div class="grid-column-1">
|
<div class="grid-column-1">
|
||||||
<img id="netModeIcon" class="center icon icon-active" src="icons/router.svg" alt="WiFi router">
|
<img id="netModeIcon" class="center icon icon-active" src="/icons/router.svg" alt="WiFi router">
|
||||||
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="Access Point Online">ONLINE</label>
|
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="Access Point Online">ONLINE</label>
|
||||||
</div>
|
</div>
|
||||||
<!-- right column -->
|
<!-- right column -->
|
||||||
|
@ -27,10 +27,10 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- BUTTONS -->
|
<!-- BUTTONS -->
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<a class="button button-primary center" href="/network/wifi/add" title="Add WiFi Network">Add WiFi Network</a>
|
<a class="button button-primary center" href="/settings/network/wifi/add" title="Add WiFi Network">Add WiFi Network</a>
|
||||||
<a id="connectWifi" class="button button-primary center" href="/network/wifi/activate" title="Enable WiFi">Enable WiFi</a>
|
<a id="connectWifi" class="button button-primary center" href="/settings/network/wifi/activate" title="Enable WiFi">Enable WiFi</a>
|
||||||
<a id="listWifi" class="button button-primary center" href="/network/wifi" title="List WiFi Networks">List WiFi Networks</a>
|
<a id="listWifi" class="button button-primary center" href="/settings/network/wifi" title="List WiFi Networks">List WiFi Networks</a>
|
||||||
<a id="viewUsage" class="button button-primary center" href="/network/wifi/usage" title="View Data Usage">View Data Usage</a>
|
<a id="viewUsage" class="button button-primary center" href="/settings/network/wifi/usage" title="View Data Usage">View Data Usage</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
|
@ -38,14 +38,14 @@
|
||||||
<div class="card-container">
|
<div class="card-container">
|
||||||
<div class="three-grid">
|
<div class="three-grid">
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="devices" class="icon icon-medium" title="Connected devices" src="icons/devices.svg" alt="Digital devices">
|
<img id="devices" class="icon icon-medium" title="Connected devices" src="/icons/devices.svg" alt="Digital devices">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
<label class="label-medium" for="devices" style="padding-right: 3px;" title="Number of connected devices"></label>
|
<label class="label-medium" for="devices" style="padding-right: 3px;" title="Number of connected devices"></label>
|
||||||
</div>
|
</div>
|
||||||
<label class="label-small font-gray">DEVICES</label>
|
<label class="label-small font-gray">DEVICES</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="dataDownload" class="icon icon-medium" title="Download" src="icons/down-arrow.svg" alt="Download">
|
<img id="dataDownload" class="icon icon-medium" title="Download" src="/icons/down-arrow.svg" alt="Download">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
{%- if ap_traffic -%}
|
{%- if ap_traffic -%}
|
||||||
<label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total in {{ ap_traffic.rx_unit }}">{{ ap_traffic.received }}</label>
|
<label class="label-medium" for="dataDownload" style="padding-right: 3px;" title="Data download total in {{ ap_traffic.rx_unit }}">{{ ap_traffic.received }}</label>
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
<label class="label-small font-gray">DOWNLOAD</label>
|
<label class="label-small font-gray">DOWNLOAD</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="dataUpload" class="icon icon-medium" title="Upload" src="icons/up-arrow.svg" alt="Upload">
|
<img id="dataUpload" class="icon icon-medium" title="Upload" src="/icons/up-arrow.svg" alt="Upload">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
{%- if ap_traffic -%}
|
{%- if ap_traffic -%}
|
||||||
<label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total in {{ ap_traffic.tx_unit }}">{{ ap_traffic.transmitted }}</label>
|
<label class="label-medium" for="dataUpload" style="padding-right: 3px;" title="Data upload total in {{ ap_traffic.tx_unit }}">{{ ap_traffic.transmitted }}</label>
|
||||||
|
@ -83,12 +83,12 @@
|
||||||
<!-- left column -->
|
<!-- left column -->
|
||||||
<!-- network mode icon with label -->
|
<!-- network mode icon with label -->
|
||||||
<div class="grid-column-1">
|
<div class="grid-column-1">
|
||||||
<img id="netModeIcon" class="center icon icon-active" src="icons/wifi.svg" alt="WiFi online">
|
<img id="netModeIcon" class="center icon icon-active" src="/icons/wifi.svg" alt="WiFi online">
|
||||||
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status">ONLINE</label>
|
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status">ONLINE</label>
|
||||||
{%- else %}
|
{%- else %}
|
||||||
<div id="netInfoBox" class="two-grid capsule warning-border" title="PeachCloud network mode and status">
|
<div id="netInfoBox" class="two-grid capsule warning-border" title="PeachCloud network mode and status">
|
||||||
<div class="grid-column-1">
|
<div class="grid-column-1">
|
||||||
<img id="netModeIcon" class="center icon icon-inactive" src="icons/wifi.svg" alt="WiFi offline">
|
<img id="netModeIcon" class="center icon icon-inactive" src="/icons/wifi.svg" alt="WiFi offline">
|
||||||
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status">OFFLINE</label>
|
<label id="netModeLabel" for="netModeIcon" class="center label-small font-gray" title="WiFi Client Status">OFFLINE</label>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,13 +105,13 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- BUTTONS -->
|
<!-- BUTTONS -->
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<a class="button button-primary center" href="/network/wifi/add" title="Add WiFi Network">Add WiFi Network</a>
|
<a class="button button-primary center" href="/settings/network/wifi/add" title="Add WiFi Network">Add WiFi Network</a>
|
||||||
<a id="deployAccessPoint" class="button button-primary center" href="/network/ap/activate" title="Deploy Access Point">Deploy Access Point</a>
|
<a id="deployAccessPoint" class="button button-primary center" href="/settings/network/ap/activate" title="Deploy Access Point">Deploy Access Point</a>
|
||||||
<a id="listWifi" class="button button-primary center" href="/network/wifi" title="List WiFi Networks">List WiFi Networks</a>
|
<a id="listWifi" class="button button-primary center" href="/settings/network/wifi" title="List WiFi Networks">List WiFi Networks</a>
|
||||||
<a id="viewUsage" class="button button-primary center" href="/network/wifi/usage" title="View Data Usage">View Data Usage</a>
|
<a id="viewUsage" class="button button-primary center" href="/settings/network/wifi/usage" title="View Data Usage">View Data Usage</a>
|
||||||
<a id="configureDNS" class="button button-primary center" href="/network/dns" title="Configure DNS">Configure DNS</a>
|
<a id="configureDNS" class="button button-primary center" href="/settings/network/dns" title="Configure DNS">Configure DNS</a>
|
||||||
<a id="changePassword" class="button button-primary center" href="/settings/change_password" title="Change Password">Change Password</a>
|
<a id="changePassword" class="button button-primary center" href="/settings/admin/change_password" title="Change Password">Change Password</a>
|
||||||
<a id="configureAdmin" class="button button-primary center" href="/settings/configure_admin" title="Configure Admin">Configure Admin</a>
|
<a id="configureAdmin" class="button button-primary center" href="/settings/admin/configure_admin" title="Configure Admin">Configure Admin</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
||||||
|
@ -120,14 +120,14 @@
|
||||||
<!-- row of icons representing network statistics -->
|
<!-- row of icons representing network statistics -->
|
||||||
<div class="three-grid">
|
<div class="three-grid">
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="netSignal" class="icon icon-medium" alt="Signal" title="WiFi Signal (%)" src="icons/low-signal.svg">
|
<img id="netSignal" class="icon icon-medium" alt="Signal" title="WiFi Signal (%)" src="/icons/low-signal.svg">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
<label class="label-medium" for="netSignal" style="padding-right: 3px;" title="Signal strength of WiFi connection (%)">{% if wlan_rssi %}{{ wlan_rssi }}{% else %}0{% endif %}%</label>
|
<label class="label-medium" for="netSignal" style="padding-right: 3px;" title="Signal strength of WiFi connection (%)">{% if wlan_rssi %}{{ wlan_rssi }}{% else %}0{% endif %}%</label>
|
||||||
</div>
|
</div>
|
||||||
<label class="label-small font-gray">SIGNAL</label>
|
<label class="label-small font-gray">SIGNAL</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="dataDownload" class="icon icon-medium" alt="Download" title="WiFi download total" src="icons/down-arrow.svg">
|
<img id="dataDownload" class="icon icon-medium" alt="Download" title="WiFi download total" src="/icons/down-arrow.svg">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
{%- if wlan_traffic %}
|
{%- if wlan_traffic %}
|
||||||
<!-- display wlan traffic data -->
|
<!-- display wlan traffic data -->
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
<label class="label-small font-gray">DOWNLOAD</label>
|
<label class="label-small font-gray">DOWNLOAD</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="stack">
|
<div class="stack">
|
||||||
<img id="dataUpload" class="icon icon-medium" alt="Upload" title="WiFi upload total" src="icons/up-arrow.svg">
|
<img id="dataUpload" class="icon icon-medium" alt="Upload" title="WiFi upload total" src="/icons/up-arrow.svg">
|
||||||
<div class="flex-grid" style="padding-top: 0.5rem;">
|
<div class="flex-grid" style="padding-top: 0.5rem;">
|
||||||
{%- if wlan_traffic %}
|
{%- if wlan_traffic %}
|
||||||
<!-- display wlan traffic data -->
|
<!-- display wlan traffic data -->
|
|
@ -29,7 +29,7 @@
|
||||||
<div class="card-container" style="padding-top: 0;">
|
<div class="card-container" style="padding-top: 0;">
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
{%- if wlan_ssid == selected -%}
|
{%- if wlan_ssid == selected -%}
|
||||||
<form id="wifiDisconnect" action="/network/wifi/disconnect" method="post">
|
<form id="wifiDisconnect" action="/settings/network/wifi/disconnect" method="post">
|
||||||
<!-- hidden element: allows ssid to be sent in request -->
|
<!-- hidden element: allows ssid to be sent in request -->
|
||||||
<input id="disconnectSsid" name="ssid" type="text" value="{{ ssid }}" style="display: none;">
|
<input id="disconnectSsid" name="ssid" type="text" value="{{ ssid }}" style="display: none;">
|
||||||
<input id="disconnectWifi" class="button button-warning center" title="Disconnect from Network" type="submit" value="Disconnect">
|
<input id="disconnectWifi" class="button button-warning center" title="Disconnect from Network" type="submit" value="Disconnect">
|
||||||
|
@ -44,14 +44,14 @@
|
||||||
{# Set 'in_list' to true to allow correct Add button display #}
|
{# Set 'in_list' to true to allow correct Add button display #}
|
||||||
{% set_global in_list = true %}
|
{% set_global in_list = true %}
|
||||||
{%- if wlan_ssid != selected and ap.state == "Available" -%}
|
{%- if wlan_ssid != selected and ap.state == "Available" -%}
|
||||||
<form id="wifiConnect" action="/network/wifi/connect" method="post">
|
<form id="wifiConnect" action="/settings/network/wifi/connect" method="post">
|
||||||
<!-- hidden element: allows ssid to be sent in request -->
|
<!-- hidden element: allows ssid to be sent in request -->
|
||||||
<input id="connectSsid" name="ssid" type="text" value="{{ ap.ssid }}" style="display: none;">
|
<input id="connectSsid" name="ssid" type="text" value="{{ ap.ssid }}" style="display: none;">
|
||||||
<input id="connectWifi" class="button button-primary center" title="Connect to Network" type="submit" value="Connect">
|
<input id="connectWifi" class="button button-primary center" title="Connect to Network" type="submit" value="Connect">
|
||||||
</form>
|
</form>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<a class="button button-primary center" href="/network/wifi/modify?ssid={{ ssid }}">Modify</a>
|
<a class="button button-primary center" href="/settings/network/wifi/modify?ssid={{ ssid }}">Modify</a>
|
||||||
<form id="wifiForget" action="/network/wifi/forget" method="post">
|
<form id="wifiForget" action="/settings/network/wifi/forget" method="post">
|
||||||
<!-- hidden element: allows ssid to be sent in request -->
|
<!-- hidden element: allows ssid to be sent in request -->
|
||||||
<input id="forgetSsid" name="ssid" type="text" value="{{ ap.ssid }}" style="display: none;">
|
<input id="forgetSsid" name="ssid" type="text" value="{{ ap.ssid }}" style="display: none;">
|
||||||
<input id="forgetWifi" class="button button-warning center" title="Forget Network" type="submit" value="Forget">
|
<input id="forgetWifi" class="button button-warning center" title="Forget Network" type="submit" value="Forget">
|
||||||
|
@ -61,9 +61,9 @@
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if in_list == false -%}
|
{%- if in_list == false -%}
|
||||||
{# Display the Add button if AP creds not already in saved networks list #}
|
{# Display the Add button if AP creds not already in saved networks list #}
|
||||||
<a class="button button-primary center" href="/network/wifi/add?ssid={{ ssid }}">Add</a>
|
<a class="button button-primary center" href="/settings/network/wifi/add?ssid={{ ssid }}">Add</a>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<a class="button button-secondary center" href="/network/wifi" title="Cancel">Cancel</a>
|
<a class="button button-secondary center" href="/settings/network/wifi" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
|
@ -9,19 +9,19 @@
|
||||||
{%- for ssid, state in wlan_networks %}
|
{%- for ssid, state in wlan_networks %}
|
||||||
<li>
|
<li>
|
||||||
{%- if ssid == wlan_ssid %}
|
{%- if ssid == wlan_ssid %}
|
||||||
<a class="list-item link primary-bg" href="/network/wifi?ssid={{ wlan_ssid }}">
|
<a class="list-item link primary-bg" href="/settings/network/wifi?ssid={{ wlan_ssid }}">
|
||||||
<img id="netStatus" class="icon icon-active icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi online">
|
<img id="netStatus" class="icon icon-active icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi online">
|
||||||
<p class="list-text">{{ wlan_ssid }}</p>
|
<p class="list-text">{{ wlan_ssid }}</p>
|
||||||
<label class="label-small list-label font-gray" for="netStatus" title="Status">Connected</label>
|
<label class="label-small list-label font-gray" for="netStatus" title="Status">Connected</label>
|
||||||
</a>
|
</a>
|
||||||
{%- elif state == "Available" %}
|
{%- elif state == "Available" %}
|
||||||
<a class="list-item link light-bg" href="/network/wifi?ssid={{ ssid }}">
|
<a class="list-item link light-bg" href="/settings/network/wifi?ssid={{ ssid }}">
|
||||||
<img id="netStatus" class="icon icon-inactive icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi offline">
|
<img id="netStatus" class="icon icon-inactive icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi offline">
|
||||||
<p class="list-text">{{ ssid }}</p>
|
<p class="list-text">{{ ssid }}</p>
|
||||||
<label class="label-small list-label font-gray" for="netStatus" title="Status">{{ state }}</label>
|
<label class="label-small list-label font-gray" for="netStatus" title="Status">{{ state }}</label>
|
||||||
</a>
|
</a>
|
||||||
{%- else %}
|
{%- else %}
|
||||||
<a class="list-item link" href="/network/wifi?ssid={{ ssid }}">
|
<a class="list-item link" href="/settings/network/wifi?ssid={{ ssid }}">
|
||||||
<img id="netStatus" class="icon icon-inactive icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi offline">
|
<img id="netStatus" class="icon icon-inactive icon-medium list-icon" src="/icons/wifi.svg" alt="WiFi offline">
|
||||||
<p class="list-text">{{ ssid }}</p>
|
<p class="list-text">{{ ssid }}</p>
|
||||||
<label class="label-small list-label font-gray" for="netStatus" title="Status">{{ state }}</label>
|
<label class="label-small list-label font-gray" for="netStatus" title="Status">{{ state }}</label>
|
|
@ -3,14 +3,14 @@
|
||||||
<!-- NETWORK MODIFY AP PASSWORD FORM -->
|
<!-- NETWORK MODIFY AP PASSWORD FORM -->
|
||||||
<div class="card center">
|
<div class="card center">
|
||||||
<div class="card-container">
|
<div class="card-container">
|
||||||
<form id="wifiModify" action="/network/wifi/modify" method="post">
|
<form id="wifiModify" action="/settings/network/wifi/modify" method="post">
|
||||||
<!-- input for network ssid -->
|
<!-- input for network ssid -->
|
||||||
<input id="ssid" name="ssid" class="center input" type="text" placeholder="SSID" title="Network name (SSID) for WiFi access point" value="{% if selected %}{{ selected }}{% endif %}" autofocus>
|
<input id="ssid" name="ssid" class="center input" type="text" placeholder="SSID" title="Network name (SSID) for WiFi access point" value="{% if selected %}{{ selected }}{% endif %}" autofocus>
|
||||||
<!-- input for network password -->
|
<!-- input for network password -->
|
||||||
<input id="pass" name="pass" class="center input" type="password" placeholder="Password" title="Password for WiFi access point">
|
<input id="pass" name="pass" class="center input" type="password" placeholder="Password" title="Password for WiFi access point">
|
||||||
<div id="buttonDiv">
|
<div id="buttonDiv">
|
||||||
<input id="savePassword" class="button button-primary center" title="Save" type="submit" value="Save">
|
<input id="savePassword" class="button button-primary center" title="Save" type="submit" value="Save">
|
||||||
<a class="button button-secondary center" href="/network" title="Cancel">Cancel</a>
|
<a class="button button-secondary center" href="/settings/network" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
|
@ -1,7 +1,7 @@
|
||||||
{%- extends "nav" -%}
|
{%- extends "nav" -%}
|
||||||
{%- block card -%}
|
{%- block card -%}
|
||||||
<!-- NETWORK DATA ALERTS VIEW -->
|
<!-- NETWORK DATA ALERTS VIEW -->
|
||||||
<form id="wifiAlerts" action="/network/wifi/usage" class="card center" method="post">
|
<form id="wifiAlerts" action="/settings/network/wifi/usage" class="card center" method="post">
|
||||||
<div class="stack capsule" style="margin-left: 2rem; margin-right: 2rem;">
|
<div class="stack capsule" style="margin-left: 2rem; margin-right: 2rem;">
|
||||||
<div class="flex-grid">
|
<div class="flex-grid">
|
||||||
<label id="dataTotal" class="label-large" title="Data download total in MB">{{ data_total.total / 1024 / 1024 | round }}</label>
|
<label id="dataTotal" class="label-large" title="Data download total in MB">{{ data_total.total / 1024 / 1024 | round }}</label>
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="buttonDiv" class="button-div">
|
<div id="buttonDiv" class="button-div">
|
||||||
<input id="updateAlerts" class="button button-primary center" title="Update" type="submit" value="Update">
|
<input id="updateAlerts" class="button button-primary center" title="Update" type="submit" value="Update">
|
||||||
<a id="resetTotal" class="button button-warning center" href="/network/wifi/usage/reset" title="Reset stored usage total to zero">Reset</a>
|
<a id="resetTotal" class="button button-warning center" href="/settings/network/wifi/usage/reset" title="Reset stored usage total to zero">Reset</a>
|
||||||
<a class="button button-secondary center" href="/network" title="Cancel">Cancel</a>
|
<a class="button button-secondary center" href="/settings/network" title="Cancel">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- FLASH MESSAGE -->
|
<!-- FLASH MESSAGE -->
|
||||||
{% include "snippets/flash_message" %}
|
{% include "snippets/flash_message" %}
|
Loading…
Reference in New Issue