#![allow(clippy::match_same_arms)]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum Role {
Auditor,
User,
Analyst,
Admin,
}
impl Role {
pub fn can_read(&self) -> bool {
match self {
Role::Auditor => true, Role::User => true,
Role::Analyst => true,
Role::Admin => true,
}
}
pub fn can_write(&self) -> bool {
match self {
Role::Auditor => false,
Role::User => true, Role::Analyst => false,
Role::Admin => true,
}
}
pub fn can_delete(&self) -> bool {
match self {
Role::Auditor => false,
Role::User => false, Role::Analyst => false,
Role::Admin => true,
}
}
pub fn can_export(&self) -> bool {
match self {
Role::Auditor => false,
Role::User => false,
Role::Analyst => true, Role::Admin => true,
}
}
pub fn can_access_audit_logs(&self) -> bool {
match self {
Role::Auditor => true,
Role::User => false,
Role::Analyst => false,
Role::Admin => true,
}
}
pub fn has_cross_tenant_access(&self) -> bool {
match self {
Role::Auditor => false, Role::User => false,
Role::Analyst => true,
Role::Admin => true,
}
}
pub fn restrictiveness(&self) -> u8 {
match self {
Role::Admin => 0, Role::Analyst => 1,
Role::User => 2,
Role::Auditor => 3, }
}
pub fn can_escalate_to(&self, target: Role) -> bool {
self.restrictiveness() <= target.restrictiveness()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_role_ordering() {
assert!(Role::Auditor < Role::User);
assert!(Role::User < Role::Analyst);
assert!(Role::Analyst < Role::Admin);
assert!(Role::Admin.restrictiveness() < Role::Analyst.restrictiveness());
assert!(Role::Analyst.restrictiveness() < Role::User.restrictiveness());
assert!(Role::User.restrictiveness() < Role::Auditor.restrictiveness());
}
#[test]
fn test_role_permissions() {
assert!(Role::Auditor.can_read());
assert!(!Role::Auditor.can_write());
assert!(!Role::Auditor.can_delete());
assert!(!Role::Auditor.can_export());
assert!(Role::Auditor.can_access_audit_logs());
assert!(!Role::Auditor.has_cross_tenant_access());
assert!(Role::User.can_read());
assert!(Role::User.can_write());
assert!(!Role::User.can_delete());
assert!(!Role::User.can_export());
assert!(!Role::User.can_access_audit_logs());
assert!(!Role::User.has_cross_tenant_access());
assert!(Role::Analyst.can_read());
assert!(!Role::Analyst.can_write());
assert!(!Role::Analyst.can_delete());
assert!(Role::Analyst.can_export());
assert!(!Role::Analyst.can_access_audit_logs());
assert!(Role::Analyst.has_cross_tenant_access());
assert!(Role::Admin.can_read());
assert!(Role::Admin.can_write());
assert!(Role::Admin.can_delete());
assert!(Role::Admin.can_export());
assert!(Role::Admin.can_access_audit_logs());
assert!(Role::Admin.has_cross_tenant_access());
}
#[test]
fn test_escalation_prevention() {
assert!(!Role::User.can_escalate_to(Role::Admin));
assert!(!Role::User.can_escalate_to(Role::Analyst));
assert!(!Role::Auditor.can_escalate_to(Role::User));
assert!(Role::Admin.can_escalate_to(Role::User));
assert!(Role::Admin.can_escalate_to(Role::Auditor));
assert!(Role::Analyst.can_escalate_to(Role::User));
assert!(Role::User.can_escalate_to(Role::User));
assert!(Role::Admin.can_escalate_to(Role::Admin));
}
#[test]
fn test_restrictiveness_ordering() {
assert!(Role::Admin.restrictiveness() < Role::Analyst.restrictiveness());
assert!(Role::Analyst.restrictiveness() < Role::User.restrictiveness());
assert!(Role::User.restrictiveness() < Role::Auditor.restrictiveness());
}
}