mod auth;
mod registry;
mod routes;
mod templates;
mod traits;
pub use registry::AdminRegistry;
pub use traits::{AdminAction, AdminField, AdminFieldKind, AdminModel};
use std::borrow::Cow;
use std::sync::Arc;
use autumn_web::app::AppBuilder;
use autumn_web::plugin::Plugin;
pub struct AdminPlugin {
registry: AdminRegistry,
prefix: String,
actuator_prefix: String,
auth_session_key: String,
require_role: Option<String>,
}
impl AdminPlugin {
#[must_use]
pub fn new() -> Self {
Self {
registry: AdminRegistry::new(),
prefix: "/admin".to_owned(),
actuator_prefix: "/actuator".to_owned(),
auth_session_key: "user_id".to_owned(),
require_role: Some("admin".to_owned()),
}
}
#[must_use]
pub fn prefix(mut self, prefix: impl Into<String>) -> Self {
self.prefix = prefix.into();
self
}
#[must_use]
pub fn actuator_prefix(mut self, prefix: impl Into<String>) -> Self {
self.actuator_prefix = prefix.into();
self
}
#[must_use]
pub fn auth_session_key(mut self, key: impl Into<String>) -> Self {
self.auth_session_key = key.into();
self
}
#[must_use]
pub fn require_role(mut self, role: impl Into<Option<String>>) -> Self {
self.require_role = role.into();
self
}
#[must_use]
pub fn register<M: AdminModel>(mut self, model: M) -> Self {
self.registry.register(model);
self
}
}
impl Default for AdminPlugin {
fn default() -> Self {
Self::new()
}
}
impl Plugin for AdminPlugin {
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("autumn-admin-plugin")
}
fn build(self, app: AppBuilder) -> AppBuilder {
let Self {
registry,
prefix,
actuator_prefix,
auth_session_key,
require_role,
} = self;
let registry = Arc::new(registry);
let router = routes::admin_router(
Arc::clone(®istry),
&prefix,
actuator_prefix.clone(),
auth_session_key.clone(),
require_role.clone(),
);
tracing::info!(
prefix = %prefix,
actuator_prefix = %actuator_prefix,
auth_session_key = %auth_session_key,
models = registry.model_count(),
role = require_role.as_deref().unwrap_or("<none>"),
"🍂 Autumn Admin mounted"
);
app.nest(&prefix, router)
}
}