diff --git a/src/server/config.rs b/src/server/config.rs index d9aa076c..e8b3c946 100644 --- a/src/server/config.rs +++ b/src/server/config.rs @@ -1,7 +1,9 @@ use std::collections::HashMap; use std::path::{PathBuf}; +use anyhow::Error; use hyper::Method; +use handlebars::Handlebars; use proxmox::api::{ApiMethod, Router, RpcEnvironmentType}; @@ -10,17 +12,22 @@ pub struct ApiConfig { router: &'static Router, aliases: HashMap, env_type: RpcEnvironmentType, + pub templates: Handlebars<'static>, } impl ApiConfig { - pub fn new>(basedir: B, router: &'static Router, env_type: RpcEnvironmentType) -> Self { - Self { - basedir: basedir.into(), + pub fn new>(basedir: B, router: &'static Router, env_type: RpcEnvironmentType) -> Result { + let mut templates = Handlebars::new(); + let basedir = basedir.into(); + templates.register_template_file("index", basedir.join("index.hbs"))?; + Ok(Self { + basedir, router, aliases: HashMap::new(), env_type, - } + templates + }) } pub fn find_method( diff --git a/src/server/rest.rs b/src/server/rest.rs index f648af3a..95f73191 100644 --- a/src/server/rest.rs +++ b/src/server/rest.rs @@ -16,6 +16,7 @@ use serde_json::{json, Value}; use tokio::fs::File; use tokio::time::Instant; use url::form_urlencoded; +use handlebars::Handlebars; use proxmox::http_err; use proxmox::api::{ApiHandler, ApiMethod, HttpError}; @@ -311,59 +312,43 @@ pub async fn handle_api_request, token: Option) -> Response { +fn get_index(username: Option, token: Option, template: &Handlebars, parts: Parts) -> Response { let nodename = proxmox::tools::nodename(); let username = username.unwrap_or_else(|| String::from("")); let token = token.unwrap_or_else(|| String::from("")); - let setup = json!({ - "Setup": { "auth_cookie_name": "PBSAuthCookie" }, + let mut debug = false; + + if let Some(query_str) = parts.uri.query() { + for (k, v) in form_urlencoded::parse(query_str.as_bytes()).into_owned() { + if k == "debug" && v == "1" || v == "true" { + debug = true; + } + } + } + + let data = json!({ "NodeName": nodename, "UserName": username, "CSRFPreventionToken": token, + "debug": debug, }); - let index = format!(r###" - - - - - - - Proxmox Backup Server - - - - - - - - - - - - - - - - - -
- -
- - -"###, setup.to_string()); + let mut ct = "text/html"; + + let index = match template.render("index", &data) { + Ok(index) => index, + Err(err) => { + ct = "text/plain"; + format!("Error rendering template: {}", err.desc) + }, + }; Response::builder() .status(StatusCode::OK) - .header(header::CONTENT_TYPE, "text/html") + .header(header::CONTENT_TYPE, ct) .body(index.into()) .unwrap() } @@ -595,15 +580,15 @@ pub async fn handle_request(api: Arc, req: Request) -> Result { let new_token = assemble_csrf_prevention_token(csrf_secret(), &username); - return Ok(get_index(Some(username), Some(new_token))); + return Ok(get_index(Some(username), Some(new_token), &api.templates, parts)); } _ => { tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await; - return Ok(get_index(None, None)); + return Ok(get_index(None, None, &api.templates, parts)); } } } else { - return Ok(get_index(None, None)); + return Ok(get_index(None, None, &api.templates, parts)); } } else { let filename = api.find_alias(&components);