1use 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#[cfg(feature = "tracing")]
13use tracing::info;
14
15#[cfg(not(feature = "tracing"))]
16macro_rules! info {
17 ($($arg:tt)*) => {};
18}
19
20pub struct ModuleRegistry {
25 modules: RwLock<HashMap<String, (ModuleMetadata, ModuleFactory)>>,
26}
27
28impl ModuleRegistry {
29 pub fn new() -> Self {
31 Self {
32 modules: RwLock::new(HashMap::new()),
33 }
34 }
35
36 pub fn global() -> &'static Self {
38 static REGISTRY: OnceLock<ModuleRegistry> = OnceLock::new();
39 REGISTRY.get_or_init(|| {
40 let registry = Self::new();
41
42 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 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 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 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 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 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 pub fn get_module_names(&self) -> Vec<String> {
141 self.list_modules()
142 }
143
144 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 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 pub fn clear(&self) {
163 self.modules
164 .write()
165 .expect("Failed to acquire write lock")
166 .clear();
167 }
168
169 pub fn count(&self) -> usize {
171 self.modules
172 .read()
173 .expect("Failed to acquire read lock")
174 .len()
175 }
176
177 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 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 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 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 pub fn create_secure(&self, name: &str) -> Result<Box<dyn Any + Send + Sync>> {
219 if !self.verify_module_signature(name)? {
221 return Err(anyhow::anyhow!("Module signature verification failed: {}", name));
222 }
223
224 if !self.is_module_approved(name)? {
226 return Err(anyhow::anyhow!("Module not approved: {}", name));
227 }
228
229 if !self.verify_supply_chain(name)? {
231 return Err(anyhow::anyhow!("Supply chain verification failed: {}", name));
232 }
233
234 self.create_with_sandbox(name)
236 }
237
238 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 if metadata.sandbox_config.enabled {
247 info!("Creating sandboxed module: {}", name);
248 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 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 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 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 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}