#[cfg(feature = "rest-api-actix")]
mod actix;
mod config;
mod error;
mod resources;
use std::sync::Arc;
use crate::database::ConnectionPool;
use crate::rest_api::{Resource, RestResourceProvider};
#[cfg(all(
feature = "biome-key-management",
feature = "rest-api-actix",
feature = "json-web-tokens"
))]
use self::actix::key_management::{
make_key_management_route, make_key_management_route_with_public_key,
};
#[cfg(feature = "biome-key-management")]
use super::key_management::store::PostgresKeyStore;
use super::user::store::diesel::SplinterUserStore;
#[cfg(feature = "json-web-tokens")]
use crate::rest_api::secrets::{AutoSecretManager, SecretManager};
pub use config::{BiomeRestConfig, BiomeRestConfigBuilder};
pub use error::BiomeRestResourceManagerBuilderError;
#[cfg(all(feature = "biome-credentials", feature = "rest-api-actix"))]
use self::actix::register::make_register_route;
#[cfg(all(
feature = "biome-credentials",
feature = "rest-api-actix",
feature = "json-web-tokens"
))]
use self::actix::{
login::make_login_route,
user::{make_list_route, make_user_routes},
verify::make_verify_route,
};
#[cfg(feature = "biome-credentials")]
use super::credentials::store::diesel::SplinterCredentialsStore;
#[allow(unused_imports)]
#[cfg(feature = "json-web-tokens")]
use crate::rest_api::sessions::AccessTokenIssuer;
pub struct BiomeRestResourceManager {
#[allow(dead_code)]
user_store: SplinterUserStore,
#[cfg(all(feature = "biome-key-management", feature = "json-web-tokens"))]
key_store: Arc<PostgresKeyStore>,
#[allow(dead_code)]
rest_config: Arc<BiomeRestConfig>,
#[allow(dead_code)]
#[cfg(feature = "json-web-tokens")]
token_secret_manager: Arc<dyn SecretManager>,
#[cfg(feature = "biome-credentials")]
credentials_store: Option<Arc<SplinterCredentialsStore>>,
}
impl RestResourceProvider for BiomeRestResourceManager {
fn resources(&self) -> Vec<Resource> {
#[allow(unused_mut)]
let mut resources = Vec::new();
#[cfg(all(
feature = "biome-credentials",
feature = "rest-api-actix",
feature = "json-web-tokens"
))]
match &self.credentials_store {
Some(credentials_store) => {
resources.push(make_register_route(
credentials_store.clone(),
self.user_store.clone(),
self.rest_config.clone(),
));
resources.push(make_login_route(
credentials_store.clone(),
self.rest_config.clone(),
Arc::new(AccessTokenIssuer::new(self.token_secret_manager.clone())),
));
resources.push(make_user_routes(
self.rest_config.clone(),
self.token_secret_manager.clone(),
credentials_store.clone(),
self.user_store.clone(),
));
resources.push(make_list_route(credentials_store.clone()));
resources.push(make_verify_route(
credentials_store.clone(),
self.rest_config.clone(),
self.token_secret_manager.clone(),
));
}
None => {
debug!(
"Credentials store not provided. Credentials REST API resources will not be'
' included in the biome endpoints."
);
}
};
#[cfg(all(feature = "biome-credentials", feature = "rest-api-actix"))]
match &self.credentials_store {
Some(credentials_store) => {
resources.push(make_register_route(
credentials_store.clone(),
self.user_store.clone(),
self.rest_config.clone(),
));
}
None => {
debug!(
"Credentials store not provided. Credentials REST API resources will not be'
' included in the biome endpoints."
);
}
};
#[cfg(all(
feature = "biome-key-management",
feature = "rest-api-actix",
feature = "json-web-tokens"
))]
{
resources.push(make_key_management_route(
self.rest_config.clone(),
self.key_store.clone(),
self.token_secret_manager.clone(),
));
resources.push(make_key_management_route_with_public_key(
self.rest_config.clone(),
self.key_store.clone(),
self.token_secret_manager.clone(),
));
}
resources
}
}
#[derive(Default)]
pub struct BiomeRestResourceManagerBuilder {
user_store: Option<SplinterUserStore>,
#[cfg(feature = "biome-key-management")]
key_store: Option<PostgresKeyStore>,
rest_config: Option<BiomeRestConfig>,
#[cfg(feature = "json-web-tokens")]
token_secret_manager: Option<Arc<dyn SecretManager>>,
#[cfg(feature = "biome-credentials")]
credentials_store: Option<SplinterCredentialsStore>,
}
impl BiomeRestResourceManagerBuilder {
pub fn with_user_store(mut self, pool: ConnectionPool) -> BiomeRestResourceManagerBuilder {
self.user_store = Some(SplinterUserStore::new(pool));
self
}
#[cfg(feature = "biome-key-management")]
pub fn with_key_store(mut self, pool: ConnectionPool) -> BiomeRestResourceManagerBuilder {
self.key_store = Some(PostgresKeyStore::new(pool));
self
}
pub fn with_rest_config(mut self, config: BiomeRestConfig) -> BiomeRestResourceManagerBuilder {
self.rest_config = Some(config);
self
}
#[cfg(feature = "biome-credentials")]
pub fn with_credentials_store(
mut self,
pool: ConnectionPool,
) -> BiomeRestResourceManagerBuilder {
self.credentials_store = Some(SplinterCredentialsStore::new(pool));
self
}
#[cfg(feature = "json-web-tokens")]
pub fn set_token_secret_manager(
mut self,
secret_manager: impl SecretManager + 'static,
) -> BiomeRestResourceManagerBuilder {
self.token_secret_manager = Some(Arc::new(secret_manager));
self
}
pub fn build(self) -> Result<BiomeRestResourceManager, BiomeRestResourceManagerBuilderError> {
let user_store = self.user_store.ok_or_else(|| {
BiomeRestResourceManagerBuilderError::MissingRequiredField(
"Missing user store".to_string(),
)
})?;
#[cfg(all(feature = "biome-key-management", feature = "json-web-tokens"))]
let key_store = self.key_store.ok_or_else(|| {
BiomeRestResourceManagerBuilderError::MissingRequiredField(
"MissingKeyStore".to_string(),
)
})?;
let rest_config = match self.rest_config {
Some(config) => config,
None => {
debug!("Building BiomeRestResourceManager with default config.");
BiomeRestConfigBuilder::default().build()?
}
};
#[cfg(feature = "json-web-tokens")]
let token_secret_manager = self.token_secret_manager.unwrap_or_else(|| {
debug!("Building BiomeRestResourceManager with default SecretManager.");
Arc::new(AutoSecretManager::default())
});
Ok(BiomeRestResourceManager {
user_store,
#[cfg(all(feature = "biome-key-management", feature = "json-web-tokens"))]
key_store: Arc::new(key_store),
rest_config: Arc::new(rest_config),
#[cfg(feature = "json-web-tokens")]
token_secret_manager,
#[cfg(feature = "biome-credentials")]
credentials_store: match self.credentials_store {
Some(credentials_store) => Some(Arc::new(credentials_store)),
None => {
debug!("Building BiomeRestResourceManager without credentials store");
None
}
},
})
}
}