use serde::{Deserialize, Serialize};
pub trait AuthUser: Send + Sync {
fn user_id(&self) -> String;
fn is_active(&self) -> bool {
true
}
fn has_role(&self, role: &str) -> bool;
fn has_any_role(&self, roles: &[&str]) -> bool {
roles.iter().any(|role| self.has_role(role))
}
fn has_all_roles(&self, roles: &[&str]) -> bool {
roles.iter().all(|role| self.has_role(role))
}
fn has_permission(&self, permission: &str) -> bool;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserContext {
pub user_id: String,
pub email: Option<String>,
pub roles: Vec<String>,
pub permissions: Vec<String>,
#[serde(default)]
pub metadata: serde_json::Value,
}
impl UserContext {
pub fn new(user_id: String) -> Self {
Self {
user_id,
email: None,
roles: Vec::new(),
permissions: Vec::new(),
metadata: serde_json::Value::Null,
}
}
pub fn with_email(mut self, email: String) -> Self {
self.email = Some(email);
self
}
pub fn with_role(mut self, role: String) -> Self {
self.roles.push(role);
self
}
pub fn with_roles(mut self, roles: Vec<String>) -> Self {
self.roles = roles;
self
}
pub fn with_permission(mut self, permission: String) -> Self {
self.permissions.push(permission);
self
}
pub fn with_permissions(mut self, permissions: Vec<String>) -> Self {
self.permissions = permissions;
self
}
pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
self.metadata = metadata;
self
}
}
impl AuthUser for UserContext {
fn user_id(&self) -> String {
self.user_id.clone()
}
fn has_role(&self, role: &str) -> bool {
self.roles.iter().any(|r| r == role)
}
fn has_permission(&self, permission: &str) -> bool {
self.permissions.iter().any(|p| p == permission)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_user_context() {
let user = UserContext::new("user123".to_string())
.with_email("user@example.com".to_string())
.with_roles(vec!["admin".to_string(), "user".to_string()])
.with_permissions(vec!["read".to_string(), "write".to_string()]);
assert_eq!(user.user_id(), "user123");
assert!(user.has_role("admin"));
assert!(user.has_role("user"));
assert!(!user.has_role("guest"));
assert!(user.has_any_role(&["admin", "guest"]));
assert!(!user.has_all_roles(&["admin", "guest"]));
assert!(user.has_permission("read"));
assert!(user.has_permission("write"));
assert!(!user.has_permission("delete"));
}
}