hessra_context_token/
verify.rs1extern crate biscuit_auth as biscuit;
2
3use biscuit::Biscuit;
4use biscuit::macros::authorizer;
5use chrono::Utc;
6use hessra_token_core::{PublicKey, TokenError};
7
8pub struct ContextVerifier {
29 token: String,
30 public_key: PublicKey,
31}
32
33impl ContextVerifier {
34 pub fn new(token: String, public_key: PublicKey) -> Self {
40 Self { token, public_key }
41 }
42
43 pub fn verify(self) -> Result<(), TokenError> {
53 let biscuit = Biscuit::from_base64(&self.token, self.public_key)?;
54 let now = Utc::now().timestamp();
55
56 let authz = authorizer!(
57 r#"
58 time({now});
59 allow if true;
60 "#
61 );
62
63 authz
64 .build(&biscuit)
65 .map_err(|e| TokenError::internal(format!("failed to build authorizer: {e}")))?
66 .authorize()
67 .map_err(TokenError::from)?;
68
69 Ok(())
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::mint::HessraContext;
77 use hessra_token_core::{KeyPair, TokenTimeConfig};
78
79 #[test]
80 fn test_verify_valid_token() {
81 let keypair = KeyPair::new();
82 let public_key = keypair.public();
83
84 let token = HessraContext::new("agent:test".to_string(), TokenTimeConfig::default())
85 .issue(&keypair)
86 .expect("Failed to create context token");
87
88 ContextVerifier::new(token, public_key)
89 .verify()
90 .expect("Should verify valid token");
91 }
92
93 #[test]
94 fn test_verify_expired_token() {
95 let keypair = KeyPair::new();
96 let public_key = keypair.public();
97
98 let expired_config = TokenTimeConfig {
99 start_time: Some(0),
100 duration: 1,
101 };
102
103 let token = HessraContext::new("agent:test".to_string(), expired_config)
104 .issue(&keypair)
105 .expect("Failed to create expired context token");
106
107 let result = ContextVerifier::new(token, public_key).verify();
108 assert!(result.is_err(), "Expired token should fail verification");
109 }
110
111 #[test]
112 fn test_verify_wrong_key() {
113 let keypair = KeyPair::new();
114 let wrong_keypair = KeyPair::new();
115 let wrong_public_key = wrong_keypair.public();
116
117 let token = HessraContext::new("agent:test".to_string(), TokenTimeConfig::default())
118 .issue(&keypair)
119 .expect("Failed to create context token");
120
121 let result = ContextVerifier::new(token, wrong_public_key).verify();
122 assert!(result.is_err(), "Token verified with wrong key should fail");
123 }
124
125 #[test]
126 fn test_verify_tainted_token() {
127 let keypair = KeyPair::new();
128 let public_key = keypair.public();
129
130 let token = HessraContext::new("agent:test".to_string(), TokenTimeConfig::default())
131 .issue(&keypair)
132 .expect("Failed to create context token");
133
134 let tainted = crate::taint::add_taint(
136 &token,
137 public_key,
138 &["PII:SSN".to_string()],
139 "data:user-ssn".to_string(),
140 )
141 .expect("Failed to add taint");
142
143 ContextVerifier::new(tainted, public_key)
144 .verify()
145 .expect("Tainted token should still verify");
146 }
147}