pub use signed::Key;
pub use std::time::{SystemTime, UNIX_EPOCH};
mod signed;
pub fn encode_expiring_claim(claim: &str, expiry_date: SystemTime) -> String {
format!("{}:{}", claim, expiry_date.duration_since(UNIX_EPOCH).unwrap().as_secs())
}
pub fn decode_expiring_claim(value: &str) -> Result<&str, &'static str> {
let mut parts = value.rsplitn(2, ':');
let expiry_date = parts.next().expect("first .rsplitn().next() is expected to return Some");
let claim = parts.next().ok_or("expected colon")?;
let expiry_date: u64 = expiry_date.parse().map_err(|_| "failed to parse timestamp")?;
if expiry_date > SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() {
Ok(claim)
} else {
Err("token is expired")
}
}
#[cfg(test)]
mod tests {
use std::time::{SystemTime, Duration};
#[test]
fn test_expiring_claim() {
for claim in vec!["test", "", "foo:bar"] {
let encoded_claim = super::encode_expiring_claim(claim, SystemTime::now() + Duration::from_secs(60));
assert_eq!(super::decode_expiring_claim(&encoded_claim).unwrap(), claim);
let encoded_claim = super::encode_expiring_claim(claim, SystemTime::now() - Duration::from_secs(60));
assert!(super::decode_expiring_claim(&encoded_claim).is_err());
}
assert!(super::decode_expiring_claim("test".into()).is_err());
}
}