use std::collections::HashMap;
use super::access_level::AccessLevel;
use super::resource_type::ResourceType;
pub mod roles {
pub const OWNER: &str = "owner";
pub const ADMIN: &str = "admin";
pub const MEMBER: &str = "member";
pub const VIEWER: &str = "viewer";
pub const GUEST: &str = "guest";
}
pub fn role_defaults(role: &str) -> HashMap<ResourceType, AccessLevel> {
let mut perms = HashMap::new();
match role.to_lowercase().as_str() {
"owner" | "admin" => {
perms.insert(ResourceType::Messages, AccessLevel::Edit);
perms.insert(ResourceType::Documents, AccessLevel::Edit);
perms.insert(ResourceType::KanbanBoards, AccessLevel::Edit);
perms.insert(ResourceType::Files, AccessLevel::Edit);
perms.insert(ResourceType::Members, AccessLevel::Edit);
perms.insert(ResourceType::Settings, AccessLevel::Edit);
}
"member" => {
perms.insert(ResourceType::Messages, AccessLevel::Edit);
perms.insert(ResourceType::Documents, AccessLevel::Edit);
perms.insert(ResourceType::KanbanBoards, AccessLevel::Edit);
perms.insert(ResourceType::Files, AccessLevel::Edit);
perms.insert(ResourceType::Members, AccessLevel::ReadOnly);
perms.insert(ResourceType::Settings, AccessLevel::ReadOnly);
}
"viewer" | "guest" => {
perms.insert(ResourceType::Messages, AccessLevel::ReadOnly);
perms.insert(ResourceType::Documents, AccessLevel::ReadOnly);
perms.insert(ResourceType::KanbanBoards, AccessLevel::ReadOnly);
perms.insert(ResourceType::Files, AccessLevel::ReadOnly);
perms.insert(ResourceType::Members, AccessLevel::ReadOnly);
perms.insert(ResourceType::Settings, AccessLevel::NotVisible);
}
_ => {
perms.insert(ResourceType::Messages, AccessLevel::ReadOnly);
perms.insert(ResourceType::Documents, AccessLevel::NotVisible);
perms.insert(ResourceType::KanbanBoards, AccessLevel::NotVisible);
perms.insert(ResourceType::Files, AccessLevel::NotVisible);
perms.insert(ResourceType::Members, AccessLevel::NotVisible);
perms.insert(ResourceType::Settings, AccessLevel::NotVisible);
}
}
perms
}
pub fn most_permissive_role() -> &'static str {
roles::OWNER
}
pub fn least_permissive_role() -> &'static str {
roles::GUEST
}
pub fn is_standard_role(role: &str) -> bool {
matches!(
role.to_lowercase().as_str(),
"owner" | "admin" | "member" | "viewer" | "guest"
)
}
pub fn standard_roles() -> &'static [&'static str] {
&[
roles::OWNER,
roles::ADMIN,
roles::MEMBER,
roles::VIEWER,
roles::GUEST,
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_owner_has_full_access() {
let perms = role_defaults("owner");
for resource in ResourceType::all() {
assert_eq!(
perms.get(resource),
Some(&AccessLevel::Edit),
"Owner should have Edit access to {:?}",
resource
);
}
}
#[test]
fn test_admin_same_as_owner() {
let owner_perms = role_defaults("owner");
let admin_perms = role_defaults("admin");
for resource in ResourceType::all() {
assert_eq!(
owner_perms.get(resource),
admin_perms.get(resource),
"Admin should have same permissions as owner for {:?}",
resource
);
}
}
#[test]
fn test_member_permissions() {
let perms = role_defaults("member");
assert_eq!(perms.get(&ResourceType::Messages), Some(&AccessLevel::Edit));
assert_eq!(
perms.get(&ResourceType::Documents),
Some(&AccessLevel::Edit)
);
assert_eq!(
perms.get(&ResourceType::KanbanBoards),
Some(&AccessLevel::Edit)
);
assert_eq!(perms.get(&ResourceType::Files), Some(&AccessLevel::Edit));
assert_eq!(
perms.get(&ResourceType::Members),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Settings),
Some(&AccessLevel::ReadOnly)
);
}
#[test]
fn test_viewer_permissions() {
let perms = role_defaults("viewer");
assert_eq!(
perms.get(&ResourceType::Messages),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Documents),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::KanbanBoards),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Settings),
Some(&AccessLevel::NotVisible)
);
}
#[test]
fn test_unknown_role_minimal_access() {
let perms = role_defaults("unknown_role");
assert_eq!(
perms.get(&ResourceType::Messages),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Documents),
Some(&AccessLevel::NotVisible)
);
assert_eq!(
perms.get(&ResourceType::Settings),
Some(&AccessLevel::NotVisible)
);
}
#[test]
fn test_case_insensitivity() {
let lower = role_defaults("member");
let upper = role_defaults("MEMBER");
let mixed = role_defaults("Member");
for resource in ResourceType::all() {
assert_eq!(lower.get(resource), upper.get(resource));
assert_eq!(lower.get(resource), mixed.get(resource));
}
}
#[test]
fn test_is_standard_role() {
assert!(is_standard_role("owner"));
assert!(is_standard_role("ADMIN"));
assert!(is_standard_role("member"));
assert!(!is_standard_role("custom_role"));
assert!(!is_standard_role(""));
}
#[test]
fn test_standard_roles() {
let roles = standard_roles();
assert!(roles.contains(&"owner"));
assert!(roles.contains(&"admin"));
assert!(roles.contains(&"member"));
assert!(roles.contains(&"viewer"));
assert!(roles.contains(&"guest"));
}
#[test]
fn test_most_permissive_role() {
let role = most_permissive_role();
assert_eq!(role, roles::OWNER);
let perms = role_defaults(role);
for resource in ResourceType::all() {
assert_eq!(
perms.get(resource),
Some(&AccessLevel::Edit),
"Most permissive role should have Edit on {:?}",
resource
);
}
}
#[test]
fn test_least_permissive_role() {
let role = least_permissive_role();
assert_eq!(role, roles::GUEST);
let perms = role_defaults(role);
assert_eq!(
perms.get(&ResourceType::Messages),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Settings),
Some(&AccessLevel::NotVisible)
);
}
#[test]
fn test_guest_permissions() {
let perms = role_defaults("guest");
assert_eq!(
perms.get(&ResourceType::Messages),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Documents),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::KanbanBoards),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Files),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Members),
Some(&AccessLevel::ReadOnly)
);
assert_eq!(
perms.get(&ResourceType::Settings),
Some(&AccessLevel::NotVisible)
);
}
#[test]
fn test_roles_constants() {
assert_eq!(roles::OWNER, "owner");
assert_eq!(roles::ADMIN, "admin");
assert_eq!(roles::MEMBER, "member");
assert_eq!(roles::VIEWER, "viewer");
assert_eq!(roles::GUEST, "guest");
}
}