peach-workspace/peach-web/src/public_router.rs

104 lines
3.7 KiB
Rust

use log::{error, info};
use rouille::{router, Request, Response};
use crate::{
private_router, routes,
utils::{flash::FlashResponse, sbot},
SessionData,
};
/// Request handler.
///
/// Mount the fileservers for static assets and define the
/// publically-accessible routes (including per-route handlers). Includes
/// logging of all incoming requests.
///
/// If the request is for a private route (ie. a route requiring successful
/// authentication to view), check the authentication status of the user
/// by querying the `session_data`. If the user is authenticated, pass their
/// request to the private router. Otherwise, redirect them to the login page.
pub fn handle_route(request: &Request, session_data: &mut Option<SessionData>) -> Response {
// static file server
// matches on assets in the `static` directory
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);
}
// get the current time (for logging purposes)
let now = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S%.6f");
// define the success logger for incoming requests
let log_ok = |req: &Request, _resp: &Response, _elap: std::time::Duration| {
info!("{} {} {}", now, req.method(), req.raw_url());
};
// define the error logger for incoming requests
let log_err = |req: &Request, _elap: std::time::Duration| {
error!(
"{} Handler panicked: {} {}",
now,
req.method(),
req.raw_url()
);
};
// instantiate request logging
rouille::log_custom(request, log_ok, log_err, || {
// handle the routes which are always accessible (ie. whether logged-in
// or not)
router!(request,
(GET) (/auth/forgot) => {
Response::html(routes::authentication::forgot::build_template(request))
.reset_flash()
},
(GET) (/auth/login) => {
Response::html(routes::authentication::login::build_template(request))
.reset_flash()
},
(POST) (/auth/login) => {
routes::authentication::login::handle_form(request, session_data)
},
(GET) (/auth/reset) => {
Response::html(routes::authentication::reset::build_template(request))
.reset_flash()
},
(POST) (/auth/reset) => {
routes::authentication::reset::handle_form(request)
},
(POST) (/auth/temporary) => {
routes::authentication::temporary::handle_form()
},
_ => {
// now that we handled all the routes that are accessible in all
// circumstances, we check that the user is logged in before proceeding
if let Some(_session) = session_data.as_ref() {
// logged in:
// mount the routes which require authentication to view
private_router::mount_peachpub_routes(request, session_data)
} else {
// not logged in:
Response::redirect_303("/auth/login")
}
}
)
})
}