use std::prelude::v1::*;
use std::sync::Arc;
#[cfg(feature = "oidc")]
use product_os_oauth_oidc::ProductOSOIDCServer;
#[cfg(feature = "authentication")]
use product_os_authentication::{Authentication, ProductOSAuthentication};
#[cfg(feature = "content")]
use product_os_content::ProductOSContentPlatform;
use crate::error::ProductOSServerError;
use crate::ProductOSServer;
#[cfg(feature = "controller")]
use product_os_async_executor;
impl<E, X> ProductOSServer<(), E, X>
where
E: product_os_async_executor::Executor<X> + product_os_async_executor::ExecutorPerform<X> + product_os_async_executor::Timer + 'static,
{
#[cfg(all(feature = "service_handler", feature = "controller"))]
pub async fn try_add_handler_service(&mut self, name: String, path: String, table_name: String, identifier_name: String) -> crate::error::Result<()> {
let controller = self.try_get_controller()?;
let handler = product_os_service_handler::ProductOSServiceHandler::new(name, path, table_name, identifier_name, controller);
let handler_name = handler.get_identifier_name();
handler.load_service(&mut self.router).await;
#[cfg(feature = "core")]
tracing::info!("Handler Service {} successfully added to server", handler_name);
Ok(())
}
#[cfg(all(feature = "oidc", feature = "controller"))]
pub async fn try_add_oidc(&mut self, identifier: String, base: Option<String>) -> crate::error::Result<()> {
let base_path = base.unwrap_or_else(|| "/auth".to_string());
let relational_store = self.try_get_relational_store()
.map_err(|e| ProductOSServerError::ControllerError {
operation: "add_oidc".to_string(),
message: alloc::format!("Failed to get relational store for OIDC: {}", e),
})?;
let controller_arc = self.try_get_controller()?;
let mut controller = controller_arc.lock();
let oidc_server = ProductOSOIDCServer::new(identifier, controller.get_configuration().get_oidc_configuration(), relational_store.clone());
let oidc_server_arc = Arc::new(oidc_server);
match product_os_oauth_oidc::setup_oidc_store(relational_store.clone()).await {
Ok(_) => {
#[cfg(feature = "core")]
tracing::info!("Database setup for OIDC complete");
}
Err(e) => {
#[cfg(feature = "core")]
tracing::error!("Error setting up database for OIDC: {:?}", e);
return Err(ProductOSServerError::ControllerError {
operation: "add_oidc".to_string(),
message: format!("Failed to complete database setup for OIDC: {:?}", e),
});
}
}
controller.add_feature(oidc_server_arc.clone(), base_path, &mut self.router).await;
#[cfg(feature = "core")]
tracing::info!("OIDC successfully added to server");
Ok(())
}
#[cfg(all(feature = "authentication", feature = "controller"))]
pub async fn try_add_authentication(&mut self, base: Option<String>, oidc_base: Option<String>) -> crate::error::Result<()> {
let base_path = base.unwrap_or_else(|| "/authentication".to_string());
let oidc_base_path = oidc_base.unwrap_or_else(|| "/oidc".to_string());
let relational_store = self.try_get_relational_store()
.map_err(|e| ProductOSServerError::ControllerError {
operation: "add_authentication".to_string(),
message: alloc::format!("Failed to get relational store for authentication: {}", e),
})?;
let auth_config: Authentication = match &self.config.authentication {
Some(value) => serde_json::from_value(value.clone()).map_err(|e| ProductOSServerError::ControllerError {
operation: "add_authentication".to_string(),
message: format!("Invalid authentication configuration: {e}"),
})?,
None => Authentication::default(),
};
let controller_arc = self.try_get_controller()?;
let authentication = ProductOSAuthentication::new(
&auth_config,
relational_store.clone(),
Some(controller_arc),
);
let auth_arc = Arc::new(authentication);
match product_os_authentication::setup_auth_store(relational_store.clone(), auth_config.scopes, auth_arc.clone()).await {
Ok(_) => {
#[cfg(feature = "core")]
tracing::info!("Database setup for user authentication complete");
}
Err(e) => {
#[cfg(feature = "core")]
tracing::error!("Error setting up database for user authentication: {:?}", e);
return Err(ProductOSServerError::ControllerError {
operation: "add_authentication".to_string(),
message: format!("Failed to complete database setup for user authentication: {:?}", e),
});
}
}
let _ = oidc_base_path;
self.try_add_feature(auth_arc, Some(base_path)).await?;
#[cfg(feature = "core")]
tracing::info!("Authentication successfully added to server");
Ok(())
}
#[cfg(all(feature = "content", feature = "controller"))]
pub async fn try_add_content_platform(&mut self, base: Option<String>, auth_base: Option<String>) -> crate::error::Result<()> {
let base_path = base.unwrap_or_default();
let auth_base_path = auth_base.unwrap_or_else(|| "/authentication".to_string());
let relational_store = self.try_get_relational_store()
.map_err(|e| ProductOSServerError::ControllerError {
operation: "add_content_platform".to_string(),
message: alloc::format!("Failed to get relational store for content platform: {}", e),
})?;
let key_value_store = self.try_get_key_value_store()
.map_err(|e| ProductOSServerError::ControllerError {
operation: "add_content_platform".to_string(),
message: alloc::format!("Failed to get key-value store for content platform: {}", e),
})?;
let controller_arc = self.try_get_controller()?;
let content_platform = ProductOSContentPlatform::new(
relational_store.clone(),
Some(key_value_store.clone()),
Some(controller_arc.clone()),
auth_base_path,
);
let content_platform_arc = Arc::new(content_platform);
match product_os_content::setup_content_store(relational_store.clone()).await {
Ok(_) => {
#[cfg(feature = "core")]
tracing::info!("Database setup for content platform complete");
}
Err(e) => {
#[cfg(feature = "core")]
tracing::error!("Error setting up database for content platform: {:?}", e);
return Err(ProductOSServerError::ControllerError {
operation: "add_content_platform".to_string(),
message: format!("Failed to complete database setup for content platform: {:?}", e),
});
}
}
let mut controller = controller_arc.lock();
controller.add_feature(content_platform_arc.clone(), base_path, &mut self.router).await;
#[cfg(feature = "core")]
tracing::info!("Content Platform successfully added to server");
Ok(())
}
}