use crate::port::authenticator::AuthPrincipal;
#[derive(Debug, Clone, Default)]
pub struct RequestContext {
session_id: Option<String>,
principal: Option<AuthPrincipal>,
}
impl RequestContext {
pub fn anonymous() -> Self {
Self::default()
}
#[must_use]
pub fn with_session(mut self, session_id: impl Into<String>) -> Self {
let session_id = session_id.into();
self.session_id = (!session_id.is_empty()).then_some(session_id);
self
}
#[must_use]
pub fn with_principal(mut self, principal: impl Into<Option<AuthPrincipal>>) -> Self {
self.principal = principal.into();
self
}
pub fn session_id(&self) -> Option<&str> {
self.session_id.as_deref()
}
pub fn principal(&self) -> Option<&AuthPrincipal> {
self.principal.as_ref()
}
pub fn caller(&self) -> Option<&str> {
self.principal.as_ref().map(|p| p.id.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_anonymous_call_names_nobody() {
let ctx = RequestContext::anonymous();
assert_eq!(ctx.session_id(), None);
assert_eq!(ctx.caller(), None);
}
#[test]
fn an_empty_session_id_is_no_session() {
let ctx = RequestContext::anonymous().with_session("");
assert_eq!(ctx.session_id(), None);
}
#[test]
fn the_caller_is_the_principals_id() {
let ctx = RequestContext::anonymous()
.with_session("ctx-1")
.with_principal(AuthPrincipal::new("alice".to_string(), "jwt".to_string()));
assert_eq!(ctx.session_id(), Some("ctx-1"));
assert_eq!(ctx.caller(), Some("alice"));
assert_eq!(ctx.principal().map(|p| p.scheme.as_str()), Some("jwt"));
}
}