use body::parse_dispatch_body;
mod body;
mod builder;
mod builtin;
mod endpoint;
mod http;
mod http_hooks;
use alibi_core::{
AuthConfig, AuthContext, AuthError, AuthInitContext, AuthPlugin, AuthRequest, AuthResponse,
AuthResult, AuthRoute, AuthSchema, AuthStore, BeforeRequestAction, EmailProvider,
HttpEndpointResponse, HttpMethod, HttpRequestAction, OkResponse, OpenApiBuilder,
OpenApiRegistry, OpenApiSpec, SessionManager, core_paths,
hooks::{RequestHookContext, with_request_hook_context_value},
middleware::{
self, BodyLimitConfig, BodyLimitMiddleware, CorsConfig, CorsMiddleware, CsrfConfig,
CsrfMiddleware, Middleware, RateLimitConfig, RateLimitMiddleware,
},
};
use std::sync::Arc;
pub struct Alibi<S: AuthSchema> {
config: Arc<AuthConfig>,
telemetry: crate::telemetry::TelemetryConfig,
pub(super) plugins: Vec<Box<dyn AuthPlugin<S>>>,
transport_middlewares: Vec<Box<dyn Middleware>>,
middlewares: Vec<Box<dyn Middleware>>,
cors: CorsMiddleware,
request_protection: CsrfMiddleware,
body_limit: BodyLimitConfig,
store: Arc<dyn AuthStore<S>>,
session_manager: SessionManager<S>,
pub(super) context: AuthContext<S>,
openapi: Arc<OpenApiRegistry>,
pub(super) endpoint_hooks: Vec<Arc<dyn alibi_core::endpoint::EndpointHook<S>>>,
}
impl<S: AuthSchema> std::fmt::Debug for Alibi<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Alibi").finish_non_exhaustive()
}
}
pub struct AuthBuilder<S: AuthSchema> {
config: AuthConfig,
telemetry: crate::telemetry::TelemetryConfig,
store: Option<Arc<dyn AuthStore<S>>>,
has_external_store: bool,
plugins: Vec<Box<dyn AuthPlugin<S>>>,
csrf_config: Option<CsrfConfig>,
rate_limit_config: Option<RateLimitConfig>,
cors_config: Option<CorsConfig>,
body_limit_config: Option<BodyLimitConfig>,
custom_middlewares: Vec<Box<dyn Middleware>>,
endpoint_hooks: Vec<Arc<dyn alibi_core::endpoint::EndpointHook<S>>>,
}
impl<S: AuthSchema> std::fmt::Debug for AuthBuilder<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AuthBuilder").finish_non_exhaustive()
}
}
impl<S: AuthSchema> AuthBuilder<S> {
#[must_use]
pub fn telemetry(mut self, telemetry: crate::telemetry::TelemetryConfig) -> Self {
self.telemetry = telemetry;
self
}
#[must_use]
pub const fn csrf(mut self, config: CsrfConfig) -> Self {
self.csrf_config = Some(config);
self
}
#[must_use]
pub const fn body_limit(mut self, config: BodyLimitConfig) -> Self {
self.body_limit_config = Some(config);
self
}
}
impl<S: AuthSchema> Alibi<S> {
pub async fn publish_telemetry(&self, event: crate::telemetry::TelemetryEvent) {
self.telemetry.publish(event).await;
}
#[must_use]
pub fn config(&self) -> &AuthConfig {
&self.config
}
#[must_use]
pub const fn context(&self) -> &AuthContext<S> {
&self.context
}
#[must_use]
pub const fn body_limit(&self) -> &BodyLimitConfig {
&self.body_limit
}
#[must_use]
pub const fn session_manager(&self) -> &SessionManager<S> {
&self.session_manager
}
#[must_use]
pub fn routes(&self) -> Vec<(String, &dyn AuthPlugin<S>)> {
let mut routes = Vec::new();
for plugin in &self.plugins {
for route in plugin.routes() {
routes.push((route.path, plugin.as_ref()));
}
}
routes
}
#[must_use]
pub fn registered_routes(&self) -> Vec<AuthRoute> {
self.openapi.registered_routes()
}
#[must_use]
pub fn plugins(&self) -> &[Box<dyn AuthPlugin<S>>] {
&self.plugins
}
#[must_use]
pub fn get_plugin(&self, name: &str) -> Option<&dyn AuthPlugin<S>> {
self.plugins
.iter()
.find(|p| p.name() == name)
.map(AsRef::as_ref)
}
#[must_use]
pub fn plugin_names(&self) -> Vec<&'static str> {
self.plugins.iter().map(|p| p.name()).collect()
}
#[must_use]
pub fn openapi_spec(&self) -> OpenApiSpec {
OpenApiBuilder::registered(&self.config, &self.openapi).build()
}
#[must_use]
pub fn openapi_spec_with_native_extensions(&self) -> OpenApiSpec {
OpenApiBuilder::registered_with_native_extensions(&self.config, &self.openapi, true).build()
}
}