use crate::Extensions;
#[derive(Clone, Debug, PartialEq, Eq)]
struct AuthStateMarker;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AuthState {
user_id: String,
is_authenticated: bool,
is_admin: bool,
is_active: bool,
_marker: AuthStateMarker,
}
impl AuthState {
pub fn authenticated(user_id: impl Into<String>, is_admin: bool, is_active: bool) -> Self {
Self {
user_id: user_id.into(),
is_authenticated: true,
is_admin,
is_active,
_marker: AuthStateMarker,
}
}
pub fn anonymous() -> Self {
Self {
user_id: String::new(),
is_authenticated: false,
is_admin: false,
is_active: false,
_marker: AuthStateMarker,
}
}
pub fn from_extensions(extensions: &Extensions) -> Option<Self> {
Some(Self {
user_id: extensions.get::<String>()?,
is_authenticated: extensions.get::<bool>()?,
is_admin: false,
is_active: false,
_marker: AuthStateMarker,
})
}
pub fn user_id(&self) -> &str {
&self.user_id
}
pub fn is_authenticated(&self) -> bool {
self.is_authenticated
}
pub fn is_admin(&self) -> bool {
self.is_admin
}
pub fn is_active(&self) -> bool {
self.is_active
}
pub fn is_anonymous(&self) -> bool {
!self.is_authenticated
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_authenticated() {
let state = AuthState::authenticated("user-123", true, true);
assert_eq!(state.user_id(), "user-123");
assert!(state.is_authenticated());
assert!(state.is_admin());
assert!(state.is_active());
}
#[test]
fn test_anonymous() {
let state = AuthState::anonymous();
assert!(state.user_id().is_empty());
assert!(!state.is_authenticated());
assert!(!state.is_admin());
assert!(!state.is_active());
}
}