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, Option, &ApiConfig, Parts) -> Response; + pub struct ApiConfig { basedir: PathBuf, router: &'static Router, @@ -23,6 +27,7 @@ pub struct ApiConfig { template_files: RwLock>, request_log: Option>>, pub api_auth: Arc, + get_index_fn: GetIndexFn, } impl ApiConfig { @@ -31,6 +36,7 @@ impl ApiConfig { router: &'static Router, env_type: RpcEnvironmentType, api_auth: Arc, + get_index_fn: GetIndexFn, ) -> Result { 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, + language: Option, + parts: Parts, + ) -> Response { + (self.get_index_fn)(auth_id, language, self, parts) + } + pub fn find_method( &self, components: &[&str], 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, - language: Option, - api: &Arc, - parts: Parts, -) -> Response { - - let (userid, csrf_token) = match auth_id { - Some(auth_id) => { - let auth_id = auth_id.parse::(); - 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);