eidetica/auth/validation/resolver.rs
1//! Key resolution for authentication
2//!
3//! This module handles resolving authentication keys, both direct keys
4//! and delegation paths.
5
6use std::collections::HashMap;
7
8use super::delegation::DelegationResolver;
9use crate::{
10 Instance, Result,
11 auth::{
12 errors::AuthError,
13 settings::AuthSettings,
14 types::{KeyHint, ResolvedAuth, SigKey},
15 },
16};
17
18/// Key resolver for handling both direct and delegated key resolution
19pub struct KeyResolver {
20 /// Cache for resolved authentication data to improve performance
21 auth_cache: HashMap<String, ResolvedAuth>,
22 /// Delegation resolver for handling complex delegation paths
23 delegation_resolver: DelegationResolver,
24}
25
26impl KeyResolver {
27 /// Create a new key resolver
28 pub fn new() -> Self {
29 Self {
30 auth_cache: HashMap::new(),
31 delegation_resolver: DelegationResolver::new(),
32 }
33 }
34
35 /// Resolve authentication identifier to concrete authentication information
36 ///
37 /// Returns all matching ResolvedAuth entries. For name hints that match
38 /// multiple keys, all matches are returned so the caller can try signature
39 /// verification against each.
40 ///
41 /// # Arguments
42 /// * `sig_key` - The signature key identifier to resolve
43 /// * `auth_settings` - Authentication settings containing auth configuration
44 /// * `instance` - Instance for loading delegated trees (required for Delegation sig_key)
45 pub async fn resolve_sig_key(
46 &mut self,
47 sig_key: &SigKey,
48 auth_settings: &AuthSettings,
49 instance: Option<&Instance>,
50 ) -> Result<Vec<ResolvedAuth>> {
51 match sig_key {
52 SigKey::Direct { hint } => self.resolve_direct_key(hint, auth_settings),
53 SigKey::Delegation { path, hint } => {
54 let instance = instance.ok_or_else(|| AuthError::DatabaseRequired {
55 operation: "delegated tree resolution".to_string(),
56 })?;
57 self.delegation_resolver
58 .resolve_delegation_path(path, hint, auth_settings, instance)
59 .await
60 }
61 }
62 }
63
64 /// Resolve a direct key reference from the main tree's auth settings
65 ///
66 /// Returns all matching ResolvedAuth entries. For name hints that match
67 /// multiple keys, all matches are returned so the caller can try signature
68 /// verification against each.
69 pub fn resolve_direct_key(
70 &mut self,
71 hint: &KeyHint,
72 auth_settings: &AuthSettings,
73 ) -> Result<Vec<ResolvedAuth>> {
74 // Use AuthSettings.resolve_hint which handles:
75 // - Global permission (returns single match with actual pubkey)
76 // - Direct pubkey lookup (returns single match)
77 // - Name lookup (may return multiple matches)
78 let matches = auth_settings.resolve_hint(hint)?;
79 if matches.is_empty() {
80 return Err(AuthError::KeyNotFound {
81 key_name: format!("hint({:?})", hint.hint_type()),
82 }
83 .into());
84 }
85
86 Ok(matches)
87 }
88
89 /// Clear the authentication cache
90 pub fn clear_cache(&mut self) {
91 self.auth_cache.clear();
92 }
93}
94
95impl Default for KeyResolver {
96 fn default() -> Self {
97 Self::new()
98 }
99}