2021-11-04 13:10:41 +00:00
|
|
|
//! # peach-web
|
|
|
|
//!
|
|
|
|
//! `peach-web` provides a web interface for monitoring and interacting with the
|
|
|
|
//! PeachCloud device. This allows administration of the single-board computer
|
|
|
|
//! (ie. Raspberry Pi) running PeachCloud, as well as the ssb-server and related
|
|
|
|
//! plugins.
|
|
|
|
//!
|
|
|
|
//! ## Design
|
|
|
|
//!
|
|
|
|
//! `peach-web` is written primarily in Rust and presents a web interface for
|
|
|
|
//! interacting with the device. The stack currently consists of Rocket (Rust
|
|
|
|
//! web framework), Tera (Rust template engine inspired by Jinja2 and the Django
|
|
|
|
//! template language), HTML, CSS and JavaScript. Additional functionality is
|
|
|
|
//! provided by JSON-RPC clients for the `peach-network` and `peach-stats`
|
|
|
|
//! microservices.
|
|
|
|
//!
|
|
|
|
//! 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
|
2021-11-04 21:30:29 +00:00
|
|
|
//! unobstructive design principles. Each Tera template is passed a context
|
2021-11-04 13:10:41 +00:00
|
|
|
//! 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.
|
2021-08-06 17:58:40 +00:00
|
|
|
|
2021-11-04 13:10:41 +00:00
|
|
|
#![feature(proc_macro_hygiene, decl_macro)]
|
2021-08-06 17:58:40 +00:00
|
|
|
|
2021-11-04 13:10:41 +00:00
|
|
|
pub mod error;
|
|
|
|
pub mod routes;
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests;
|
|
|
|
pub mod utils;
|
2021-08-06 17:58:40 +00:00
|
|
|
|
2021-11-15 09:59:25 +00:00
|
|
|
use log::{error, info};
|
2021-11-04 21:39:40 +00:00
|
|
|
use std::process;
|
2021-11-04 13:10:41 +00:00
|
|
|
|
2021-11-15 09:59:25 +00:00
|
|
|
use rocket::{catchers, fs::FileServer, routes, Build, Rocket};
|
2021-11-04 13:10:41 +00:00
|
|
|
use rocket_dyn_templates::Template;
|
|
|
|
|
|
|
|
use crate::routes::authentication::*;
|
2021-11-08 14:00:27 +00:00
|
|
|
use crate::routes::catchers::*;
|
2021-11-04 13:10:41 +00:00
|
|
|
use crate::routes::index::*;
|
|
|
|
use crate::routes::scuttlebutt::*;
|
2021-11-15 15:32:21 +00:00
|
|
|
use crate::routes::status::device::*;
|
2021-11-16 13:50:42 +00:00
|
|
|
use crate::routes::status::network::*;
|
2021-11-04 13:10:41 +00:00
|
|
|
|
|
|
|
use crate::routes::settings::admin::*;
|
|
|
|
use crate::routes::settings::dns::*;
|
2021-11-15 15:32:21 +00:00
|
|
|
use crate::routes::settings::menu::*;
|
2021-11-04 13:10:41 +00:00
|
|
|
use crate::routes::settings::network::*;
|
2021-11-15 18:58:13 +00:00
|
|
|
use crate::routes::settings::scuttlebutt::*;
|
2021-11-04 21:39:40 +00:00
|
|
|
|
2021-11-04 13:10:41 +00:00
|
|
|
pub type BoxError = Box<dyn std::error::Error>;
|
|
|
|
|
|
|
|
/// Create rocket instance & mount all routes.
|
|
|
|
fn init_rocket() -> Rocket<Build> {
|
|
|
|
rocket::build()
|
2021-11-15 15:32:21 +00:00
|
|
|
// GENERAL HTML ROUTES
|
|
|
|
.mount(
|
|
|
|
"/",
|
|
|
|
routes![
|
|
|
|
help,
|
|
|
|
home,
|
|
|
|
login,
|
|
|
|
login_post,
|
|
|
|
logout,
|
|
|
|
reboot_cmd,
|
|
|
|
shutdown_cmd,
|
|
|
|
power_menu,
|
|
|
|
settings_menu,
|
|
|
|
],
|
|
|
|
)
|
2021-11-16 13:50:42 +00:00
|
|
|
// STATUS HTML ROUTES
|
|
|
|
.mount("/status", routes![device_status, network_status])
|
2021-11-15 15:32:21 +00:00
|
|
|
// ADMIN SETTINGS HTML ROUTES
|
|
|
|
.mount(
|
|
|
|
"/settings/admin",
|
|
|
|
routes![
|
2021-11-15 18:58:13 +00:00
|
|
|
admin_menu,
|
2021-11-15 15:32:21 +00:00
|
|
|
configure_admin,
|
|
|
|
add_admin,
|
|
|
|
add_admin_post,
|
|
|
|
delete_admin_post,
|
|
|
|
change_password,
|
|
|
|
change_password_post,
|
|
|
|
reset_password,
|
|
|
|
reset_password_post,
|
|
|
|
forgot_password_page,
|
|
|
|
send_password_reset_post,
|
|
|
|
],
|
|
|
|
)
|
|
|
|
// NETWORK SETTINGS HTML ROUTES
|
|
|
|
.mount(
|
|
|
|
"/settings/network",
|
|
|
|
routes![
|
|
|
|
add_credentials,
|
|
|
|
connect_wifi,
|
|
|
|
configure_dns,
|
|
|
|
configure_dns_post,
|
|
|
|
disconnect_wifi,
|
|
|
|
deploy_ap,
|
|
|
|
deploy_client,
|
|
|
|
forget_wifi,
|
|
|
|
network_home,
|
|
|
|
add_ssid,
|
|
|
|
add_wifi,
|
|
|
|
network_detail,
|
|
|
|
wifi_list,
|
|
|
|
wifi_password,
|
|
|
|
wifi_set_password,
|
|
|
|
wifi_usage,
|
|
|
|
wifi_usage_alerts,
|
|
|
|
wifi_usage_reset,
|
|
|
|
],
|
|
|
|
)
|
2021-11-15 18:58:13 +00:00
|
|
|
// SCUTTLEBUTT SETTINGS HTML ROUTES
|
|
|
|
.mount("/settings/scuttlebutt", routes![ssb_settings_menu])
|
|
|
|
// SCUTTLEBUTT SOCIAL HTML ROUTES
|
2021-11-15 09:59:25 +00:00
|
|
|
.mount(
|
|
|
|
"/scuttlebutt",
|
|
|
|
routes![
|
2021-11-15 15:32:21 +00:00
|
|
|
peers, friends, follows, followers, blocks, profile, private, follow, unfollow,
|
|
|
|
block, publish,
|
2021-11-15 09:59:25 +00:00
|
|
|
],
|
|
|
|
)
|
2021-11-04 13:10:41 +00:00
|
|
|
.mount("/", FileServer::from("static"))
|
2021-11-08 14:00:27 +00:00
|
|
|
.register("/", catchers![not_found, internal_error, forbidden])
|
2021-11-04 13:10:41 +00:00
|
|
|
.attach(Template::fairing())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Launch the peach-web rocket server.
|
|
|
|
#[rocket::main]
|
|
|
|
async fn main() {
|
|
|
|
// initialize logger
|
2021-08-06 17:58:40 +00:00
|
|
|
env_logger::init();
|
|
|
|
|
2021-11-04 21:30:29 +00:00
|
|
|
// initialize rocket
|
2021-11-04 13:10:41 +00:00
|
|
|
info!("Initializing Rocket");
|
|
|
|
let rocket = init_rocket();
|
|
|
|
|
2021-11-04 21:30:29 +00:00
|
|
|
// launch rocket
|
2021-11-04 13:10:41 +00:00
|
|
|
info!("Launching Rocket");
|
2021-11-15 09:59:25 +00:00
|
|
|
if let Err(e) = rocket.launch().await {
|
2021-11-04 21:39:40 +00:00
|
|
|
error!("Error in Rocket application: {}", e);
|
|
|
|
process::exit(1);
|
|
|
|
}
|
2021-08-06 17:58:40 +00:00
|
|
|
}
|