use crate::key_registry::{load_ed25519_yaml, KeyRegistryError, StaticEd25519KeyRegistry};
use crate::types::AgentId;
use ed25519_dalek::VerifyingKey;
use std::collections::HashMap;
use std::path::Path;
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum SourceIdentityRegistryError {
#[error(transparent)]
Load(#[from] KeyRegistryError),
}
pub trait SourceIdentityRegistry: Send + Sync {
fn lookup(&self, agent: &AgentId) -> Option<VerifyingKey>;
}
pub struct StaticSourceIdentityRegistry {
inner: StaticEd25519KeyRegistry<AgentId>,
}
impl StaticSourceIdentityRegistry {
#[must_use]
pub fn from_map(keys: HashMap<AgentId, VerifyingKey>) -> Self {
Self {
inner: StaticEd25519KeyRegistry::from_map(keys),
}
}
pub fn from_yaml(path: impl AsRef<Path>) -> Result<Self, SourceIdentityRegistryError> {
let keys = load_ed25519_yaml(path, AgentId)?;
Ok(Self {
inner: StaticEd25519KeyRegistry::from_map(keys),
})
}
}
impl SourceIdentityRegistry for StaticSourceIdentityRegistry {
fn lookup(&self, agent: &AgentId) -> Option<VerifyingKey> {
use crate::key_registry::Ed25519KeyRegistry as _;
self.inner.lookup(agent)
}
}
#[cfg(test)]
mod tests {
use super::*;
use ed25519_dalek::SigningKey;
#[test]
fn round_trip_via_yaml() {
let sk = SigningKey::from_bytes(&[5u8; 32]);
let pk = sk.verifying_key();
use base64::Engine as _;
let b64 = base64::engine::general_purpose::STANDARD.encode(pk.to_bytes());
let yaml = format!("claims-triage: \"{b64}\"\n");
let path = std::env::temp_dir().join("klieo-test-source-identity.yaml");
std::fs::write(&path, yaml).unwrap();
let reg = StaticSourceIdentityRegistry::from_yaml(&path).expect("load");
let resolved = reg.lookup(&AgentId("claims-triage".into())).expect("found");
assert_eq!(resolved.to_bytes(), pk.to_bytes());
}
#[test]
fn missing_agent_returns_none() {
let reg = StaticSourceIdentityRegistry::from_map(HashMap::new());
assert!(reg.lookup(&AgentId("ghost".into())).is_none());
}
}