use std::collections::BTreeSet;
use std::sync::Arc;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::prelude::*;
mod attrunique;
mod base;
mod cred_import;
mod default_values;
mod domain;
pub(crate) mod dyngroup;
mod eckeygen;
pub(crate) mod gidnumber;
mod jwskeygen;
mod keyobject;
mod memberof;
mod namehistory;
mod protected;
mod refint;
mod session;
mod spn;
mod valuedeny;
trait Plugin {
fn id() -> &'static str;
fn pre_create_transform(
_qs: &mut QueryServerWriteTransaction,
_cand: &mut Vec<EntryInvalidNew>,
_ce: &CreateEvent,
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented pre_create_transform!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn pre_create(
_qs: &mut QueryServerWriteTransaction,
_cand: &[EntrySealedNew],
_ce: &CreateEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented pre_create!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_create(
_qs: &mut QueryServerWriteTransaction,
_cand: &[EntrySealedCommitted],
_ce: &CreateEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented post_create!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn pre_modify(
_qs: &mut QueryServerWriteTransaction,
_pre_cand: &[Arc<EntrySealedCommitted>],
_cand: &mut Vec<EntryInvalidCommitted>,
_me: &ModifyEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented pre_modify!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_modify(
_qs: &mut QueryServerWriteTransaction,
_pre_cand: &[Arc<EntrySealedCommitted>],
_cand: &[EntrySealedCommitted],
_ce: &ModifyEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented post_modify!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn pre_batch_modify(
_qs: &mut QueryServerWriteTransaction,
_pre_cand: &[Arc<EntrySealedCommitted>],
_cand: &mut Vec<EntryInvalidCommitted>,
_me: &BatchModifyEvent,
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented pre_batch_modify!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_batch_modify(
_qs: &mut QueryServerWriteTransaction,
_pre_cand: &[Arc<EntrySealedCommitted>],
_cand: &[EntrySealedCommitted],
_me: &BatchModifyEvent,
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented post_batch_modify!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn pre_delete(
_qs: &mut QueryServerWriteTransaction,
_cand: &mut Vec<EntryInvalidCommitted>,
_de: &DeleteEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented pre_delete!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_delete(
_qs: &mut QueryServerWriteTransaction,
_cand: &[EntrySealedCommitted],
_ce: &DeleteEvent,
) -> Result<(), OperationError> {
admin_error!("plugin {} has an unimplemented post_delete!", Self::id());
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn pre_repl_refresh(
_qs: &mut QueryServerWriteTransaction,
_cand: &[EntryRefreshNew],
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented pre_repl_refresh!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_repl_refresh(
_qs: &mut QueryServerWriteTransaction,
_cand: &[EntrySealedCommitted],
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented post_repl_refresh!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_repl_incremental_conflict(
_qs: &mut QueryServerWriteTransaction,
_cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
_conflict_uuids: &mut BTreeSet<Uuid>,
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented post_repl_incremental_conflict!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn post_repl_incremental(
_qs: &mut QueryServerWriteTransaction,
_pre_cand: &[Arc<EntrySealedCommitted>],
_cand: &[EntrySealedCommitted],
_conflict_uuids: &BTreeSet<Uuid>,
) -> Result<(), OperationError> {
admin_error!(
"plugin {} has an unimplemented post_repl_incremental!",
Self::id()
);
debug_assert!(false);
Err(OperationError::InvalidState)
}
fn verify(_qs: &mut QueryServerReadTransaction) -> Vec<Result<(), ConsistencyError>> {
admin_error!("plugin {} has an unimplemented verify!", Self::id());
vec![Err(ConsistencyError::Unknown)]
}
}
pub struct Plugins {}
macro_rules! run_verify_plugin {
(
$qs:ident,
$results:expr,
$target_plugin:ty
) => {{
let mut r = <$target_plugin>::verify($qs);
$results.append(&mut r);
}};
}
impl Plugins {
#[instrument(level = "debug", name = "plugins::run_pre_create_transform", skip_all)]
pub fn run_pre_create_transform(
qs: &mut QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent,
) -> Result<(), OperationError> {
base::Base::pre_create_transform(qs, cand, ce)?;
valuedeny::ValueDeny::pre_create_transform(qs, cand, ce)?;
cred_import::CredImport::pre_create_transform(qs, cand, ce)?;
keyobject::KeyObjectManagement::pre_create_transform(qs, cand, ce)?;
jwskeygen::JwsKeygen::pre_create_transform(qs, cand, ce)?;
gidnumber::GidNumber::pre_create_transform(qs, cand, ce)?;
domain::Domain::pre_create_transform(qs, cand, ce)?;
spn::Spn::pre_create_transform(qs, cand, ce)?;
default_values::DefaultValues::pre_create_transform(qs, cand, ce)?;
namehistory::NameHistory::pre_create_transform(qs, cand, ce)?;
eckeygen::EcdhKeyGen::pre_create_transform(qs, cand, ce)?;
attrunique::AttrUnique::pre_create_transform(qs, cand, ce)
}
#[instrument(level = "debug", name = "plugins::run_pre_create", skip_all)]
pub fn run_pre_create(
qs: &mut QueryServerWriteTransaction,
cand: &[Entry<EntrySealed, EntryNew>],
ce: &CreateEvent,
) -> Result<(), OperationError> {
protected::Protected::pre_create(qs, cand, ce)
}
#[instrument(level = "debug", name = "plugins::run_post_create", skip_all)]
pub fn run_post_create(
qs: &mut QueryServerWriteTransaction,
cand: &[Entry<EntrySealed, EntryCommitted>],
ce: &CreateEvent,
) -> Result<(), OperationError> {
refint::ReferentialIntegrity::post_create(qs, cand, ce)?;
memberof::MemberOf::post_create(qs, cand, ce)
}
#[instrument(level = "debug", name = "plugins::run_pre_modify", skip_all)]
pub fn run_pre_modify(
qs: &mut QueryServerWriteTransaction,
pre_cand: &[Arc<EntrySealedCommitted>],
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
me: &ModifyEvent,
) -> Result<(), OperationError> {
protected::Protected::pre_modify(qs, pre_cand, cand, me)?;
base::Base::pre_modify(qs, pre_cand, cand, me)?;
valuedeny::ValueDeny::pre_modify(qs, pre_cand, cand, me)?;
cred_import::CredImport::pre_modify(qs, pre_cand, cand, me)?;
jwskeygen::JwsKeygen::pre_modify(qs, pre_cand, cand, me)?;
keyobject::KeyObjectManagement::pre_modify(qs, pre_cand, cand, me)?;
gidnumber::GidNumber::pre_modify(qs, pre_cand, cand, me)?;
domain::Domain::pre_modify(qs, pre_cand, cand, me)?;
spn::Spn::pre_modify(qs, pre_cand, cand, me)?;
session::SessionConsistency::pre_modify(qs, pre_cand, cand, me)?;
default_values::DefaultValues::pre_modify(qs, pre_cand, cand, me)?;
namehistory::NameHistory::pre_modify(qs, pre_cand, cand, me)?;
eckeygen::EcdhKeyGen::pre_modify(qs, pre_cand, cand, me)?;
attrunique::AttrUnique::pre_modify(qs, pre_cand, cand, me)
}
#[instrument(level = "debug", name = "plugins::run_post_modify", skip_all)]
pub fn run_post_modify(
qs: &mut QueryServerWriteTransaction,
pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
cand: &[Entry<EntrySealed, EntryCommitted>],
me: &ModifyEvent,
) -> Result<(), OperationError> {
refint::ReferentialIntegrity::post_modify(qs, pre_cand, cand, me)?;
spn::Spn::post_modify(qs, pre_cand, cand, me)?;
memberof::MemberOf::post_modify(qs, pre_cand, cand, me)
}
#[instrument(level = "debug", name = "plugins::run_pre_batch_modify", skip_all)]
pub fn run_pre_batch_modify(
qs: &mut QueryServerWriteTransaction,
pre_cand: &[Arc<EntrySealedCommitted>],
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
me: &BatchModifyEvent,
) -> Result<(), OperationError> {
protected::Protected::pre_batch_modify(qs, pre_cand, cand, me)?;
base::Base::pre_batch_modify(qs, pre_cand, cand, me)?;
valuedeny::ValueDeny::pre_batch_modify(qs, pre_cand, cand, me)?;
cred_import::CredImport::pre_batch_modify(qs, pre_cand, cand, me)?;
jwskeygen::JwsKeygen::pre_batch_modify(qs, pre_cand, cand, me)?;
keyobject::KeyObjectManagement::pre_batch_modify(qs, pre_cand, cand, me)?;
gidnumber::GidNumber::pre_batch_modify(qs, pre_cand, cand, me)?;
domain::Domain::pre_batch_modify(qs, pre_cand, cand, me)?;
spn::Spn::pre_batch_modify(qs, pre_cand, cand, me)?;
session::SessionConsistency::pre_batch_modify(qs, pre_cand, cand, me)?;
default_values::DefaultValues::pre_batch_modify(qs, pre_cand, cand, me)?;
namehistory::NameHistory::pre_batch_modify(qs, pre_cand, cand, me)?;
eckeygen::EcdhKeyGen::pre_batch_modify(qs, pre_cand, cand, me)?;
attrunique::AttrUnique::pre_batch_modify(qs, pre_cand, cand, me)
}
#[instrument(level = "debug", name = "plugins::run_post_batch_modify", skip_all)]
pub fn run_post_batch_modify(
qs: &mut QueryServerWriteTransaction,
pre_cand: &[Arc<Entry<EntrySealed, EntryCommitted>>],
cand: &[Entry<EntrySealed, EntryCommitted>],
me: &BatchModifyEvent,
) -> Result<(), OperationError> {
refint::ReferentialIntegrity::post_batch_modify(qs, pre_cand, cand, me)?;
spn::Spn::post_batch_modify(qs, pre_cand, cand, me)?;
memberof::MemberOf::post_batch_modify(qs, pre_cand, cand, me)
}
#[instrument(level = "debug", name = "plugins::run_pre_delete", skip_all)]
pub fn run_pre_delete(
qs: &mut QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
de: &DeleteEvent,
) -> Result<(), OperationError> {
protected::Protected::pre_delete(qs, cand, de)?;
memberof::MemberOf::pre_delete(qs, cand, de)
}
#[instrument(level = "debug", name = "plugins::run_post_delete", skip_all)]
pub fn run_post_delete(
qs: &mut QueryServerWriteTransaction,
cand: &[Entry<EntrySealed, EntryCommitted>],
de: &DeleteEvent,
) -> Result<(), OperationError> {
refint::ReferentialIntegrity::post_delete(qs, cand, de)?;
memberof::MemberOf::post_delete(qs, cand, de)
}
#[instrument(level = "debug", name = "plugins::run_pre_repl_refresh", skip_all)]
pub fn run_pre_repl_refresh(
qs: &mut QueryServerWriteTransaction,
cand: &[EntryRefreshNew],
) -> Result<(), OperationError> {
attrunique::AttrUnique::pre_repl_refresh(qs, cand)
}
#[instrument(level = "debug", name = "plugins::run_post_repl_refresh", skip_all)]
pub fn run_post_repl_refresh(
qs: &mut QueryServerWriteTransaction,
cand: &[EntrySealedCommitted],
) -> Result<(), OperationError> {
refint::ReferentialIntegrity::post_repl_refresh(qs, cand)?;
memberof::MemberOf::post_repl_refresh(qs, cand)
}
#[instrument(level = "debug", name = "plugins::run_pre_repl_incremental", skip_all)]
pub fn run_pre_repl_incremental(
_qs: &mut QueryServerWriteTransaction,
_cand: &mut [(EntryIncrementalCommitted, Arc<EntrySealedCommitted>)],
) -> Result<(), OperationError> {
Ok(())
}
#[instrument(
level = "debug",
name = "plugins::run_post_repl_incremental_conflict",
skip_all
)]
pub fn run_post_repl_incremental_conflict(
qs: &mut QueryServerWriteTransaction,
cand: &[(EntrySealedCommitted, Arc<EntrySealedCommitted>)],
conflict_uuids: &mut BTreeSet<Uuid>,
) -> Result<(), OperationError> {
attrunique::AttrUnique::post_repl_incremental_conflict(qs, cand, conflict_uuids)
}
#[instrument(level = "debug", name = "plugins::run_post_repl_incremental", skip_all)]
pub fn run_post_repl_incremental(
qs: &mut QueryServerWriteTransaction,
pre_cand: &[Arc<EntrySealedCommitted>],
cand: &[EntrySealedCommitted],
conflict_uuids: &BTreeSet<Uuid>,
) -> Result<(), OperationError> {
spn::Spn::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
refint::ReferentialIntegrity::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)?;
memberof::MemberOf::post_repl_incremental(qs, pre_cand, cand, conflict_uuids)
}
#[instrument(level = "debug", name = "plugins::run_verify", skip_all)]
pub fn run_verify(
qs: &mut QueryServerReadTransaction,
results: &mut Vec<Result<(), ConsistencyError>>,
) {
run_verify_plugin!(qs, results, base::Base);
run_verify_plugin!(qs, results, valuedeny::ValueDeny);
run_verify_plugin!(qs, results, attrunique::AttrUnique);
run_verify_plugin!(qs, results, refint::ReferentialIntegrity);
run_verify_plugin!(qs, results, keyobject::KeyObjectManagement);
run_verify_plugin!(qs, results, dyngroup::DynGroup);
run_verify_plugin!(qs, results, memberof::MemberOf);
run_verify_plugin!(qs, results, spn::Spn);
}
}