[pbs-devel] [PATCH proxmox-backup v2 09/16] make get_index and ApiConfig property (callback)
Dietmar Maurer
dietmar at proxmox.com
Tue Sep 21 07:58:47 CEST 2021
---
proxmox-rest-server/src/api_config.rs | 18 +++++-
src/bin/proxmox-backup-api.rs | 21 +++++++
src/bin/proxmox-backup-proxy.rs | 81 ++++++++++++++++++++++++++-
src/bin/proxmox-restore-daemon.rs | 22 +++++++-
src/server/rest.rs | 80 +-------------------------
5 files changed, 142 insertions(+), 80 deletions(-)
diff --git a/proxmox-rest-server/src/api_config.rs b/proxmox-rest-server/src/api_config.rs
index a319e204..fee94e88 100644
--- a/proxmox-rest-server/src/api_config.rs
+++ b/proxmox-rest-server/src/api_config.rs
@@ -5,7 +5,9 @@ use std::fs::metadata;
use std::sync::{Arc, Mutex, RwLock};
use anyhow::{bail, Error, format_err};
-use hyper::Method;
+use hyper::{Method, Body, Response};
+use hyper::http::request::Parts;
+
use handlebars::Handlebars;
use serde::Serialize;
@@ -14,6 +16,8 @@ use proxmox::tools::fs::{create_path, CreateOptions};
use crate::{ApiAuth, FileLogger, FileLogOptions, CommandoSocket};
+pub type GetIndexFn = fn(Option<String>, Option<String>, &ApiConfig, Parts) -> Response<Body>;
+
pub struct ApiConfig {
basedir: PathBuf,
router: &'static Router,
@@ -23,6 +27,7 @@ pub struct ApiConfig {
template_files: RwLock<HashMap<String, (SystemTime, PathBuf)>>,
request_log: Option<Arc<Mutex<FileLogger>>>,
pub api_auth: Arc<dyn ApiAuth + Send + Sync>,
+ get_index_fn: GetIndexFn,
}
impl ApiConfig {
@@ -31,6 +36,7 @@ impl ApiConfig {
router: &'static Router,
env_type: RpcEnvironmentType,
api_auth: Arc<dyn ApiAuth + Send + Sync>,
+ get_index_fn: GetIndexFn,
) -> Result<Self, Error> {
Ok(Self {
basedir: basedir.into(),
@@ -41,9 +47,19 @@ impl ApiConfig {
template_files: RwLock::new(HashMap::new()),
request_log: None,
api_auth,
+ get_index_fn,
})
}
+ pub fn get_index(
+ &self,
+ auth_id: Option<String>,
+ language: Option<String>,
+ parts: Parts,
+ ) -> Response<Body> {
+ (self.get_index_fn)(auth_id, language, self, parts)
+ }
+
pub fn find_method(
&self,
components: &[&str],
diff --git a/src/bin/proxmox-backup-api.rs b/src/bin/proxmox-backup-api.rs
index 17b6f184..3bc02639 100644
--- a/src/bin/proxmox-backup-api.rs
+++ b/src/bin/proxmox-backup-api.rs
@@ -1,5 +1,9 @@
use anyhow::{bail, Error};
use futures::*;
+use http::request::Parts;
+use http::Response;
+use hyper::{Body, StatusCode};
+use hyper::header;
use proxmox::try_block;
use proxmox::api::RpcEnvironmentType;
@@ -27,6 +31,22 @@ fn main() {
}
}
+fn get_index(
+ _auth_id: Option<String>,
+ _language: Option<String>,
+ _api: &ApiConfig,
+ _parts: Parts,
+) -> Response<Body> {
+
+ let index = "<center><h1>Proxmox Backup API Server</h1></center>";
+
+ Response::builder()
+ .status(StatusCode::OK)
+ .header(header::CONTENT_TYPE, "text/html")
+ .body(index.into())
+ .unwrap()
+}
+
async fn run() -> Result<(), Error> {
if let Err(err) = syslog::init(
syslog::Facility::LOG_DAEMON,
@@ -65,6 +85,7 @@ async fn run() -> Result<(), Error> {
&proxmox_backup::api2::ROUTER,
RpcEnvironmentType::PRIVILEGED,
default_api_auth(),
+ get_index,
)?;
let backup_user = pbs_config::backup_user()?;
diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs
index d4ac2a85..6a4fddef 100644
--- a/src/bin/proxmox-backup-proxy.rs
+++ b/src/bin/proxmox-backup-proxy.rs
@@ -4,10 +4,15 @@ use std::os::unix::io::AsRawFd;
use anyhow::{bail, format_err, Error};
use futures::*;
+use http::request::Parts;
+use http::Response;
+use hyper::{Body, StatusCode};
+use hyper::header;
+use url::form_urlencoded;
use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype};
use tokio_stream::wrappers::ReceiverStream;
-use serde_json::Value;
+use serde_json::{json, Value};
use proxmox::try_block;
use proxmox::api::RpcEnvironmentType;
@@ -73,6 +78,79 @@ fn main() -> Result<(), Error> {
pbs_runtime::main(run())
}
+fn get_index(
+ auth_id: Option<String>,
+ language: Option<String>,
+ api: &ApiConfig,
+ parts: Parts,
+) -> Response<Body> {
+
+ let (userid, csrf_token) = match auth_id {
+ Some(auth_id) => {
+ let auth_id = auth_id.parse::<Authid>();
+ match auth_id {
+ Ok(auth_id) if !auth_id.is_token() => {
+ let userid = auth_id.user().clone();
+ let new_csrf_token = assemble_csrf_prevention_token(csrf_secret(), &userid);
+ (Some(userid), Some(new_csrf_token))
+ }
+ _ => (None, None)
+ }
+ }
+ None => (None, None),
+ };
+
+ let nodename = proxmox::tools::nodename();
+ let user = userid.as_ref().map(|u| u.as_str()).unwrap_or("");
+
+ let csrf_token = csrf_token.unwrap_or_else(|| String::from(""));
+
+ let mut debug = false;
+ let mut template_file = "index";
+
+ 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 != "0" && v != "false" {
+ debug = true;
+ } else if k == "console" {
+ template_file = "console";
+ }
+ }
+ }
+
+ let mut lang = String::from("");
+ if let Some(language) = language {
+ if Path::new(&format!("/usr/share/pbs-i18n/pbs-lang-{}.js", language)).exists() {
+ lang = language;
+ }
+ }
+
+ let data = json!({
+ "NodeName": nodename,
+ "UserName": user,
+ "CSRFPreventionToken": csrf_token,
+ "language": lang,
+ "debug": debug,
+ });
+
+ let (ct, index) = match api.render_template(template_file, &data) {
+ Ok(index) => ("text/html", index),
+ Err(err) => ("text/plain", format!("Error rendering template: {}", err)),
+ };
+
+ let mut resp = Response::builder()
+ .status(StatusCode::OK)
+ .header(header::CONTENT_TYPE, ct)
+ .body(index.into())
+ .unwrap();
+
+ if let Some(userid) = userid {
+ resp.extensions_mut().insert(Authid::from((userid, None)));
+ }
+
+ resp
+}
+
async fn run() -> Result<(), Error> {
if let Err(err) = syslog::init(
syslog::Facility::LOG_DAEMON,
@@ -93,6 +171,7 @@ async fn run() -> Result<(), Error> {
&proxmox_backup::api2::ROUTER,
RpcEnvironmentType::PUBLIC,
default_api_auth(),
+ get_index,
)?;
config.add_alias("novnc", "/usr/share/novnc-pve");
diff --git a/src/bin/proxmox-restore-daemon.rs b/src/bin/proxmox-restore-daemon.rs
index c5122cff..d9a8eff0 100644
--- a/src/bin/proxmox-restore-daemon.rs
+++ b/src/bin/proxmox-restore-daemon.rs
@@ -13,6 +13,10 @@ use lazy_static::lazy_static;
use log::{error, info};
use tokio::sync::mpsc;
use tokio_stream::wrappers::ReceiverStream;
+use http::request::Parts;
+use http::Response;
+use hyper::{Body, StatusCode};
+use hyper::header;
use proxmox::api::RpcEnvironmentType;
@@ -89,13 +93,29 @@ fn setup_system_env() -> Result<(), Error> {
Ok(())
}
+fn get_index(
+ _auth_id: Option<String>,
+ _language: Option<String>,
+ _api: &ApiConfig,
+ _parts: Parts,
+) -> Response<Body> {
+
+ let index = "<center><h1>Proxmox Backup Restore Daemon/h1></center>";
+
+ Response::builder()
+ .status(StatusCode::OK)
+ .header(header::CONTENT_TYPE, "text/html")
+ .body(index.into())
+ .unwrap()
+}
+
async fn run() -> Result<(), Error> {
watchdog_init();
let auth_config = Arc::new(
auth::ticket_auth().map_err(|err| format_err!("reading ticket file failed: {}", err))?,
);
- let config = ApiConfig::new("", &ROUTER, RpcEnvironmentType::PUBLIC, auth_config)?;
+ let config = ApiConfig::new("", &ROUTER, RpcEnvironmentType::PUBLIC, auth_config, get_index)?;
let rest_server = RestServer::new(config);
let vsock_fd = get_vsock_fd()?;
diff --git a/src/server/rest.rs b/src/server/rest.rs
index 3cc6bccb..9ed0eb32 100644
--- a/src/server/rest.rs
+++ b/src/server/rest.rs
@@ -15,7 +15,7 @@ use hyper::http::request::Parts;
use hyper::{Body, Request, Response, StatusCode};
use lazy_static::lazy_static;
use regex::Regex;
-use serde_json::{json, Value};
+use serde_json::Value;
use tokio::fs::File;
use tokio::time::Instant;
use url::form_urlencoded;
@@ -42,8 +42,6 @@ use proxmox_rest_server::formatter::*;
use pbs_config::CachedUserInfo;
-use crate::auth_helpers::*;
-
extern "C" {
fn tzset();
}
@@ -468,78 +466,6 @@ pub async fn handle_api_request<Env: RpcEnvironment, S: 'static + BuildHasher +
Ok(resp)
}
-fn get_index(
- auth_id: Option<String>,
- language: Option<String>,
- api: &Arc<ApiConfig>,
- parts: Parts,
-) -> Response<Body> {
-
- let (userid, csrf_token) = match auth_id {
- Some(auth_id) => {
- let auth_id = auth_id.parse::<Authid>();
- match auth_id {
- Ok(auth_id) if !auth_id.is_token() => {
- let userid = auth_id.user().clone();
- let new_csrf_token = assemble_csrf_prevention_token(csrf_secret(), &userid);
- (Some(userid), Some(new_csrf_token))
- }
- _ => (None, None)
- }
- }
- None => (None, None),
- };
-
- let nodename = proxmox::tools::nodename();
- let user = userid.as_ref().map(|u| u.as_str()).unwrap_or("");
-
- let csrf_token = csrf_token.unwrap_or_else(|| String::from(""));
-
- let mut debug = false;
- let mut template_file = "index";
-
- 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 != "0" && v != "false" {
- debug = true;
- } else if k == "console" {
- template_file = "console";
- }
- }
- }
-
- let mut lang = String::from("");
- if let Some(language) = language {
- if Path::new(&format!("/usr/share/pbs-i18n/pbs-lang-{}.js", language)).exists() {
- lang = language;
- }
- }
-
- let data = json!({
- "NodeName": nodename,
- "UserName": user,
- "CSRFPreventionToken": csrf_token,
- "language": lang,
- "debug": debug,
- });
-
- let (ct, index) = match api.render_template(template_file, &data) {
- Ok(index) => ("text/html", index),
- Err(err) => ("text/plain", format!("Error rendering template: {}", err)),
- };
-
- let mut resp = Response::builder()
- .status(StatusCode::OK)
- .header(header::CONTENT_TYPE, ct)
- .body(index.into())
- .unwrap();
-
- if let Some(userid) = userid {
- resp.extensions_mut().insert(Authid::from((userid, None)));
- }
-
- resp
-}
fn extension_to_content_type(filename: &Path) -> (&'static str, bool) {
if let Some(ext) = filename.extension().and_then(|osstr| osstr.to_str()) {
@@ -802,14 +728,14 @@ async fn handle_request(
let language = extract_lang_header(&parts.headers);
match auth.check_auth(&parts.headers, &method) {
Ok(auth_id) => {
- return Ok(get_index(Some(auth_id), language, &api, parts));
+ return Ok(api.get_index(Some(auth_id), language, parts));
}
Err(AuthError::Generic(_)) => {
tokio::time::sleep_until(Instant::from_std(delay_unauth_time)).await;
}
Err(AuthError::NoData) => {}
}
- return Ok(get_index(None, language, &api, parts));
+ return Ok(api.get_index(None, language, parts));
} else {
let filename = api.find_alias(&components);
let compression = extract_compression_method(&parts.headers);
--
2.30.2
More information about the pbs-devel
mailing list