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
|
2022-03-10 09:09:26 +00:00
|
|
|
//! interacting with the device. The stack currently consists of Rouille (Rust
|
|
|
|
//! micro-web-framework), Maud (an HTML template engine for Rust), HTML and
|
|
|
|
//! CSS.
|
|
|
|
|
|
|
|
//mod context;
|
2022-03-11 12:27:40 +00:00
|
|
|
mod config;
|
2021-11-04 13:10:41 +00:00
|
|
|
pub mod error;
|
2022-03-20 15:17:17 +00:00
|
|
|
mod router;
|
2022-03-11 12:27:40 +00:00
|
|
|
mod routes;
|
2022-03-10 09:09:26 +00:00
|
|
|
//#[cfg(test)]
|
|
|
|
//mod tests;
|
|
|
|
mod templates;
|
2021-11-04 13:10:41 +00:00
|
|
|
pub mod utils;
|
2021-08-06 17:58:40 +00:00
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
use std::sync::RwLock;
|
2021-11-04 13:10:41 +00:00
|
|
|
|
2022-02-03 14:29:20 +00:00
|
|
|
use lazy_static::lazy_static;
|
2022-03-10 09:09:26 +00:00
|
|
|
//use log::{debug, error, info};
|
|
|
|
use log::info;
|
|
|
|
//use peach_lib::{config_manager, config_manager::YAML_PATH as PEACH_CONFIG};
|
|
|
|
//use rocket::{fairing::AdHoc, serde::Deserialize, Build, Rocket};
|
|
|
|
|
2022-03-11 12:27:40 +00:00
|
|
|
// crate-local dependencies
|
|
|
|
use config::Config;
|
2022-03-23 09:41:47 +00:00
|
|
|
use utils::{sbot, theme::Theme};
|
2022-02-03 14:29:20 +00:00
|
|
|
|
2021-11-04 13:10:41 +00:00
|
|
|
pub type BoxError = Box<dyn std::error::Error>;
|
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
/*
|
2022-01-18 14:58:13 +00:00
|
|
|
/// Application configuration parameters.
|
|
|
|
/// These values are extracted from Rocket's default configuration provider:
|
|
|
|
/// `Config::figment()`. As such, the values are drawn from `Rocket.toml` or
|
|
|
|
/// the TOML file path in the `ROCKET_CONFIG` environment variable. The TOML
|
|
|
|
/// file parameters are automatically overruled by any `ROCKET_` variables
|
|
|
|
/// which might be set.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct RocketConfig {
|
|
|
|
disable_auth: bool,
|
|
|
|
standalone_mode: bool,
|
2022-01-13 11:15:42 +00:00
|
|
|
}
|
2022-03-10 09:09:26 +00:00
|
|
|
*/
|
2022-01-13 11:15:42 +00:00
|
|
|
|
2022-03-23 09:41:47 +00:00
|
|
|
/// The path of the application configuration parameters.
|
2022-03-11 12:27:40 +00:00
|
|
|
static CONFIG_PATH: &str = "./config";
|
|
|
|
|
2022-02-03 14:29:20 +00:00
|
|
|
lazy_static! {
|
2022-03-11 12:27:40 +00:00
|
|
|
static ref CONFIG: Config = Config::from_file(CONFIG_PATH).expect("failed to read config file");
|
2022-02-03 14:29:20 +00:00
|
|
|
static ref THEME: RwLock<Theme> = RwLock::new(Theme::Light);
|
|
|
|
}
|
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
//static WLAN_IFACE: &str = "wlan0";
|
|
|
|
//static AP_IFACE: &str = "ap0";
|
2022-01-13 13:47:43 +00:00
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
/*
|
2022-01-13 11:15:42 +00:00
|
|
|
pub fn init_rocket() -> Rocket<Build> {
|
|
|
|
info!("Initializing Rocket");
|
2022-01-18 14:58:13 +00:00
|
|
|
// build a basic rocket instance
|
|
|
|
let rocket = rocket::build();
|
|
|
|
|
|
|
|
// return the default provider figment used by `rocket::build()`
|
|
|
|
let figment = rocket.figment();
|
|
|
|
|
|
|
|
// deserialize configuration parameters into our `RocketConfig` struct (defined above)
|
|
|
|
// since we're in the intialisation phase, panic if the extraction fails
|
|
|
|
let config: RocketConfig = figment.extract().expect("configuration extraction failed");
|
|
|
|
|
|
|
|
debug!("{:?}", config);
|
|
|
|
|
|
|
|
info!("Mounting Rocket routes");
|
|
|
|
let mounted_rocket = if config.standalone_mode {
|
|
|
|
router::mount_peachpub_routes(rocket)
|
2022-01-13 11:15:42 +00:00
|
|
|
} else {
|
2022-01-18 14:58:13 +00:00
|
|
|
router::mount_peachcloud_routes(rocket)
|
|
|
|
};
|
|
|
|
|
|
|
|
info!("Attaching application configuration to managed state");
|
|
|
|
mounted_rocket.attach(AdHoc::config::<RocketConfig>())
|
2021-11-04 13:10:41 +00:00
|
|
|
}
|
2022-03-10 09:09:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
const HOSTNAME_AND_PORT: &str = "localhost:8000";
|
2021-11-04 13:10:41 +00:00
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
/// Launch the peach-web server.
|
|
|
|
fn main() {
|
2021-11-04 13:10:41 +00:00
|
|
|
// initialize logger
|
2021-08-06 17:58:40 +00:00
|
|
|
env_logger::init();
|
|
|
|
|
2022-03-10 09:09:26 +00:00
|
|
|
/*
|
2022-03-07 09:26:52 +00:00
|
|
|
// check if /var/lib/peachcloud/config.yml exists
|
|
|
|
if !std::path::Path::new(PEACH_CONFIG).exists() {
|
|
|
|
info!("PeachCloud configuration file not found; loading default values");
|
|
|
|
// since we're in the intialisation phase, panic if the loading fails
|
|
|
|
let config =
|
|
|
|
config_manager::load_peach_config().expect("peachcloud configuration loading failed");
|
|
|
|
|
|
|
|
info!("Saving default PeachCloud configuration values to file");
|
|
|
|
// this ensures a config file is created if it does not already exist
|
|
|
|
config_manager::save_peach_config(config).expect("peachcloud configuration saving failed");
|
|
|
|
}
|
2022-03-10 09:09:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
info!("Launching web server...");
|
|
|
|
|
|
|
|
// the `start_server` starts listening forever on the given address.
|
|
|
|
rouille::start_server(HOSTNAME_AND_PORT, move |request| {
|
|
|
|
info!("Now listening on {}", HOSTNAME_AND_PORT);
|
|
|
|
|
|
|
|
// static file server
|
|
|
|
// matches on assets in the `static` directory
|
2022-03-23 09:41:47 +00:00
|
|
|
let static_response = rouille::match_assets(request, "static");
|
|
|
|
if static_response.is_success() {
|
|
|
|
return static_response;
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the `.ssb-go` path in order to mount the blob fileserver
|
|
|
|
let ssb_path = sbot::get_go_ssb_path().expect("define ssb-go dir path");
|
|
|
|
let blobstore = format!("{}/blobs/sha256", ssb_path);
|
|
|
|
|
|
|
|
// blobstore file server
|
|
|
|
// removes the /blob url prefix and serves blobs from blobstore
|
|
|
|
// matches on assets in the `static` directory
|
|
|
|
if let Some(request) = request.remove_prefix("/blob") {
|
|
|
|
return rouille::match_assets(&request, &blobstore);
|
2022-03-10 09:09:26 +00:00
|
|
|
}
|
|
|
|
|
2022-03-20 15:17:17 +00:00
|
|
|
router::mount_peachpub_routes(request)
|
2022-03-10 09:09:26 +00:00
|
|
|
});
|
2021-08-06 17:58:40 +00:00
|
|
|
}
|
2022-03-23 09:41:47 +00:00
|
|
|
|
|
|
|
// TODO: write a test for each route
|
|
|
|
// look at `init_test_rocket()` from old code
|
|
|
|
// https://docs.rs/rouille/latest/rouille/struct.Request.html#method.fake_http
|
|
|
|
/*
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
#[test]
|
|
|
|
fn it_works() {
|
|
|
|
assert_eq!(2 + 2, 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|