guardian_db/access_controller/
simple.rs

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
12/// Estado interno do SimpleAccessController
13struct SimpleAccessControllerState {
14    allowed_keys: HashMap<String, Vec<String>>,
15}
16
17/// Estrutura principal do controlador de acesso simples.
18/// Mantém uma lista de chaves autorizadas em memória.
19pub struct SimpleAccessController {
20    state: Arc<RwLock<SimpleAccessControllerState>>,
21    span: Span,
22}
23
24impl SimpleAccessController {
25    /// Cria um novo SimpleAccessController com configuração inicial opcional
26    #[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        // Garante que pelo menos as categorias básicas existam
31        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    /// Cria um novo SimpleAccessController simples
48    #[allow(dead_code)]
49    pub fn new_simple() -> Self {
50        Self::new(None)
51    }
52
53    /// Retorna uma referência ao span de tracing para instrumentação
54    pub fn span(&self) -> &Span {
55        &self.span
56    }
57
58    /// Lista todas as chaves de uma capacidade
59    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    /// Lista todas as capacidades disponíveis
69    #[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    /// Verifica se uma chave tem uma capacidade específica
76    #[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    /// Remove todas as chaves de uma capacidade
88    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    /// Obtém estatísticas das permissões
117    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    /// Verifica se uma capacidade está vazia
127    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    /// Conta o total de permissões em todas as capacidades
137    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    /// Exporta todas as permissões para um HashMap
143    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    /// Importa permissões de um HashMap (substitui todas as existentes)
149    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    /// Adiciona múltiplas chaves a uma capacidade de uma vez
165    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    /// Remove múltiplas chaves de uma capacidade de uma vez
199    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            // Remove a capacidade completamente se não há mais chaves
227            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    /// Clona as permissões de uma capacidade para outra
239    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    /// Este controlador não tem um endereço, pois não é persistido.
274    pub fn address(&self) -> Option<Box<dyn Address>> {
275        None
276    }
277
278    /// Método factory alternativo
279    #[instrument(skip(params))]
280    pub fn from_options(params: CreateAccessControllerOptions) -> Result<Self> {
281        // As permissões são extraídas diretamente dos parâmetros de criação.
282        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        // Validação de parâmetros
300        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        // Log da consulta
307        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        // Validação de parâmetros
324        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        // Log da operação
336        info!(target: "simple_access_controller", "Granting permission: capability={}, key_id={}",
337            capability, key_id
338        );
339
340        // Adiciona a chave à lista de permissões para a capacidade especificada
341        let entry = state
342            .allowed_keys
343            .entry(capability.to_string())
344            .or_insert_with(Vec::new);
345
346        // Verifica se a chave já existe para evitar duplicatas
347        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        // Validação de parâmetros
369        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        // Log da operação
381        info!(target: "simple_access_controller", "Revoking permission: capability={}, key_id={}",
382            capability, key_id
383        );
384
385        // Remove a chave da lista de permissões para a capacidade especificada
386        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                // Remove a entrada completamente se não há mais chaves
401                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        // Validação de parâmetros
423        if address.is_empty() {
424            return Err(GuardianError::Store("Address cannot be empty".to_string()));
425        }
426
427        // Log da operação
428        info!(target: "simple_access_controller", "Loading access controller configuration: address={}",
429            address
430        );
431
432        // Para SimpleAccessController, load é uma operação no-op já que é baseado em memória
433        // Em uma implementação mais avançada, isso poderia carregar de um arquivo ou rede
434        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        // Log da operação
445        info!(target: "simple_access_controller", "Saving access controller configuration");
446
447        // Cria opções com as permissões atuais
448        let mut options = CreateAccessControllerOptions::new_empty();
449        options.set_type("simple".to_string());
450
451        // Copia todas as permissões atuais para o manifesto
452        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        // Log da operação de fechamento
467        info!(target: "simple_access_controller", "Closing simple access controller");
468
469        // Para SimpleAccessController, close é uma operação no-op já que é baseado em memória
470        // Em uma implementação mais avançada, isso poderia fechar conexões ou salvar estado
471        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        // Obtém o ID da identidade da entrada
488        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        // Verifica primeiro as chaves com permissão de escrita
496        if let Some(write_keys) = state.allowed_keys.get("write") {
497            // Verifica se há um wildcard que permite qualquer identidade
498            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                // Ainda assim, verifica a identidade para garantir que é válida
504                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            // Verifica se o ID da entrada está na lista de chaves autorizadas para escrita
524            if write_keys.contains(&entry_id.to_string()) {
525                // Verifica a assinatura da identidade
526                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        // Verifica também permissões de admin (admin pode escrever)
544        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            // Verifica a assinatura da identidade
548            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}