Skip to main content

alibi_core/store/contracts/
hooks.rs

1use crate::AdapterRecord;
2use crate::{AuthResult, AuthSchema, AuthStore, CreateUser};
3use async_trait::async_trait;
4
5/// Registered model defaults applied by an adapter after its creation hooks.
6/// Keeping this phase separate preserves a validation candidate's absent fields.
7#[derive(Clone, Default)]
8pub struct UserCreationDefaults(pub(crate) Vec<UserCreateTransform>);
9impl UserCreationDefaults {
10    pub fn apply(self, data: CreateUser) -> AuthResult<CreateUser> {
11        create_data(data, &self.0)
12    }
13}
14
15/// Application/plugin adapter hook observing a successfully persisted session.
16/// Transactional hooks execute only after commit against the finalized store,
17/// including registered user transforms. Hook failures do not roll back commit.
18#[async_trait]
19pub trait SessionCreatedHook<S: AuthSchema>: Send + Sync {
20    async fn after_create(
21        &self,
22        session: &S::Session,
23        database: &dyn AuthStore<S>,
24    ) -> AuthResult<()>;
25}
26
27/// A persisted adapter result after declared output transforms. Hidden fields
28/// remain present; public response filtering has not run on this record.
29pub enum AdapterEvent<S: AuthSchema> {
30    UserCreated(AdapterRecord<S::User>),
31    UserUpdated(AdapterRecord<S::User>),
32    SessionCreated(AdapterRecord<S::Session>),
33    SessionUpdated(AdapterRecord<S::Session>),
34    AccountCreated(AdapterRecord<S::Account>),
35    AccountUpdated(AdapterRecord<S::Account>),
36}
37
38/// Record-aware application adapter after observer. Output errors prevent this
39/// observer; transaction observers run only after commit. Observer errors do not
40/// roll back committed writes. Typed physical storage hooks remain separate.
41#[async_trait]
42pub trait AdapterAfterHook<S: AuthSchema>: Send + Sync {
43    async fn after_write(
44        &self,
45        event: &AdapterEvent<S>,
46        database: &dyn AuthStore<S>,
47    ) -> AuthResult<()>;
48}
49
50use std::sync::Arc;
51
52pub(crate) type UserCreateTransform =
53    Arc<dyn Fn(CreateUser) -> AuthResult<CreateUser> + Send + Sync>;
54
55pub(in crate::store) fn create_data(
56    mut data: CreateUser,
57    transforms: &[UserCreateTransform],
58) -> AuthResult<CreateUser> {
59    for transform in transforms {
60        data = transform(data)?;
61    }
62    Ok(data)
63}