use std::path::Path; use crate::SandboxMode; pub struct SessionKey { pub default_profile: &'static str, pub hex_len: usize, } impl Default for SessionKey { fn default() -> Self { Self { default_profile: "", hex_len: 12, } } } impl SessionKey { pub fn derive( &self, profile: Option<&str>, mode: &SandboxMode, canonical_cwd: &Path, ) -> String { let profile = profile.unwrap_or(self.default_profile); let mode = match mode { SandboxMode::Blacklist => "blacklist", SandboxMode::Whitelist => "whitelist", }; let cwd = canonical_cwd.to_string_lossy(); let mut hasher = blake3::Hasher::new(); hasher.update(profile.as_bytes()); hasher.update(b"\0"); hasher.update(mode.as_bytes()); hasher.update(b"\0"); hasher.update(cwd.as_bytes()); let hex = hasher.finalize().to_hex(); hex[..self.hex_len].to_string() } } #[cfg(test)] mod tests { use super::*; #[test] fn missing_profile_uses_default_label() { let sk = SessionKey::default(); let cwd = Path::new("/x"); assert_eq!( sk.derive(None, &SandboxMode::Whitelist, cwd), sk.derive(Some(sk.default_profile), &SandboxMode::Whitelist, cwd), ); } #[test] fn key_respects_configured_hex_len() { let sk = SessionKey { hex_len: 8, ..SessionKey::default() }; let key = sk.derive(Some("foo"), &SandboxMode::Whitelist, Path::new("/x")); assert_eq!(key.len(), 8); } }