module_registry/
registry.rs

1//! Module registry implementation
2
3use anyhow::{Context, Result};
4use std::any::Any;
5use std::collections::HashMap;
6use std::sync::{OnceLock, RwLock};
7
8use crate::security::{SecurityValidator, SecurityCheckResult};
9use crate::types::*;
10
11// Optional tracing support
12#[cfg(feature = "tracing")]
13use tracing::info;
14
15#[cfg(not(feature = "tracing"))]
16macro_rules! info {
17    ($($arg:tt)*) => {};
18}
19
20/// Generic module registry
21///
22/// Thread-safe registry for storing and instantiating modules at runtime.
23/// Modules are registered with a factory function and can be created by name.
24pub struct ModuleRegistry {
25    modules: RwLock<HashMap<String, (ModuleMetadata, ModuleFactory)>>,
26}
27
28impl ModuleRegistry {
29    /// Create a new empty registry
30    pub fn new() -> Self {
31        Self {
32            modules: RwLock::new(HashMap::new()),
33        }
34    }
35
36    /// Get the global registry instance
37    pub fn global() -> &'static Self {
38        static REGISTRY: OnceLock<ModuleRegistry> = OnceLock::new();
39        REGISTRY.get_or_init(|| {
40            let registry = Self::new();
41
42            // Load inventory-registered modules
43            for reg in inventory::iter::<ModuleRegistration> {
44                let metadata = ModuleMetadata::new(
45                    reg.name.to_string(),
46                    reg.module_type.to_string(),
47                    reg.instantiate_fn_name.to_string(),
48                    reg.module_path.to_string(),
49                    reg.struct_name.to_string(),
50                );
51                registry
52                    .modules
53                    .write()
54                    .unwrap()
55                    .insert(metadata.name.clone(), (metadata, reg.factory));
56            }
57
58            info!(
59                "Module registry initialized with {} modules",
60                registry.modules.read().unwrap().len()
61            );
62
63            registry
64        })
65    }
66
67    /// Register a module with a factory function
68    ///
69    /// The factory function should return a Box<dyn YourTrait> cast to Box<dyn Any + Send + Sync>
70    pub fn register(&self, name: &str, module_type: &str, factory: ModuleFactory) {
71        self.register_with_metadata(
72            name,
73            module_type,
74            "factory",
75            module_path!(),
76            "Module",
77            factory,
78        );
79    }
80
81    /// Register a module with full metadata
82    pub fn register_with_metadata(
83        &self,
84        name: &str,
85        module_type: &str,
86        instantiate_fn: &str,
87        module_path: &str,
88        struct_name: &str,
89        factory: ModuleFactory,
90    ) {
91        let metadata = ModuleMetadata::new(
92            name.to_string(),
93            module_type.to_string(),
94            instantiate_fn.to_string(),
95            module_path.to_string(),
96            struct_name.to_string(),
97        );
98
99        let mut modules = self.modules.write().expect("Failed to acquire write lock");
100        modules.insert(name.to_string(), (metadata, factory));
101
102        info!("Registered module: {} (type: {})", name, module_type);
103    }
104
105    /// Create a module instance by name
106    ///
107    /// Returns Box<dyn Any + Send + Sync> which you must downcast to your trait type
108    pub fn create_any(&self, name: &str) -> Result<Box<dyn Any + Send + Sync>> {
109        let modules = self.modules.read().expect("Failed to acquire read lock");
110
111        let (_metadata, factory) = modules
112            .get(name)
113            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
114
115        info!("Creating module: {}", name);
116
117        factory().with_context(|| format!("Failed to instantiate module: {}", name))
118    }
119
120    /// Create and downcast a module to a specific trait type
121    pub fn create<T: 'static>(&self, name: &str) -> Result<Box<T>> {
122        let any_module = self.create_any(name)?;
123
124        any_module
125            .downcast::<T>()
126            .map_err(|_| anyhow::anyhow!("Module type mismatch for: {}", name))
127    }
128
129    /// Get all registered module names
130    pub fn list_modules(&self) -> Vec<String> {
131        self.modules
132            .read()
133            .expect("Failed to acquire read lock")
134            .keys()
135            .cloned()
136            .collect()
137    }
138
139    /// Get all registered module names (alias for compatibility)
140    pub fn get_module_names(&self) -> Vec<String> {
141        self.list_modules()
142    }
143
144    /// Check if a module is registered
145    pub fn has_module(&self, name: &str) -> bool {
146        self.modules
147            .read()
148            .expect("Failed to acquire read lock")
149            .contains_key(name)
150    }
151
152    /// Get metadata for a module
153    pub fn get_metadata(&self, name: &str) -> Option<ModuleMetadata> {
154        self.modules
155            .read()
156            .expect("Failed to acquire read lock")
157            .get(name)
158            .map(|(metadata, _)| metadata.clone())
159    }
160
161    /// Clear all registered modules (for testing)
162    pub fn clear(&self) {
163        self.modules
164            .write()
165            .expect("Failed to acquire write lock")
166            .clear();
167    }
168
169    /// Get count of registered modules
170    pub fn count(&self) -> usize {
171        self.modules
172            .read()
173            .expect("Failed to acquire read lock")
174            .len()
175    }
176
177    /// Verify module signature
178    pub fn verify_module_signature(&self, name: &str) -> Result<bool> {
179        let modules = self.modules.read().expect("Failed to acquire read lock");
180        let (metadata, _) = modules
181            .get(name)
182            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
183
184        SecurityValidator::verify_signature(metadata)
185    }
186
187    /// Check if module has required permissions
188    pub fn check_module_permissions(&self, name: &str, required_permission: &str) -> Result<bool> {
189        let modules = self.modules.read().expect("Failed to acquire read lock");
190        let (metadata, _) = modules
191            .get(name)
192            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
193
194        SecurityValidator::check_permissions(metadata, required_permission)
195    }
196
197    /// Check if module passed code review
198    pub fn is_module_approved(&self, name: &str) -> Result<bool> {
199        let modules = self.modules.read().expect("Failed to acquire read lock");
200        let (metadata, _) = modules
201            .get(name)
202            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
203
204        SecurityValidator::is_approved(metadata)
205    }
206
207    /// Verify supply chain information
208    pub fn verify_supply_chain(&self, name: &str) -> Result<bool> {
209        let modules = self.modules.read().expect("Failed to acquire read lock");
210        let (metadata, _) = modules
211            .get(name)
212            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
213
214        SecurityValidator::verify_supply_chain(metadata)
215    }
216
217    /// Create module with security checks
218    pub fn create_secure(&self, name: &str) -> Result<Box<dyn Any + Send + Sync>> {
219        // Verify signature
220        if !self.verify_module_signature(name)? {
221            return Err(anyhow::anyhow!("Module signature verification failed: {}", name));
222        }
223
224        // Check if module is approved
225        if !self.is_module_approved(name)? {
226            return Err(anyhow::anyhow!("Module not approved: {}", name));
227        }
228
229        // Verify supply chain
230        if !self.verify_supply_chain(name)? {
231            return Err(anyhow::anyhow!("Supply chain verification failed: {}", name));
232        }
233
234        // Create module with sandboxing
235        self.create_with_sandbox(name)
236    }
237
238    /// Create module with sandbox configuration
239    pub fn create_with_sandbox(&self, name: &str) -> Result<Box<dyn Any + Send + Sync>> {
240        let modules = self.modules.read().expect("Failed to acquire read lock");
241        let (metadata, factory) = modules
242            .get(name)
243            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
244
245        // Apply sandbox configuration
246        if metadata.sandbox_config.enabled {
247            info!("Creating sandboxed module: {}", name);
248            // In a real implementation, set up sandbox environment
249            // For now, just log the sandbox config
250            info!("Sandbox config: {:?}", metadata.sandbox_config);
251        }
252
253        info!("Creating module: {}", name);
254        factory().with_context(|| format!("Failed to instantiate module: {}", name))
255    }
256
257    /// Register module with security metadata
258    pub fn register_secure(
259        &self,
260        name: &str,
261        module_type: &str,
262        factory: ModuleFactory,
263        signature: Option<ModuleSignature>,
264        permissions: ModulePermissions,
265        supply_chain: Option<SupplyChainInfo>,
266    ) {
267        let metadata = ModuleMetadata::secure(
268            name.to_string(),
269            module_type.to_string(),
270            "factory".to_string(),
271            module_path!().to_string(),
272            "Module".to_string(),
273            signature,
274            permissions,
275            supply_chain,
276        );
277
278        let mut modules = self.modules.write().expect("Failed to acquire write lock");
279        modules.insert(name.to_string(), (metadata, factory));
280
281        info!("Registered secure module: {} (type: {})", name, module_type);
282    }
283
284    /// Update code review status
285    pub fn update_review_status(
286        &self,
287        name: &str,
288        status: CodeReviewStatus,
289    ) -> Result<()> {
290        let mut modules = self.modules.write().expect("Failed to acquire write lock");
291        let (metadata, factory) = modules
292            .get_mut(name)
293            .ok_or_else(|| anyhow::anyhow!("Module not found: {}", name))?;
294
295        metadata.review_status = status;
296        info!("Updated review status for module: {}", name);
297        Ok(())
298    }
299
300    /// Get security report for all modules
301    pub fn get_security_report(&self) -> HashMap<String, SecurityReport> {
302        let modules = self.modules.read().expect("Failed to acquire read lock");
303        let mut report = HashMap::new();
304
305        for (name, (metadata, _)) in modules.iter() {
306            let security_report = SecurityReport {
307                name: name.clone(),
308                has_signature: metadata.signature.is_some(),
309                signature_verified: metadata.signature.is_some(),
310                is_approved: matches!(metadata.review_status, CodeReviewStatus::Approved { .. }),
311                has_supply_chain: metadata.supply_chain.is_some(),
312                supply_chain_verified: metadata.supply_chain.is_some(),
313                permissions: metadata.permissions.clone(),
314                sandbox_enabled: metadata.sandbox_config.enabled,
315            };
316            report.insert(name.clone(), security_report);
317        }
318
319        report
320    }
321
322    /// Perform comprehensive security check on all modules
323    pub fn security_audit(&self) -> HashMap<String, SecurityCheckResult> {
324        let modules = self.modules.read().expect("Failed to acquire read lock");
325        let mut audit_results = HashMap::new();
326
327        for (name, (metadata, _)) in modules.iter() {
328            let security_check = SecurityValidator::comprehensive_check(metadata);
329            audit_results.insert(name.clone(), security_check);
330        }
331
332        audit_results
333    }
334}
335
336impl Default for ModuleRegistry {
337    fn default() -> Self {
338        Self::new()
339    }
340}