use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Claims<E> {
pub sub: String,
pub session_id: String,
pub exp: usize,
#[serde(flatten)]
pub ext: E,
}
#[derive(Clone, Debug)]
pub struct SecurityContext<E> {
claims: Claims<E>,
}
impl<E> SecurityContext<E> {
pub fn new(claims: Claims<E>) -> Self {
Self { claims }
}
pub fn sub(&self) -> &str {
&self.claims.sub
}
pub fn session_id(&self) -> &str {
&self.claims.session_id
}
pub fn ext(&self) -> &E {
&self.claims.ext
}
pub fn claims(&self) -> &Claims<E> {
&self.claims
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_security_context_new_and_accessors_with_unit_ext() {
let claims = Claims {
sub: "user-1".to_string(),
session_id: "session-1".to_string(),
exp: 1000,
ext: (),
};
let context = SecurityContext::new(claims.clone());
assert_eq!(context.sub(), "user-1");
assert_eq!(context.session_id(), "session-1");
assert_eq!(*context.ext(), ());
assert_eq!(context.claims().exp, 1000);
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct CustomExt {
role: String,
}
#[test]
fn test_security_context_new_and_accessors_with_custom_ext_struct() {
let claims = Claims {
sub: "user-2".to_string(),
session_id: "session-2".to_string(),
exp: 2000,
ext: CustomExt {
role: "admin".to_string(),
},
};
let context = SecurityContext::new(claims.clone());
assert_eq!(context.sub(), "user-2");
assert_eq!(context.session_id(), "session-2");
assert_eq!(context.ext().role, "admin");
assert_eq!(context.claims().exp, 2000);
}
}