1use crate::access_controller::manifest::{CreateAccessControllerOptions, ManifestParams};
2use crate::access_controller::traits::AccessController;
3use crate::address::Address;
4use crate::error::{GuardianError, Result};
5use crate::ipfs_log::{access_controller::LogEntry, identity_provider::IdentityProvider};
6use async_trait::async_trait;
7use std::collections::HashMap;
8use std::sync::Arc;
9use tokio::sync::RwLock;
10use tracing::{Span, debug, info, instrument, warn};
11
12struct SimpleAccessControllerState {
14 allowed_keys: HashMap<String, Vec<String>>,
15}
16
17pub struct SimpleAccessController {
20 state: Arc<RwLock<SimpleAccessControllerState>>,
21 span: Span,
22}
23
24impl SimpleAccessController {
25 #[instrument(skip(initial_keys))]
27 pub fn new(initial_keys: Option<HashMap<String, Vec<String>>>) -> Self {
28 let mut allowed_keys = initial_keys.unwrap_or_default();
29
30 allowed_keys.entry("read".to_string()).or_default();
32 allowed_keys.entry("write".to_string()).or_default();
33 allowed_keys.entry("admin".to_string()).or_default();
34
35 info!(target: "simple_access_controller",
36 categories = ?allowed_keys.keys().collect::<Vec<_>>(),
37 total_permissions = allowed_keys.values().map(|v| v.len()).sum::<usize>(),
38 "Created SimpleAccessController"
39 );
40
41 Self {
42 state: Arc::new(RwLock::new(SimpleAccessControllerState { allowed_keys })),
43 span: tracing::info_span!("simple_access_controller"),
44 }
45 }
46
47 #[allow(dead_code)]
49 pub fn new_simple() -> Self {
50 Self::new(None)
51 }
52
53 pub fn span(&self) -> &Span {
55 &self.span
56 }
57
58 pub async fn list_keys(&self, capability: &str) -> Vec<String> {
60 let state = self.state.read().await;
61 state
62 .allowed_keys
63 .get(capability)
64 .cloned()
65 .unwrap_or_default()
66 }
67
68 #[allow(dead_code)]
70 pub async fn list_capabilities(&self) -> Vec<String> {
71 let state = self.state.read().await;
72 state.allowed_keys.keys().cloned().collect()
73 }
74
75 #[allow(dead_code)]
77 pub async fn has_capability(&self, capability: &str, key_id: &str) -> bool {
78 let state = self.state.read().await;
79
80 if let Some(keys) = state.allowed_keys.get(capability) {
81 keys.contains(&"*".to_string()) || keys.contains(&key_id.to_string())
82 } else {
83 false
84 }
85 }
86
87 pub async fn clear_capability(&self, capability: &str) -> Result<()> {
89 if capability.is_empty() {
90 return Err(GuardianError::Store(
91 "Capability cannot be empty".to_string(),
92 ));
93 }
94
95 let mut state = self.state.write().await;
96
97 if let Some(keys) = state.allowed_keys.get_mut(capability) {
98 let count = keys.len();
99 keys.clear();
100
101 info!(target: "simple_access_controller",
102 capability = %capability,
103 removed_keys = count,
104 "Capability cleared"
105 );
106 } else {
107 warn!(target: "simple_access_controller",
108 capability = %capability,
109 "Capability not found for clearing"
110 );
111 }
112
113 Ok(())
114 }
115
116 pub async fn get_stats(&self) -> HashMap<String, usize> {
118 let state = self.state.read().await;
119 state
120 .allowed_keys
121 .iter()
122 .map(|(capability, keys)| (capability.clone(), keys.len()))
123 .collect()
124 }
125
126 pub async fn is_capability_empty(&self, capability: &str) -> bool {
128 let state = self.state.read().await;
129 state
130 .allowed_keys
131 .get(capability)
132 .map(|keys| keys.is_empty())
133 .unwrap_or(true)
134 }
135
136 pub async fn total_permissions(&self) -> usize {
138 let state = self.state.read().await;
139 state.allowed_keys.values().map(|keys| keys.len()).sum()
140 }
141
142 pub async fn export_permissions(&self) -> HashMap<String, Vec<String>> {
144 let state = self.state.read().await;
145 state.allowed_keys.clone()
146 }
147
148 pub async fn import_permissions(
150 &self,
151 permissions: HashMap<String, Vec<String>>,
152 ) -> Result<()> {
153 let mut state = self.state.write().await;
154
155 info!(target: "simple_access_controller", "Importing permissions: capabilities_count={}, total_permissions={}",
156 permissions.len(),
157 permissions.values().map(|v| v.len()).sum::<usize>()
158 );
159
160 state.allowed_keys = permissions;
161 Ok(())
162 }
163
164 pub async fn grant_multiple(&self, capability: &str, key_ids: Vec<&str>) -> Result<()> {
166 let _entered = self.span.enter();
167
168 if capability.is_empty() {
169 return Err(GuardianError::Store(
170 "Capability cannot be empty".to_string(),
171 ));
172 }
173
174 let mut state = self.state.write().await;
175 let keys = state
176 .allowed_keys
177 .entry(capability.to_string())
178 .or_insert_with(Vec::new);
179
180 let mut added_count = 0;
181 for key_id in key_ids {
182 if !key_id.is_empty() && !keys.contains(&key_id.to_string()) {
183 keys.push(key_id.to_string());
184 added_count += 1;
185 }
186 }
187
188 let total_keys = keys.len();
189 let capability_name = capability.to_string();
190
191 info!(target: "simple_access_controller", "Multiple permissions granted: capability={}, added_keys={}, total_keys={}",
192 capability_name, added_count, total_keys
193 );
194
195 Ok(())
196 }
197
198 pub async fn revoke_multiple(&self, capability: &str, key_ids: Vec<&str>) -> Result<()> {
200 let _entered = self.span.enter();
201
202 if capability.is_empty() {
203 return Err(GuardianError::Store(
204 "Capability cannot be empty".to_string(),
205 ));
206 }
207
208 let mut state = self.state.write().await;
209
210 if let Some(keys) = state.allowed_keys.get_mut(capability) {
211 let initial_len = keys.len();
212
213 for key_id in key_ids {
214 keys.retain(|k| k != key_id);
215 }
216
217 let removed_count = initial_len - keys.len();
218 let remaining_keys = keys.len();
219 let capability_name = capability.to_string();
220 let should_remove_capability = keys.is_empty();
221
222 info!(target: "simple_access_controller", "Multiple permissions revoked: capability={}, removed_keys={}, remaining_keys={}",
223 capability_name, removed_count, remaining_keys
224 );
225
226 if should_remove_capability {
228 state.allowed_keys.remove(capability);
229 debug!(target: "simple_access_controller", "Capability removed completely: capability={}",
230 capability
231 );
232 }
233 }
234
235 Ok(())
236 }
237
238 pub async fn clone_capability(
240 &self,
241 source_capability: &str,
242 target_capability: &str,
243 ) -> Result<()> {
244 if source_capability.is_empty() || target_capability.is_empty() {
245 return Err(GuardianError::Store(
246 "Source and target capabilities cannot be empty".to_string(),
247 ));
248 }
249
250 let mut state = self.state.write().await;
251
252 if let Some(source_keys) = state.allowed_keys.get(source_capability) {
253 let cloned_keys = source_keys.clone();
254 let keys_count = cloned_keys.len();
255
256 state
257 .allowed_keys
258 .insert(target_capability.to_string(), cloned_keys);
259
260 info!(target: "simple_access_controller", "Capability cloned: source_capability={}, target_capability={}, cloned_keys={}",
261 source_capability, target_capability, keys_count
262 );
263 } else {
264 return Err(GuardianError::Store(format!(
265 "Source capability '{}' not found",
266 source_capability
267 )));
268 }
269
270 Ok(())
271 }
272
273 pub fn address(&self) -> Option<Box<dyn Address>> {
275 None
276 }
277
278 #[instrument(skip(params))]
280 pub fn from_options(params: CreateAccessControllerOptions) -> Result<Self> {
281 let allowed_keys = params.get_all_access();
283 Ok(Self {
284 state: Arc::new(RwLock::new(SimpleAccessControllerState { allowed_keys })),
285 span: tracing::info_span!("simple_access_controller", controller_type = "simple"),
286 })
287 }
288}
289
290#[async_trait]
291impl AccessController for SimpleAccessController {
292 fn get_type(&self) -> &str {
293 "simple"
294 }
295
296 async fn get_authorized_by_role(&self, role: &str) -> Result<Vec<String>> {
297 let _entered = self.span.enter();
298
299 if role.is_empty() {
301 return Err(GuardianError::Store("Role cannot be empty".to_string()));
302 }
303
304 let state = self.state.read().await;
305
306 debug!(target: "simple_access_controller", "Getting authorized keys by role: role={}",
308 role
309 );
310
311 let keys = state.allowed_keys.get(role).cloned().unwrap_or_default();
312
313 debug!(target: "simple_access_controller", "Retrieved authorized keys: role={}, key_count={}",
314 role, keys.len()
315 );
316
317 Ok(keys)
318 }
319
320 async fn grant(&self, capability: &str, key_id: &str) -> Result<()> {
321 let _entered = self.span.enter();
322
323 if capability.is_empty() {
325 return Err(GuardianError::Store(
326 "Capability cannot be empty".to_string(),
327 ));
328 }
329 if key_id.is_empty() {
330 return Err(GuardianError::Store("Key ID cannot be empty".to_string()));
331 }
332
333 let mut state = self.state.write().await;
334
335 info!(target: "simple_access_controller", "Granting permission: capability={}, key_id={}",
337 capability, key_id
338 );
339
340 let entry = state
342 .allowed_keys
343 .entry(capability.to_string())
344 .or_insert_with(Vec::new);
345
346 if !entry.contains(&key_id.to_string()) {
348 entry.push(key_id.to_string());
349 let total_keys = entry.len();
350 let capability_name = capability.to_string();
351 let key_id_name = key_id.to_string();
352
353 debug!(target: "simple_access_controller", "Permission granted successfully: capability={}, key_id={}, total_keys={}",
354 capability_name, key_id_name, total_keys
355 );
356 } else {
357 debug!(target: "simple_access_controller", "Permission already exists: capability={}, key_id={}",
358 capability, key_id
359 );
360 }
361
362 Ok(())
363 }
364
365 async fn revoke(&self, capability: &str, key_id: &str) -> Result<()> {
366 let _entered = self.span.enter();
367
368 if capability.is_empty() {
370 return Err(GuardianError::Store(
371 "Capability cannot be empty".to_string(),
372 ));
373 }
374 if key_id.is_empty() {
375 return Err(GuardianError::Store("Key ID cannot be empty".to_string()));
376 }
377
378 let mut state = self.state.write().await;
379
380 info!(target: "simple_access_controller", "Revoking permission: capability={}, key_id={}",
382 capability, key_id
383 );
384
385 if let Some(keys) = state.allowed_keys.get_mut(capability) {
387 let initial_len = keys.len();
388 keys.retain(|k| k != key_id);
389
390 if keys.len() < initial_len {
391 let remaining_keys = keys.len();
392 let capability_name = capability.to_string();
393 let key_id_name = key_id.to_string();
394 let should_remove_capability = keys.is_empty();
395
396 debug!(target: "simple_access_controller", "Permission revoked successfully: capability={}, key_id={}, remaining_keys={}",
397 capability_name, key_id_name, remaining_keys
398 );
399
400 if should_remove_capability {
402 state.allowed_keys.remove(capability);
403 debug!(target: "simple_access_controller", "Capability removed completely: capability={}",
404 capability
405 );
406 }
407 } else {
408 debug!(target: "simple_access_controller", "Permission not found for revocation: capability={}, key_id={}",
409 capability, key_id
410 );
411 }
412 } else {
413 debug!(target: "simple_access_controller", "Capability not found for revocation: capability={}",
414 capability
415 );
416 }
417
418 Ok(())
419 }
420
421 async fn load(&self, address: &str) -> Result<()> {
422 if address.is_empty() {
424 return Err(GuardianError::Store("Address cannot be empty".to_string()));
425 }
426
427 info!(target: "simple_access_controller", "Loading access controller configuration: address={}",
429 address
430 );
431
432 debug!(target: "simple_access_controller", "Load operation completed (no-op for simple controller): address={}",
435 address
436 );
437
438 Ok(())
439 }
440
441 async fn save(&self) -> Result<Box<dyn ManifestParams>> {
442 let state = self.state.read().await;
443
444 info!(target: "simple_access_controller", "Saving access controller configuration");
446
447 let mut options = CreateAccessControllerOptions::new_empty();
449 options.set_type("simple".to_string());
450
451 for (capability, keys) in &state.allowed_keys {
453 options.set_access(capability.clone(), keys.clone());
454 }
455
456 debug!(target: "simple_access_controller", "Save operation completed: capabilities_count={}",
457 state.allowed_keys.len()
458 );
459
460 Ok(Box::new(options))
461 }
462
463 async fn close(&self) -> Result<()> {
464 let state = self.state.read().await;
465
466 info!(target: "simple_access_controller", "Closing simple access controller");
468
469 debug!(target: "simple_access_controller", "Close operation completed: capabilities_count={}",
472 state.allowed_keys.len()
473 );
474
475 Ok(())
476 }
477
478 async fn can_append(
479 &self,
480 entry: &dyn LogEntry,
481 identity_provider: &dyn IdentityProvider,
482 _additional_context: &dyn crate::ipfs_log::access_controller::CanAppendAdditionalContext,
483 ) -> Result<()> {
484 let _entered = self.span.enter();
485 let state = self.state.read().await;
486
487 let entry_identity = entry.get_identity();
489 let entry_id = entry_identity.id();
490
491 debug!(target: "simple_access_controller", "Checking append permission: entry_id={}",
492 entry_id
493 );
494
495 if let Some(write_keys) = state.allowed_keys.get("write") {
497 if write_keys.contains(&"*".to_string()) {
499 debug!(target: "simple_access_controller", "Wildcard permission found, verifying identity: entry_id={}",
500 entry_id
501 );
502
503 if let Err(e) = identity_provider
505 .verify_identity(entry.get_identity())
506 .await
507 {
508 warn!(target: "simple_access_controller", "Invalid identity signature for wildcard access: entry_id={}, error={}",
509 entry_id, e
510 );
511 return Err(GuardianError::Store(format!(
512 "Invalid identity signature: {}",
513 e
514 )));
515 }
516
517 debug!(target: "simple_access_controller", "Append permission granted (wildcard): entry_id={}",
518 entry_id
519 );
520 return Ok(());
521 }
522
523 if write_keys.contains(&entry_id.to_string()) {
525 if let Err(e) = identity_provider.verify_identity(entry_identity).await {
527 warn!(target: "simple_access_controller", "Invalid identity signature for authorized key: entry_id={}, error={}",
528 entry_id, e
529 );
530 return Err(GuardianError::Store(format!(
531 "Invalid identity signature for authorized key {}: {}",
532 entry_id, e
533 )));
534 }
535
536 debug!(target: "simple_access_controller", "Append permission granted (write key): entry_id={}",
537 entry_id
538 );
539 return Ok(());
540 }
541 }
542
543 if let Some(admin_keys) = state.allowed_keys.get("admin")
545 && (admin_keys.contains(&"*".to_string()) || admin_keys.contains(&entry_id.to_string()))
546 {
547 if let Err(e) = identity_provider.verify_identity(entry_identity).await {
549 warn!(target: "simple_access_controller", "Invalid identity signature for admin key: entry_id={}, error={}",
550 entry_id, e
551 );
552 return Err(GuardianError::Store(format!(
553 "Invalid identity signature for admin key {}: {}",
554 entry_id, e
555 )));
556 }
557
558 debug!(target: "simple_access_controller", "Append permission granted (admin key): entry_id={}",
559 entry_id
560 );
561 return Ok(());
562 }
563
564 warn!(target: "simple_access_controller", "Access denied for append operation: entry_id={}, available_write_keys={:?}, available_admin_keys={:?}",
565 entry_id, state.allowed_keys.get("write"), state.allowed_keys.get("admin")
566 );
567
568 Err(GuardianError::Store(format!(
569 "Access denied: identity {} not authorized for write operations",
570 entry_id
571 )))
572 }
573}