use std::fmt;
use serde::Deserialize;
use crate::error::AuthError;
#[derive(Debug)]
pub enum AuthStrategy {
ABAC,
RBAC,
SBA,
}
impl AuthStrategy {
pub fn from_str(strategy: &str) -> Result<Self, AuthError> {
match strategy.to_uppercase().as_str() {
"ABAC" => Ok(AuthStrategy::ABAC),
"RBAC" => Ok(AuthStrategy::RBAC),
"SBA" => Ok(AuthStrategy::SBA),
_ => Err(AuthError::InvalidStrategy(strategy.to_string())),
}
}
}
pub struct AuthContext {
pub user: Option<User>,
pub claims: Option<Claims>,
pub resource: Option<Resource>,
}
#[derive(Debug, Clone)]
pub struct User {
pub email: String,
pub password_hash: String,
pub role: Role,
pub department: String,
pub clearance_level: u8,
}
pub trait Identifiable {
fn identity(&self) -> String;
}
impl Identifiable for User {
fn identity(&self) -> String {
self.email.clone()
}
}
impl Identifiable for Claims {
fn identity(&self) -> String {
self.email.clone()
}
}
#[derive(Debug, Deserialize, Clone)]
pub struct Claims {
pub email: String,
pub service: String,
pub scopes: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct Resource {
pub department: String,
pub required_level: u8,
}
#[derive(Debug, Clone)]
pub struct Role {
pub name: String,
pub permissions: Vec<Permission>,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Permission {
Create,
Read,
Update,
Delete,
}
impl fmt::Display for Permission {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Permission::Create => "create",
Permission::Read => "read",
Permission::Update => "update",
Permission::Delete => "delete",
};
write!(f, "{}", s)
}
}