change index to templates using handlebars
using a handlebars instance in ApiConfig, to cache the templates as long as possible, this is currently ok, as the index template can only change when the whole package changes if we split this in the future, we have to trigger a reload of the daemon on gui package upgrade (so that the template gets reloaded) Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
bc0d03885c
commit
f9e3b1104e
@ -22,6 +22,7 @@ endian_trait = { version = "0.6", features = ["arrays"] }
|
||||
anyhow = "1.0"
|
||||
futures = "0.3"
|
||||
h2 = { version = "0.2", features = ["stream"] }
|
||||
handlebars = "3.0"
|
||||
http = "0.2"
|
||||
hyper = "0.13"
|
||||
lazy_static = "1.4"
|
||||
|
1
debian/proxmox-backup-server.install
vendored
1
debian/proxmox-backup-server.install
vendored
@ -5,6 +5,7 @@ usr/lib/x86_64-linux-gnu/proxmox-backup/proxmox-backup-api
|
||||
usr/lib/x86_64-linux-gnu/proxmox-backup/proxmox-backup-proxy
|
||||
usr/lib/x86_64-linux-gnu/proxmox-backup/proxmox-backup-banner
|
||||
usr/sbin/proxmox-backup-manager
|
||||
usr/share/javascript/proxmox-backup/index.hbs
|
||||
usr/share/javascript/proxmox-backup/css/ext6-pbs.css
|
||||
usr/share/javascript/proxmox-backup/images/logo-128.png
|
||||
usr/share/javascript/proxmox-backup/images/proxmox_logo.png
|
||||
|
@ -45,7 +45,7 @@ async fn run() -> Result<(), Error> {
|
||||
let _ = csrf_secret(); // load with lazy_static
|
||||
|
||||
let config = server::ApiConfig::new(
|
||||
buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PRIVILEGED);
|
||||
buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PRIVILEGED)?;
|
||||
|
||||
let rest_server = RestServer::new(config);
|
||||
|
||||
|
@ -34,7 +34,7 @@ async fn run() -> Result<(), Error> {
|
||||
let _ = csrf_secret(); // load with lazy_static
|
||||
|
||||
let mut config = ApiConfig::new(
|
||||
buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PUBLIC);
|
||||
buildcfg::JS_DIR, &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PUBLIC)?;
|
||||
|
||||
// add default dirs which includes jquery and bootstrap
|
||||
// my $base = '/usr/share/libpve-http-server-perl';
|
||||
|
@ -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<String, PathBuf>,
|
||||
env_type: RpcEnvironmentType,
|
||||
pub templates: Handlebars<'static>,
|
||||
}
|
||||
|
||||
impl ApiConfig {
|
||||
|
||||
pub fn new<B: Into<PathBuf>>(basedir: B, router: &'static Router, env_type: RpcEnvironmentType) -> Self {
|
||||
Self {
|
||||
basedir: basedir.into(),
|
||||
pub fn new<B: Into<PathBuf>>(basedir: B, router: &'static Router, env_type: RpcEnvironmentType) -> Result<Self, Error> {
|
||||
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(
|
||||
|
@ -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<Env: RpcEnvironment, S: 'static + BuildHasher +
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
fn get_index(username: Option<String>, token: Option<String>) -> Response<Body> {
|
||||
fn get_index(username: Option<String>, token: Option<String>, template: &Handlebars, parts: Parts) -> Response<Body> {
|
||||
|
||||
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###"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>Proxmox Backup Server</title>
|
||||
<link rel="icon" sizes="128x128" href="/images/logo-128.png" />
|
||||
<link rel="apple-touch-icon" sizes="128x128" href="/pve2/images/logo-128.png" />
|
||||
<link rel="stylesheet" type="text/css" href="/extjs/theme-crisp/resources/theme-crisp-all.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/extjs/crisp/resources/charts-all.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/fontawesome/css/font-awesome.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ext6-pbs.css" />
|
||||
<script type='text/javascript'> function gettext(buf) {{ return buf; }} </script>
|
||||
<script type="text/javascript" src="/extjs/ext-all-debug.js"></script>
|
||||
<script type="text/javascript" src="/extjs/charts-debug.js"></script>
|
||||
<script type="text/javascript">
|
||||
Proxmox = {};
|
||||
</script>
|
||||
<script type="text/javascript" src="/widgettoolkit/proxmoxlib.js"></script>
|
||||
<script type="text/javascript" src="/extjs/locale/locale-en.js"></script>
|
||||
<script type="text/javascript">
|
||||
Ext.History.fieldid = 'x-history-field';
|
||||
</script>
|
||||
<script type="text/javascript" src="/js/proxmox-backup-gui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Fields required for history management -->
|
||||
<form id="history-form" class="x-hidden">
|
||||
<input type="hidden" id="x-history-field"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
"###, 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<ApiConfig>, req: Request<Body>) -> Result<R
|
||||
match check_auth(&method, &ticket, &token, &user_info) {
|
||||
Ok(username) => {
|
||||
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);
|
||||
|
@ -36,8 +36,9 @@ clean:
|
||||
find . -name '*~' -exec rm {} ';'
|
||||
rm -rf js
|
||||
|
||||
install: js/proxmox-backup-gui.js css/ext6-pbs.css
|
||||
install: js/proxmox-backup-gui.js css/ext6-pbs.css index.hbs
|
||||
install -dm755 $(DESTDIR)$(JSDIR)
|
||||
install -m644 index.hbs $(DESTDIR)$(JSDIR)/
|
||||
install -dm755 $(DESTDIR)$(JSDIR)/js
|
||||
install -m644 js/proxmox-backup-gui.js $(DESTDIR)$(JSDIR)/js/
|
||||
install -dm755 $(DESTDIR)$(JSDIR)/css
|
||||
|
43
www/index.hbs
Normal file
43
www/index.hbs
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>Proxmox Backup Server</title>
|
||||
<link rel="icon" sizes="128x128" href="/images/logo-128.png" />
|
||||
<link rel="apple-touch-icon" sizes="128x128" href="/pve2/images/logo-128.png" />
|
||||
<link rel="stylesheet" type="text/css" href="/extjs/theme-crisp/resources/theme-crisp-all.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/extjs/crisp/resources/charts-all.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/fontawesome/css/font-awesome.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/css/ext6-pbs.css" />
|
||||
<script type='text/javascript'> function gettext(buf) { return buf; } </script>
|
||||
{{#if debug}}
|
||||
<script type="text/javascript" src="/extjs/ext-all-debug.js"></script>
|
||||
<script type="text/javascript" src="/extjs/charts-debug.js"></script>
|
||||
{{else}}
|
||||
<script type="text/javascript" src="/extjs/ext-all.js"></script>
|
||||
<script type="text/javascript" src="/extjs/charts.js"></script>
|
||||
{{/if}}
|
||||
<script type="text/javascript">
|
||||
Proxmox = {
|
||||
Setup: { auth_cookie_name: 'PBSAuthCookie' },
|
||||
NodeName: "{{ NodeName }}",
|
||||
UserName: "{{ UserName }}",
|
||||
CSRFPreventionToken: "{{ CSRFPreventionToken }}",
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" src="/widgettoolkit/proxmoxlib.js"></script>
|
||||
<script type="text/javascript" src="/extjs/locale/locale-en.js"></script>
|
||||
<script type="text/javascript">
|
||||
Ext.History.fieldid = 'x-history-field';
|
||||
</script>
|
||||
<script type="text/javascript" src="/js/proxmox-backup-gui.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Fields required for history management -->
|
||||
<form id="history-form" class="x-hidden">
|
||||
<input type="hidden" id="x-history-field"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user