all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup rebase 09/15] make get_index and ApiConfig property (callback)
Date: Mon, 20 Sep 2021 11:13:34 +0200	[thread overview]
Message-ID: <20210920091340.3251578-9-dietmar@proxmox.com> (raw)
In-Reply-To: <20210920091340.3251578-1-dietmar@proxmox.com>

---
 pbs-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/pbs-server/src/api_config.rs b/pbs-server/src/api_config.rs
index a319e204..fee94e88 100644
--- a/pbs-server/src/api_config.rs
+++ b/pbs-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 fa846bc8..bb083b7d 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 c7435e1f..5e75ec72 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 45dd2c95..38c96194 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 a6db5155..659179c7 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 pbs_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





  parent reply	other threads:[~2021-09-20  9:14 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-20  9:13 [pbs-devel] [PATCH proxmox-backup rebase 01/15] start new pbs-server workspace Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 02/15] move ApiConfig, FileLogger and CommandoSocket to " Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 03/15] move src/tools/daemon.rs " Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 04/15] move src/server/environment.rs to pbs-server crate Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 05/15] move src/server/formatter.rs " Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 06/15] move src/tools/compression.rs " Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 07/15] move normalize_uri_path and extract_cookie " Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 08/15] rest server: simplify get_index() method signature Dietmar Maurer
2021-09-20  9:13 ` Dietmar Maurer [this message]
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 10/15] rest server: return UserInformation from ApiAuth::check_auth Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 11/15] rest server: do not use pbs_api_types::Authid Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 12/15] rest server: cleanup auth-log handling Dietmar Maurer
2021-09-20 10:37   ` Fabian Grünbichler
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 13/15] move src/server/rest.rs to pbs-server crate Dietmar Maurer
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 14/15] move proxmox_restore_daemon code into extra crate Dietmar Maurer
2021-09-20 12:01   ` Fabian Grünbichler
2021-09-20  9:13 ` [pbs-devel] [PATCH proxmox-backup rebase 15/15] basically a (semantic) revert of commit 991be99c37c6f55f43a3d9a2c54edb2a8dc6d4f2 "buildsys: workaround linkage issues from openid/curl build server stuff separate" Dietmar Maurer
2021-09-20 12:03 ` [pbs-devel] [PATCH proxmox-backup rebase 01/15] start new pbs-server workspace Fabian Grünbichler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210920091340.3251578-9-dietmar@proxmox.com \
    --to=dietmar@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal