use chrono::{DateTime, Utc};
#[derive(Debug, Clone, PartialEq)]
pub struct AuthnStatementRef<'a> {
pub authn_instant: DateTime<Utc>,
pub session_index: Option<&'a str>,
pub session_not_on_or_after: Option<DateTime<Utc>>,
pub subject_locality: Option<SubjectLocalityRef<'a>>,
pub authn_context: AuthnContextRef<'a>,
}
impl<'a> AuthnStatementRef<'a> {
pub fn to_owned(&self) -> AuthnStatement {
AuthnStatement {
authn_instant: self.authn_instant,
session_index: self.session_index.map(str::to_string),
session_not_on_or_after: self.session_not_on_or_after,
subject_locality: self.subject_locality.as_ref().map(|sl| sl.to_owned()),
authn_context: self.authn_context.to_owned(),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct AuthnStatement {
pub authn_instant: DateTime<Utc>,
pub session_index: Option<String>,
pub session_not_on_or_after: Option<DateTime<Utc>>,
pub subject_locality: Option<SubjectLocality>,
pub authn_context: AuthnContext,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SubjectLocalityRef<'a> {
pub address: Option<&'a str>,
pub dns_name: Option<&'a str>,
}
impl<'a> SubjectLocalityRef<'a> {
pub fn to_owned(&self) -> SubjectLocality {
SubjectLocality {
address: self.address.map(str::to_string),
dns_name: self.dns_name.map(str::to_string),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SubjectLocality {
pub address: Option<String>,
pub dns_name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AuthnContextRef<'a> {
pub authn_context_class_ref: Option<&'a str>,
pub authn_context_decl_ref: Option<&'a str>,
pub authenticating_authorities: Vec<&'a str>,
}
impl<'a> AuthnContextRef<'a> {
pub fn to_owned(&self) -> AuthnContext {
AuthnContext {
authn_context_class_ref: self.authn_context_class_ref.map(str::to_string),
authn_context_decl_ref: self.authn_context_decl_ref.map(str::to_string),
authenticating_authorities: self
.authenticating_authorities
.iter()
.map(|a| a.to_string())
.collect(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AuthnContext {
pub authn_context_class_ref: Option<String>,
pub authn_context_decl_ref: Option<String>,
pub authenticating_authorities: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::constants::AUTHN_CONTEXT_PASSWORD_PROTECTED_TRANSPORT;
use chrono::Utc;
#[test]
fn test_authn_statement_ref_to_owned() {
let now = Utc::now();
let stmt_ref = AuthnStatementRef {
authn_instant: now,
session_index: Some("_session_1"),
session_not_on_or_after: None,
subject_locality: Some(SubjectLocalityRef {
address: Some("192.168.1.1"),
dns_name: Some("client.example.com"),
}),
authn_context: AuthnContextRef {
authn_context_class_ref: Some(AUTHN_CONTEXT_PASSWORD_PROTECTED_TRANSPORT),
authn_context_decl_ref: None,
authenticating_authorities: vec![],
},
};
let owned = stmt_ref.to_owned();
assert_eq!(owned.authn_instant, now);
assert_eq!(owned.session_index.as_deref(), Some("_session_1"));
assert_eq!(
owned.authn_context.authn_context_class_ref.as_deref(),
Some(AUTHN_CONTEXT_PASSWORD_PROTECTED_TRANSPORT)
);
assert_eq!(
owned.subject_locality.as_ref().unwrap().address.as_deref(),
Some("192.168.1.1")
);
}
}