pub type GetIndexFn = fn(Option<String>, Option<String>, &ApiConfig, Parts) -> Response<Body>;
+/// REST server configuration
pub struct ApiConfig {
basedir: PathBuf,
router: &'static Router,
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,
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>,
(self.get_index_fn)(auth_id, language, self, parts)
}
- pub fn find_method(
+ pub(crate) fn find_method(
&self,
components: &[&str],
method: Method,
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();
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>,
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>
}
}
- 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>,
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)
})?;
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()
+ }
}