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",
|
||||
"maud",
|
||||
"peach-lib",
|
||||
"peach-network",
|
||||
"rouille",
|
||||
"temporary",
|
||||
"xdg",
|
||||
|
@ -45,7 +45,7 @@ log = "0.4"
|
||||
maud = "0.23"
|
||||
peach-lib = { path = "../peach-lib" }
|
||||
# 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" }
|
||||
rouille = { version = "3.5", default-features = false }
|
||||
temporary = "0.6"
|
||||
|
@ -200,6 +200,10 @@ pub fn mount_peachpub_routes(
|
||||
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}) => {
|
||||
routes::settings::theme::set_theme(theme)
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
pub mod admin;
|
||||
//pub mod dns;
|
||||
pub mod menu;
|
||||
//pub mod network;
|
||||
pub mod network;
|
||||
pub mod scuttlebutt;
|
||||
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