add network settings menu template and route handler, along with network settings placeholder files for routes
This commit is contained in:
parent
c5c0bb91e4
commit
1a7bd7987b
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2346,6 +2346,7 @@ dependencies = [
|
|||||||
"log 0.4.17",
|
"log 0.4.17",
|
||||||
"maud",
|
"maud",
|
||||||
"peach-lib",
|
"peach-lib",
|
||||||
|
"peach-network",
|
||||||
"rouille",
|
"rouille",
|
||||||
"temporary",
|
"temporary",
|
||||||
"xdg",
|
"xdg",
|
||||||
|
@ -45,7 +45,7 @@ log = "0.4"
|
|||||||
maud = "0.23"
|
maud = "0.23"
|
||||||
peach-lib = { path = "../peach-lib" }
|
peach-lib = { path = "../peach-lib" }
|
||||||
# these will be reintroduced when the full peachcloud mode is added
|
# these will be reintroduced when the full peachcloud mode is added
|
||||||
#peach-network = { path = "../peach-network" }
|
peach-network = { path = "../peach-network" }
|
||||||
#peach-stats = { path = "../peach-stats" }
|
#peach-stats = { path = "../peach-stats" }
|
||||||
rouille = { version = "3.5", default-features = false }
|
rouille = { version = "3.5", default-features = false }
|
||||||
temporary = "0.6"
|
temporary = "0.6"
|
||||||
|
@ -200,6 +200,10 @@ pub fn mount_peachpub_routes(
|
|||||||
routes::settings::scuttlebutt::default::write_config()
|
routes::settings::scuttlebutt::default::write_config()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
(GET) (/settings/network) => {
|
||||||
|
Response::html(routes::settings::network::menu::build_template(request)).reset_flash()
|
||||||
|
},
|
||||||
|
|
||||||
(GET) (/settings/theme/{theme: String}) => {
|
(GET) (/settings/theme/{theme: String}) => {
|
||||||
routes::settings::theme::set_theme(theme)
|
routes::settings::theme::set_theme(theme)
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
pub mod admin;
|
pub mod admin;
|
||||||
//pub mod dns;
|
//pub mod dns;
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
//pub mod network;
|
pub mod network;
|
||||||
pub mod scuttlebutt;
|
pub mod scuttlebutt;
|
||||||
pub mod theme;
|
pub mod theme;
|
||||||
|
@ -1,322 +0,0 @@
|
|||||||
use log::{debug, warn};
|
|
||||||
use rocket::{
|
|
||||||
form::{Form, FromForm},
|
|
||||||
get, post,
|
|
||||||
request::FlashMessage,
|
|
||||||
response::{Flash, Redirect},
|
|
||||||
uri, UriDisplayQuery,
|
|
||||||
};
|
|
||||||
use rocket_dyn_templates::{tera::Context, Template};
|
|
||||||
|
|
||||||
use peach_network::network;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
context,
|
|
||||||
context::network::{NetworkAlertContext, NetworkDetailContext, NetworkListContext},
|
|
||||||
routes::authentication::Authenticated,
|
|
||||||
utils::{monitor, monitor::Threshold},
|
|
||||||
AP_IFACE, WLAN_IFACE,
|
|
||||||
};
|
|
||||||
|
|
||||||
// STRUCTS USED BY NETWORK ROUTES
|
|
||||||
|
|
||||||
#[derive(Debug, FromForm, UriDisplayQuery)]
|
|
||||||
pub struct Ssid {
|
|
||||||
pub ssid: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, FromForm)]
|
|
||||||
pub struct WiFi {
|
|
||||||
pub ssid: String,
|
|
||||||
pub pass: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi/usage/reset
|
|
||||||
|
|
||||||
#[get("/wifi/usage/reset")]
|
|
||||||
pub fn wifi_usage_reset(_auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
let url = uri!(wifi_usage);
|
|
||||||
match monitor::reset_data() {
|
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "Reset stored network traffic total"),
|
|
||||||
Err(_) => Flash::error(
|
|
||||||
Redirect::to(url),
|
|
||||||
"Failed to reset stored network traffic total",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/connect", data = "<network>")]
|
|
||||||
pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
let ssid = &network.ssid;
|
|
||||||
let url = uri!(network_detail(ssid = ssid));
|
|
||||||
match network::id(&*WLAN_IFACE, ssid) {
|
|
||||||
Ok(Some(id)) => match network::connect(&id, &*WLAN_IFACE) {
|
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "Connected to chosen network"),
|
|
||||||
Err(_) => Flash::error(Redirect::to(url), "Failed to connect to chosen network"),
|
|
||||||
},
|
|
||||||
_ => Flash::error(Redirect::to(url), "Failed to retrieve the network ID"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/disconnect", data = "<network>")]
|
|
||||||
pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
let ssid = &network.ssid;
|
|
||||||
let url = uri!(network_home);
|
|
||||||
match network::disable(&*WLAN_IFACE, ssid) {
|
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "Disconnected from WiFi network"),
|
|
||||||
Err(_) => Flash::error(Redirect::to(url), "Failed to disconnect from WiFi network"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/forget", data = "<network>")]
|
|
||||||
pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
let ssid = &network.ssid;
|
|
||||||
let url = uri!(network_home);
|
|
||||||
match network::forget(&*WLAN_IFACE, ssid) {
|
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "WiFi credentials removed"),
|
|
||||||
Err(_) => Flash::error(
|
|
||||||
Redirect::to(url),
|
|
||||||
"Failed to remove WiFi credentials".to_string(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi/modify?<ssid>")]
|
|
||||||
pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = Context::new();
|
|
||||||
context.insert("back", &Some("/settings/network/wifi".to_string()));
|
|
||||||
context.insert("title", &Some("Update WiFi Password".to_string()));
|
|
||||||
context.insert("selected", &Some(ssid.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.insert("flash_name", &Some(flash.kind().to_string()));
|
|
||||||
context.insert("flash_msg", &Some(flash.message().to_string()));
|
|
||||||
};
|
|
||||||
|
|
||||||
Template::render("settings/network/modify_ap", &context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/modify", data = "<wifi>")]
|
|
||||||
pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
let ssid = &wifi.ssid;
|
|
||||||
let pass = &wifi.pass;
|
|
||||||
let url = uri!(network_detail(ssid = ssid));
|
|
||||||
match network::update(&*WLAN_IFACE, ssid, pass) {
|
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "WiFi password updated".to_string()),
|
|
||||||
Err(_) => Flash::error(
|
|
||||||
Redirect::to(url),
|
|
||||||
"Failed to update WiFi password".to_string(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network
|
|
||||||
|
|
||||||
#[get("/")]
|
|
||||||
pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
// assign context
|
|
||||||
let mut context = Context::new();
|
|
||||||
context.insert("back", &Some("/settings"));
|
|
||||||
context.insert("title", &Some("Network Configuration"));
|
|
||||||
context.insert("ap_state", &context::network::ap_state());
|
|
||||||
|
|
||||||
// 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.insert("flash_name", &Some(flash.kind().to_string()));
|
|
||||||
context.insert("flash_msg", &Some(flash.message().to_string()));
|
|
||||||
};
|
|
||||||
|
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/menu", &context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/ap/activate
|
|
||||||
|
|
||||||
#[get("/ap/activate")]
|
|
||||||
pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
// activate the wireless access point
|
|
||||||
debug!("Activating WiFi access point.");
|
|
||||||
match network::start_iface_service(&*AP_IFACE) {
|
|
||||||
Ok(_) => Flash::success(
|
|
||||||
Redirect::to("/settings/network"),
|
|
||||||
"Activated WiFi access point",
|
|
||||||
),
|
|
||||||
Err(_) => Flash::error(
|
|
||||||
Redirect::to("/settings/network"),
|
|
||||||
"Failed to activate WiFi access point",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi
|
|
||||||
|
|
||||||
#[get("/wifi")]
|
|
||||||
pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
// assign context through context_builder call
|
|
||||||
let mut context = NetworkListContext::build();
|
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.title = Some("WiFi Networks".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/network/list_aps", &context)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi<ssid>
|
|
||||||
|
|
||||||
#[get("/wifi?<ssid>")]
|
|
||||||
pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = NetworkDetailContext::build();
|
|
||||||
context.back = Some("/settings/network/wifi".to_string());
|
|
||||||
context.title = Some("WiFi Network".to_string());
|
|
||||||
context.selected = Some(ssid.to_string());
|
|
||||||
|
|
||||||
if let Some(flash) = flash {
|
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
|
||||||
};
|
|
||||||
|
|
||||||
Template::render("settings/network/ap_details", &context)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi/activate
|
|
||||||
|
|
||||||
#[get("/wifi/activate")]
|
|
||||||
pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
// activate the wireless client
|
|
||||||
debug!("Activating WiFi client mode.");
|
|
||||||
match network::start_iface_service(&*WLAN_IFACE) {
|
|
||||||
Ok(_) => Flash::success(Redirect::to("/settings/network"), "Activated WiFi client"),
|
|
||||||
Err(_) => Flash::error(
|
|
||||||
Redirect::to("/settings/network"),
|
|
||||||
"Failed to activate WiFi client",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi/add
|
|
||||||
|
|
||||||
#[get("/wifi/add")]
|
|
||||||
pub fn add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = Context::new();
|
|
||||||
context.insert("back", &Some("/settings/network".to_string()));
|
|
||||||
context.insert("title", &Some("Add WiFi Network".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.insert("flash_name", &Some(flash.kind().to_string()));
|
|
||||||
context.insert("flash_msg", &Some(flash.message().to_string()));
|
|
||||||
};
|
|
||||||
|
|
||||||
Template::render("settings/network/add_ap", &context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi/add?<ssid>")]
|
|
||||||
pub fn add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = Context::new();
|
|
||||||
context.insert("back", &Some("/settings/network".to_string()));
|
|
||||||
context.insert("title", &Some("Add WiFi Network".to_string()));
|
|
||||||
context.insert("selected", &Some(ssid.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.insert("flash_name", &Some(flash.kind().to_string()));
|
|
||||||
context.insert("flash_msg", &Some(flash.message().to_string()));
|
|
||||||
};
|
|
||||||
|
|
||||||
Template::render("settings/network/add_ap", &context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/add", data = "<wifi>")]
|
|
||||||
pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = Context::new();
|
|
||||||
context.insert("back", &Some("/settings/network".to_string()));
|
|
||||||
context.insert("title", &Some("Add WiFi Network".to_string()));
|
|
||||||
|
|
||||||
// check if the credentials already exist for this access point
|
|
||||||
// note: this is nicer but it's an unstable feature:
|
|
||||||
// if check_saved_aps(&wifi.ssid).contains(true)
|
|
||||||
// use unwrap_or instead, set value to false if err is returned
|
|
||||||
//let creds_exist = network::saved_networks(&wifi.ssid).unwrap_or(false);
|
|
||||||
let creds_exist = match network::saved_networks() {
|
|
||||||
Ok(Some(networks)) => networks.contains(&wifi.ssid),
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// if credentials not found, generate and write wifi config to wpa_supplicant
|
|
||||||
let (flash_name, flash_msg) = if creds_exist {
|
|
||||||
(
|
|
||||||
"error".to_string(),
|
|
||||||
"Network credentials already exist for this access point".to_string(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
match network::add(&*WLAN_IFACE, &wifi.ssid, &wifi.pass) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("Added WiFi credentials.");
|
|
||||||
// force reread of wpa_supplicant.conf file with new credentials
|
|
||||||
match network::reconfigure() {
|
|
||||||
Ok(_) => debug!("Successfully reconfigured wpa_supplicant"),
|
|
||||||
Err(_) => warn!("Failed to reconfigure wpa_supplicant"),
|
|
||||||
}
|
|
||||||
("success".to_string(), "Added WiFi credentials".to_string())
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
debug!("Failed to add WiFi credentials.");
|
|
||||||
("error".to_string(), format!("{}", e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
context.insert("flash_name", &Some(flash_name));
|
|
||||||
context.insert("flash_msg", &Some(flash_msg));
|
|
||||||
|
|
||||||
Template::render("settings/network/add_ap", &context.into_json())
|
|
||||||
}
|
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR WIFI USAGE
|
|
||||||
|
|
||||||
#[get("/wifi/usage")]
|
|
||||||
pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
|
||||||
let mut context = NetworkAlertContext::build();
|
|
||||||
// set back icon link to network route
|
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.title = Some("Network Data Usage".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_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/data_usage_limits", &context)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/wifi/usage", data = "<thresholds>")]
|
|
||||||
pub fn wifi_usage_alerts(thresholds: Form<Threshold>, _auth: Authenticated) -> Flash<Redirect> {
|
|
||||||
match monitor::update_store(thresholds.into_inner()) {
|
|
||||||
Ok(_) => {
|
|
||||||
debug!("WiFi data usage thresholds updated.");
|
|
||||||
Flash::success(
|
|
||||||
Redirect::to("/settings/network/wifi/usage"),
|
|
||||||
"Updated alert thresholds and flags",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("Failed to update WiFi data usage thresholds.");
|
|
||||||
Flash::error(
|
|
||||||
Redirect::to("/settings/network/wifi/usage"),
|
|
||||||
"Failed to update alert thresholds and flags",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
0
peach-web/src/routes/settings/network/add_ap.rs
Normal file
0
peach-web/src/routes/settings/network/add_ap.rs
Normal file
0
peach-web/src/routes/settings/network/ap_details.rs
Normal file
0
peach-web/src/routes/settings/network/ap_details.rs
Normal file
0
peach-web/src/routes/settings/network/list_aps.rs
Normal file
0
peach-web/src/routes/settings/network/list_aps.rs
Normal file
57
peach-web/src/routes/settings/network/menu.rs
Normal file
57
peach-web/src/routes/settings/network/menu.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use maud::{html, Markup, PreEscaped};
|
||||||
|
use peach_network::network;
|
||||||
|
use rouille::Request;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
templates,
|
||||||
|
utils::{flash::FlashRequest, theme},
|
||||||
|
};
|
||||||
|
|
||||||
|
// ROUTE: /settings/network
|
||||||
|
|
||||||
|
/// Read the wireless interface mode (WiFi AP or client) and selectively render
|
||||||
|
/// the activation button for the deactivated mode.
|
||||||
|
fn render_mode_toggle_button() -> Markup {
|
||||||
|
match network::state("ap0") {
|
||||||
|
Ok(Some(state)) if state == "up" => {
|
||||||
|
html! {
|
||||||
|
a id="connectWifi" class="button button-primary center" href="/settings/network/wifi/activate" title="Enable WiFi" { "Enable WiFi" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => html! {
|
||||||
|
a id="deployAccessPoint" class="button button-primary center" href="/settings/network/ap/activate" title="Deploy Access Point" { "Deploy Access Point" }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Network settings menu template builder.
|
||||||
|
pub fn build_template(request: &Request) -> PreEscaped<String> {
|
||||||
|
let (flash_name, flash_msg) = request.retrieve_flash();
|
||||||
|
|
||||||
|
let menu_template = html! {
|
||||||
|
(PreEscaped("<!-- NETWORK SETTINGS MENU -->"))
|
||||||
|
div class="card center" {
|
||||||
|
(PreEscaped("<!-- BUTTONS -->"))
|
||||||
|
div id="buttons" {
|
||||||
|
a class="button button-primary center" href="/settings/network/wifi/add" title="Add WiFi Network" { "Add WiFi Network" }
|
||||||
|
a id="configureDNS" class="button button-primary center" href="/settings/network/dns" title="Configure DNS" { "Configure DNS" }
|
||||||
|
(PreEscaped("<!-- if ap is up, show 'Enable WiFi' button, else show 'Deplay Access Point' -->"))
|
||||||
|
(render_mode_toggle_button())
|
||||||
|
a id="listWifi" class="button button-primary center" href="/settings/network/wifi" title="List WiFi Networks" { "List WiFi Networks" }
|
||||||
|
a id="viewUsage" class="button button-primary center" href="/settings/network/wifi/usage" title="View Data Usage" { "View Data Usage" }
|
||||||
|
a id="viewStatus" class="button button-primary center" href="/status/network" title="View Network Status" { "View Network Status" }
|
||||||
|
}
|
||||||
|
// render flash message if cookies were found in the request
|
||||||
|
@if let (Some(name), Some(msg)) = (flash_name, flash_msg) {
|
||||||
|
(PreEscaped("<!-- FLASH MESSAGE -->"))
|
||||||
|
(templates::flash::build_template(name, msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let body = templates::nav::build_template(menu_template, "Network Settings", Some("/settings"));
|
||||||
|
|
||||||
|
let theme = theme::get_theme();
|
||||||
|
|
||||||
|
templates::base::build_template(body, theme)
|
||||||
|
}
|
1
peach-web/src/routes/settings/network/mod.rs
Normal file
1
peach-web/src/routes/settings/network/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod menu;
|
0
peach-web/src/routes/settings/network/modify_ap.rs
Normal file
0
peach-web/src/routes/settings/network/modify_ap.rs
Normal file
Loading…
x
Reference in New Issue
Block a user