Skip to main content

Mountain/IPC/Permission/Role/ManageRole/
Permission.rs

1
2//! `Permission::Struct` - RBAC permission descriptor.
3//! `category.action` name shape (validated by `Validate`),
4//! human description, category bucket, and an `IsSensitive`
5//! flag that drives elevated audit logging in the
6//! `LogEvent` module.
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct Struct {
12	pub Name:String,
13
14	pub Description:String,
15
16	pub Category:String,
17
18	pub IsSensitive:bool,
19}
20
21impl Struct {
22	pub fn New(Name:String, Description:String, Category:String) -> Self {
23		Self { Name, Description, Category, IsSensitive:false }
24	}
25
26	pub fn NewSensitive(Name:String, Description:String, Category:String) -> Self {
27		Self { Name, Description, Category, IsSensitive:true }
28	}
29
30	pub fn SetSensitive(mut self) -> Self {
31		self.IsSensitive = true;
32
33		self
34	}
35
36	pub fn GetAction(&self) -> String { self.Name.rsplit('.').next().unwrap_or("unknown").to_string() }
37
38	pub fn GetCategory(&self) -> String {
39		if let Some(pos) = self.Name.rfind('.') {
40			self.Name[..pos].to_string()
41		} else {
42			"unknown".to_string()
43		}
44	}
45
46	pub fn Validate(&self) -> Result<(), String> {
47		if self.Name.is_empty() {
48			return Err("Permission name cannot be empty".to_string());
49		}
50
51		if self.Name.contains(|c:char| c.is_whitespace()) {
52			return Err("Permission name cannot contain whitespace".to_string());
53		}
54
55		if !self.Name.contains('.') {
56			return Err("Permission name must contain a dot separating category and action".to_string());
57		}
58
59		if self.Description.is_empty() {
60			return Err("Permission description cannot be empty".to_string());
61		}
62
63		if self.Category.is_empty() {
64			return Err("Permission category cannot be empty".to_string());
65		}
66
67		Ok(())
68	}
69}