Skip to main content

sova_scope/
plugin.rs

1//! ScopeAuth plugin install.
2
3use crate::engine::{AuthorizeEngine, SharedEngine};
4use crate::matrix::MatrixBuilder;
5use crate::owner::OwnerRegistry;
6use sova_core::{App, Plugin};
7use sova_db::DbHandle;
8use std::future::Future;
9use std::sync::Arc;
10
11type ConfigureFn = Box<dyn FnOnce(&mut MatrixBuilder) + Send>;
12
13pub struct ScopeAuthState {
14    pub engine: SharedEngine,
15}
16
17pub struct ScopeAuth {
18    configure_fn: Option<ConfigureFn>,
19    owners: OwnerRegistry,
20}
21
22impl ScopeAuth {
23    pub fn new() -> Self {
24        Self {
25            configure_fn: None,
26            owners: OwnerRegistry::default(),
27        }
28    }
29
30    pub fn configure(mut self, f: impl FnOnce(&mut MatrixBuilder) + Send + 'static) -> Self {
31        self.configure_fn = Some(Box::new(f));
32        self
33    }
34
35    pub fn owner<F, Fut>(mut self, kind: &'static str, f: F) -> Self
36    where
37        F: Fn(DbHandle, i64) -> Fut + Send + Sync + 'static,
38        Fut: Future<Output = sova_core::Result<Option<i64>>> + Send + 'static,
39    {
40        self.owners.register(kind, crate::owner::callback_owner(f));
41        self
42    }
43}
44
45impl Default for ScopeAuth {
46    fn default() -> Self {
47        Self::new()
48    }
49}
50
51impl Plugin for ScopeAuth {
52    fn id(&self) -> &'static str {
53        "scope"
54    }
55
56    fn requires(&self) -> &'static [&'static str] {
57        &["db"]
58    }
59
60    fn meta(&self) -> sova_core::PluginMeta {
61        sova_core::PluginMeta::new("ScopeAuth")
62            .description("Scoped RBAC: membership, role matrix, ownership hooks, cache, audit")
63            .version(env!("CARGO_PKG_VERSION"))
64    }
65
66    fn install(self, app: &mut App) {
67        let mut builder = MatrixBuilder::default();
68        if let Some(f) = self.configure_fn {
69            f(&mut builder);
70        }
71        let matrices = builder.build();
72        let engine = Arc::new(AuthorizeEngine::new(matrices, self.owners));
73        app.state(ScopeAuthState { engine });
74    }
75}