use crate::models::{
CapabilityDescriptor, CapabilityHexUnitSet, CapabilityName, CapabilityNameSet, CapilityHexValue,
};
pub struct RoleCapability {
descriptor: CapabilityDescriptor,
pub hex_value: CapilityHexValue,
}
impl RoleCapability {
pub fn new(descriptor: CapabilityDescriptor, hex_value: CapilityHexValue) -> Self {
RoleCapability {
descriptor,
hex_value,
}
}
pub fn to_hex_set(&self) -> CapabilityHexUnitSet {
let mut hex_set = CapabilityHexUnitSet::new();
let mut tmp = self.descriptor.values();
while let Some(&value) = tmp.next() {
if self.hex_value & value != 0 {
hex_set.insert(value);
}
}
hex_set
}
pub fn to_name_set(&self) -> CapabilityNameSet {
let mut name_set = CapabilityNameSet::new();
for (name, &value) in &self.descriptor {
if self.hex_value & value != 0 {
name_set.insert(name.clone());
}
}
name_set
}
pub fn has_capability(&self, permission_name: &CapabilityName) -> bool {
if let Some(&value) = self.descriptor.get(permission_name) {
return self.hex_value & value != 0;
}
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::models::CapabilityDescriptor;
fn create_test_descriptor() -> CapabilityDescriptor {
let mut descriptor = CapabilityDescriptor::new();
descriptor.insert("Read".to_string(), 0x1);
descriptor.insert("Write".to_string(), 0x2);
descriptor.insert("Execute".to_string(), 0x4);
descriptor.insert("Admin".to_string(), 0x8);
descriptor
}
#[test]
fn test_role_capability_new() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor.clone(), 0x5);
assert_eq!(role.hex_value, 0x5);
}
#[test]
fn test_to_hex_set() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x5);
let hex_set = role.to_hex_set();
assert!(hex_set.contains(&0x1)); assert!(!hex_set.contains(&0x2)); assert!(hex_set.contains(&0x4)); assert!(!hex_set.contains(&0x8)); assert_eq!(hex_set.len(), 2);
}
#[test]
fn test_to_hex_set_empty_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x0);
let hex_set = role.to_hex_set();
assert!(hex_set.is_empty());
}
#[test]
fn test_to_hex_set_all_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor.clone(), 0xF);
let hex_set = role.to_hex_set();
assert_eq!(hex_set.len(), 4);
assert!(hex_set.contains(&0x1)); assert!(hex_set.contains(&0x2)); assert!(hex_set.contains(&0x4)); assert!(hex_set.contains(&0x8)); }
#[test]
fn test_to_name_set() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x3);
let name_set = role.to_name_set();
assert!(name_set.contains("Read"));
assert!(name_set.contains("Write"));
assert!(!name_set.contains("Execute"));
assert!(!name_set.contains("Admin"));
assert_eq!(name_set.len(), 2);
}
#[test]
fn test_to_name_set_empty_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x0);
let name_set = role.to_name_set();
assert!(name_set.is_empty());
}
#[test]
fn test_to_name_set_all_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor.clone(), 0xF);
let name_set = role.to_name_set();
assert_eq!(name_set.len(), 4);
assert!(name_set.contains("Read"));
assert!(name_set.contains("Write"));
assert!(name_set.contains("Execute"));
assert!(name_set.contains("Admin"));
for (capability_name, _) in &descriptor {
assert!(name_set.contains(capability_name));
}
}
#[test]
fn test_has_capability() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x9);
assert!(role.has_capability(&"Read".to_string()));
assert!(!role.has_capability(&"Write".to_string()));
assert!(!role.has_capability(&"Execute".to_string()));
assert!(role.has_capability(&"Admin".to_string()));
assert!(!role.has_capability(&"NonExistent".to_string()));
}
#[test]
fn test_has_capability_empty_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x0);
assert!(!role.has_capability(&"Read".to_string()));
assert!(!role.has_capability(&"Write".to_string()));
assert!(!role.has_capability(&"Execute".to_string()));
assert!(!role.has_capability(&"Admin".to_string()));
assert!(!role.has_capability(&"NonExistent".to_string()));
}
#[test]
fn test_has_capability_all_permissions() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor.clone(), 0xF);
for (capability_name, _) in &descriptor {
assert!(role.has_capability(capability_name));
}
assert!(!role.has_capability(&"NonExistent".to_string()));
}
#[test]
fn test_has_capability_case_sensitivity() {
let descriptor = create_test_descriptor();
let role = RoleCapability::new(descriptor, 0x1);
assert!(role.has_capability(&"Read".to_string()));
assert!(!role.has_capability(&"read".to_string())); assert!(!role.has_capability(&"READ".to_string())); }
#[test]
fn test_complex_permission_combinations() {
let descriptor = create_test_descriptor();
let test_cases = vec![
(0x1, vec!["Read"], vec!["Write", "Execute", "Admin"]),
(0x2, vec!["Write"], vec!["Read", "Execute", "Admin"]),
(0x4, vec!["Execute"], vec!["Read", "Write", "Admin"]),
(0x8, vec!["Admin"], vec!["Read", "Write", "Execute"]),
(0x5, vec!["Read", "Execute"], vec!["Write", "Admin"]),
(0xA, vec!["Write", "Admin"], vec!["Read", "Execute"]),
(0xC, vec!["Execute", "Admin"], vec!["Read", "Write"]),
];
for (permission_value, should_have, should_not_have) in test_cases {
let role = RoleCapability::new(descriptor.clone(), permission_value);
for capability in should_have {
assert!(
role.has_capability(&capability.to_string()),
"Role with 0x{:X} should have {} capability",
permission_value,
capability
);
}
for capability in should_not_have {
assert!(
!role.has_capability(&capability.to_string()),
"Role with 0x{:X} should NOT have {} capability",
permission_value,
capability
);
}
}
}
#[test]
fn test_large_permission_system() {
let mut large_descriptor = CapabilityDescriptor::new();
for i in 0..10 {
large_descriptor.insert(format!("Permission{}", i), 1 << i);
}
let role = RoleCapability::new(large_descriptor.clone(), 0x155);
let name_set = role.to_name_set();
let hex_set = role.to_hex_set();
assert_eq!(name_set.len(), 5);
assert_eq!(hex_set.len(), 5);
assert!(role.has_capability(&"Permission0".to_string()));
assert!(!role.has_capability(&"Permission1".to_string()));
assert!(role.has_capability(&"Permission2".to_string()));
assert!(!role.has_capability(&"Permission3".to_string()));
assert!(role.has_capability(&"Permission4".to_string()));
assert!(!role.has_capability(&"Permission5".to_string()));
assert!(role.has_capability(&"Permission6".to_string()));
assert!(!role.has_capability(&"Permission7".to_string()));
assert!(role.has_capability(&"Permission8".to_string()));
assert!(!role.has_capability(&"Permission9".to_string()));
assert!(hex_set.contains(&0x1)); assert!(hex_set.contains(&0x4)); assert!(hex_set.contains(&0x10)); assert!(hex_set.contains(&0x40)); assert!(hex_set.contains(&0x100)); }
#[test]
fn test_descriptor_with_custom_hex_values() {
let mut custom_descriptor = CapabilityDescriptor::new();
custom_descriptor.insert("CustomA".to_string(), 0x10);
custom_descriptor.insert("CustomB".to_string(), 0x20);
custom_descriptor.insert("CustomC".to_string(), 0x40);
let role = RoleCapability::new(custom_descriptor, 0x30);
assert!(role.has_capability(&"CustomA".to_string()));
assert!(role.has_capability(&"CustomB".to_string()));
assert!(!role.has_capability(&"CustomC".to_string()));
let hex_set = role.to_hex_set();
assert!(hex_set.contains(&0x10));
assert!(hex_set.contains(&0x20));
assert!(!hex_set.contains(&0x40));
}
#[test]
fn test_empty_descriptor() {
let empty_descriptor = CapabilityDescriptor::new();
let role = RoleCapability::new(empty_descriptor, 0x0);
assert!(role.to_hex_set().is_empty());
assert!(role.to_name_set().is_empty());
assert!(!role.has_capability(&"AnyCapability".to_string()));
}
}