]> git.proxmox.com Git - proxmox-backup.git/blobdiff - proxmox-rest-server/src/api_config.rs
proxmox-rest-server: improve docs
[proxmox-backup.git] / proxmox-rest-server / src / api_config.rs
index fee94e887a35f8ab5c96706f7f3475ab08984ca4..712c591b96c585686bbb2385c735cf6bf88fefc5 100644 (file)
@@ -18,6 +18,7 @@ use crate::{ApiAuth, FileLogger, FileLogOptions, CommandoSocket};
 
 pub type GetIndexFn = fn(Option<String>, Option<String>, &ApiConfig, Parts) -> Response<Body>;
 
+/// REST server configuration
 pub struct ApiConfig {
     basedir: PathBuf,
     router: &'static Router,
@@ -26,11 +27,26 @@ pub struct ApiConfig {
     templates: RwLock<Handlebars<'static>>,
     template_files: RwLock<HashMap<String, (SystemTime, PathBuf)>>,
     request_log: Option<Arc<Mutex<FileLogger>>>,
-    pub api_auth: Arc<dyn ApiAuth + Send + Sync>,
+    auth_log: Option<Arc<Mutex<FileLogger>>>,
+    pub(crate) api_auth: Arc<dyn ApiAuth + Send + Sync>,
     get_index_fn: GetIndexFn,
 }
 
 impl ApiConfig {
+    /// Creates a new instance
+    ///
+    /// `basedir` - File lookups are relative to this directory.
+    ///
+    /// `router` - The REST API definition.
+    ///
+    /// `env_type` - The environment type.
+    ///
+    /// `api_auth` - The Authentification handler
+    ///
+    /// `get_index_fn` - callback to generate the root page
+    /// (index). Please note that this fuctions gets a reference to
+    /// the [ApiConfig], so it can use [Handlebars] templates
+    /// ([render_template](Self::render_template) to generate pages.
     pub fn new<B: Into<PathBuf>>(
         basedir: B,
         router: &'static Router,
@@ -46,12 +62,13 @@ impl ApiConfig {
             templates: RwLock::new(Handlebars::new()),
             template_files: RwLock::new(HashMap::new()),
             request_log: None,
+            auth_log: None,
             api_auth,
             get_index_fn,
         })
     }
 
-    pub fn get_index(
+    pub(crate) fn get_index(
         &self,
         auth_id: Option<String>,
         language: Option<String>,
@@ -60,7 +77,7 @@ impl ApiConfig {
         (self.get_index_fn)(auth_id, language, self, parts)
     }
 
-    pub fn find_method(
+    pub(crate) fn find_method(
         &self,
         components: &[&str],
         method: Method,
@@ -70,7 +87,7 @@ impl ApiConfig {
         self.router.find_method(components, method, uri_param)
     }
 
-    pub fn find_alias(&self, components: &[&str]) -> PathBuf {
+    pub(crate) fn find_alias(&self, components: &[&str]) -> PathBuf {
 
         let mut prefix = String::new();
         let mut filename = self.basedir.clone();
@@ -87,6 +104,18 @@ impl ApiConfig {
         filename
     }
 
+    /// Register a path alias
+    ///
+    /// This can be used to redirect file lookups to a specific
+    /// directory, e.g.:
+    ///
+    /// ```
+    /// use proxmox_rest_server::ApiConfig;
+    /// // let mut config = ApiConfig::new(...);
+    /// # fn fake(config: &mut ApiConfig) {
+    /// config.add_alias("extjs", "/usr/share/javascript/extjs");
+    /// # }
+    /// ```
     pub fn add_alias<S, P>(&mut self, alias: S, path: P)
         where S: Into<String>,
               P: Into<PathBuf>,
@@ -94,10 +123,13 @@ impl ApiConfig {
         self.aliases.insert(alias.into(), path.into());
     }
 
-    pub fn env_type(&self) -> RpcEnvironmentType {
+    pub(crate) fn env_type(&self) -> RpcEnvironmentType {
         self.env_type
     }
 
+    /// Register a [Handlebars] template file
+    ///
+    /// Those templates cane be use with [render_template](Self::render_template) to generate pages.
     pub fn register_template<P>(&self, name: &str, path: P) -> Result<(), Error>
     where
         P: Into<PathBuf>
@@ -146,7 +178,12 @@ impl ApiConfig {
         }
     }
 
-    pub fn enable_file_log<P>(
+    /// Enable the access log feature
+    ///
+    /// When enabled, all requests are logged to the specified file.
+    /// This function also registers a `api-access-log-reopen`
+    /// command one the [CommandoSocket].
+    pub fn enable_access_log<P>(
         &mut self,
         path: P,
         dir_opts: Option<CreateOptions>,
@@ -172,7 +209,7 @@ impl ApiConfig {
         self.request_log = Some(Arc::clone(&request_log));
 
         commando_sock.register_command("api-access-log-reopen".into(), move |_args| {
-            println!("re-opening log file");
+            println!("re-opening access-log file");
             request_log.lock().unwrap().reopen()?;
             Ok(serde_json::Value::Null)
         })?;
@@ -180,7 +217,51 @@ impl ApiConfig {
         Ok(())
     }
 
-    pub fn get_file_log(&self) -> Option<&Arc<Mutex<FileLogger>>> {
+    /// Enable the authentification log feature
+    ///
+    /// When enabled, all authentification requests are logged to the
+    /// specified file. This function also registers a
+    /// `api-auth-log-reopen` command one the [CommandoSocket].
+    pub fn enable_auth_log<P>(
+        &mut self,
+        path: P,
+        dir_opts: Option<CreateOptions>,
+        file_opts: Option<CreateOptions>,
+        commando_sock: &mut CommandoSocket,
+    ) -> Result<(), Error>
+    where
+        P: Into<PathBuf>
+    {
+        let path: PathBuf = path.into();
+        if let Some(base) = path.parent() {
+            if !base.exists() {
+                create_path(base, None, dir_opts).map_err(|err| format_err!("{}", err))?;
+            }
+        }
+
+        let logger_options = FileLogOptions {
+            append: true,
+            prefix_time: true,
+            file_opts: file_opts.unwrap_or(CreateOptions::default()),
+            ..Default::default()
+        };
+        let auth_log = Arc::new(Mutex::new(FileLogger::new(&path, logger_options)?));
+        self.auth_log = Some(Arc::clone(&auth_log));
+
+        commando_sock.register_command("api-auth-log-reopen".into(), move |_args| {
+            println!("re-opening auth-log file");
+            auth_log.lock().unwrap().reopen()?;
+            Ok(serde_json::Value::Null)
+        })?;
+
+        Ok(())
+    }
+
+    pub(crate) fn get_access_log(&self) -> Option<&Arc<Mutex<FileLogger>>> {
         self.request_log.as_ref()
     }
+
+    pub(crate) fn get_auth_log(&self) -> Option<&Arc<Mutex<FileLogger>>> {
+        self.auth_log.as_ref()
+    }
 }