Skip to main content

keyhog_core/
registry.rs

1//! Global registry for pluggable components (Sources, Verifiers).
2//! This allows adding new features in a single file without modifying the core.
3
4use crate::{DedupedMatch, Source, VerificationResult};
5use parking_lot::RwLock;
6use std::collections::HashMap;
7use std::sync::{Arc, OnceLock};
8
9/// A registry for input sources.
10#[derive(Default)]
11pub struct SourceRegistry {
12    sources: RwLock<HashMap<String, Arc<dyn Source + Send + Sync>>>,
13}
14
15impl SourceRegistry {
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    pub fn register(&self, source: Arc<dyn Source + Send + Sync>) {
21        let mut lock = self.sources.write();
22        lock.insert(source.name().to_string(), source);
23    }
24
25    pub fn get(&self, name: &str) -> Option<Arc<dyn Source + Send + Sync>> {
26        let lock = self.sources.read();
27        lock.get(name).cloned()
28    }
29}
30
31pub static SOURCE_REGISTRY: OnceLock<SourceRegistry> = OnceLock::new();
32
33/// Return the global registry of scannable source backends.
34pub fn get_source_registry() -> &'static SourceRegistry {
35    SOURCE_REGISTRY.get_or_init(|| SourceRegistry {
36        sources: RwLock::new(HashMap::new()),
37    })
38}
39
40/// A trait for custom verification logic (OAuth2, multi-step, etc).
41#[async_trait::async_trait]
42pub trait CustomVerifier: Send + Sync {
43    fn name(&self) -> &str;
44    async fn verify(&self, group: &DedupedMatch) -> (VerificationResult, HashMap<String, String>);
45}
46
47/// A registry for custom verifiers.
48#[derive(Default)]
49pub struct VerifierRegistry {
50    verifiers: RwLock<HashMap<String, Arc<dyn CustomVerifier>>>,
51}
52
53impl VerifierRegistry {
54    pub fn new() -> Self {
55        Self::default()
56    }
57
58    pub fn register(&self, verifier: Arc<dyn CustomVerifier>) {
59        let mut lock = self.verifiers.write();
60        lock.insert(verifier.name().to_string(), verifier);
61    }
62
63    pub fn get(&self, name: &str) -> Option<Arc<dyn CustomVerifier>> {
64        let lock = self.verifiers.read();
65        lock.get(name).cloned()
66    }
67}
68
69pub static VERIFIER_REGISTRY: OnceLock<VerifierRegistry> = OnceLock::new();
70
71/// Return the global registry of credential verifiers.
72pub fn get_verifier_registry() -> &'static VerifierRegistry {
73    VERIFIER_REGISTRY.get_or_init(|| VerifierRegistry {
74        verifiers: RwLock::new(HashMap::new()),
75    })
76}