Skip to main content

Mountain/IPC/Security/PermissionManager/
Manager.rs

1#![allow(non_snake_case)]
2
3//! `Manager::Struct` - the IPC RBAC enforcement core. Holds
4//! the role / permission tables and the rolling 1k audit log;
5//! `validate_permission` is the gate every IPC operation
6//! passes through before dispatch. The struct + impl + tests
7//! stay in one file - tightly coupled cluster.
8
9use std::{collections::HashMap, sync::Arc};
10
11use tokio::sync::RwLock;
12
13use crate::{
14	IPC::Security::{
15		Permission::Permission,
16		PermissionManager::{
17			SecurityContext::Struct as SecurityContext,
18			SecurityEvent::Struct as SecurityEvent,
19			SecurityEventType::Enum as SecurityEventType,
20		},
21		Role::Role,
22	},
23	dev_log,
24};
25
26pub struct Struct {
27	pub(super) roles:Arc<RwLock<HashMap<String, Role>>>,
28	pub(super) permissions:Arc<RwLock<HashMap<String, Permission>>>,
29	pub(super) audit_log:Arc<RwLock<Vec<SecurityEvent>>>,
30}
31
32impl Struct {
33	pub fn new() -> Self {
34		dev_log!("ipc", "[PermissionManager] Creating new PermissionManager instance");
35
36		Self {
37			roles:Arc::new(RwLock::new(HashMap::new())),
38			permissions:Arc::new(RwLock::new(HashMap::new())),
39			audit_log:Arc::new(RwLock::new(Vec::new())),
40		}
41	}
42
43	pub async fn validate_permission(&self, operation:&str, context:&SecurityContext) -> Result<(), String> {
44		let required_permissions = self.get_required_permissions(operation).await;
45
46		if required_permissions.is_empty() {
47			dev_log!(
48				"ipc",
49				"[PermissionManager] Operation '{}' requires no special permissions",
50				operation
51			);
52			return Ok(());
53		}
54
55		let mut user_permissions:Vec<String> = context.permissions.iter().cloned().collect();
56
57		for role in context.roles.iter() {
58			let role_perms = self.get_role_permissions(role).await;
59			user_permissions.extend(role_perms);
60		}
61
62		for required in &required_permissions {
63			if !user_permissions.contains(required) {
64				let error = format!("Missing permission: {}", required);
65				dev_log!(
66					"ipc",
67					"[PermissionManager] Permission denied for user '{}' on operation '{}': {}",
68					context.user_id,
69					operation,
70					error
71				);
72
73				self.log_security_event(SecurityEvent {
74					event_type:SecurityEventType::PermissionDenied,
75					user_id:context.user_id.clone(),
76					operation:operation.to_string(),
77					timestamp:std::time::SystemTime::now(),
78					details:Some(format!("Permission denied: {}", error)),
79				})
80				.await;
81
82				return Err(error);
83			}
84		}
85
86		self.log_security_event(SecurityEvent {
87			event_type:SecurityEventType::AccessGranted,
88			user_id:context.user_id.clone(),
89			operation:operation.to_string(),
90			timestamp:std::time::SystemTime::now(),
91			details:Some(format!("Access granted for operation: {}", operation)),
92		})
93		.await;
94
95		dev_log!(
96			"ipc",
97			"[PermissionManager] Access granted for user '{}' on operation '{}'",
98			context.user_id,
99			operation
100		);
101
102		Ok(())
103	}
104
105	async fn get_required_permissions(&self, operation:&str) -> Vec<String> {
106		match operation {
107			"file:write" | "file:delete" => vec!["file.write".to_string()],
108			"configuration:update" => vec!["config.update".to_string()],
109			"storage:set" => vec!["storage.write".to_string()],
110			"native:openExternal" => vec!["system.external".to_string()],
111			_ => Vec::new(),
112		}
113	}
114
115	async fn get_role_permissions(&self, role_name:&str) -> Vec<String> {
116		let roles = self.roles.read().await;
117		roles.get(role_name).map(|role| role.permissions.clone()).unwrap_or_default()
118	}
119
120	pub async fn log_security_event(&self, event:SecurityEvent) {
121		let mut audit_log = self.audit_log.write().await;
122		audit_log.push(event.clone());
123
124		if audit_log.len() > 1000 {
125			audit_log.remove(0);
126		}
127
128		match event.event_type {
129			SecurityEventType::PermissionDenied => {
130				dev_log!(
131					"ipc",
132					"warn: [SecurityEvent] Permission denied - User: {}, Operation: {}, Details: {:?}",
133					event.user_id,
134					event.operation,
135					event.details
136				);
137			},
138			SecurityEventType::SecurityViolation => {
139				dev_log!(
140					"ipc",
141					"error: [SecurityEvent] Security violation - User: {}, Operation: {}, Details: {:?}",
142					event.user_id,
143					event.operation,
144					event.details
145				);
146			},
147			SecurityEventType::AccessGranted => {
148				dev_log!(
149					"ipc",
150					"[SecurityEvent] Access granted - User: {}, Operation: {}",
151					event.user_id,
152					event.operation
153				);
154			},
155			_ => {
156				dev_log!(
157					"ipc",
158					"[SecurityEvent] {:?} - User: {}, Operation: {}",
159					event.event_type,
160					event.user_id,
161					event.operation
162				);
163			},
164		}
165	}
166
167	pub async fn get_audit_log(&self, limit:usize) -> Vec<SecurityEvent> {
168		let audit_log = self.audit_log.read().await;
169		audit_log.iter().rev().take(limit).cloned().collect()
170	}
171
172	pub async fn initialize_defaults(&self) {
173		dev_log!("ipc", "[PermissionManager] Initializing default roles and permissions");
174
175		let mut permissions = self.permissions.write().await;
176		let mut roles = self.roles.write().await;
177
178		let standard_permissions = vec![
179			("file.read", "Read file operations"),
180			("file.write", "Write file operations"),
181			("config.read", "Read configuration"),
182			("config.update", "Update configuration"),
183			("storage.read", "Read storage"),
184			("storage.write", "Write storage"),
185			("system.external", "Access external system resources"),
186		];
187
188		for (name, description) in standard_permissions {
189			permissions.insert(
190				name.to_string(),
191				Permission {
192					name:name.to_string(),
193					description:description.to_string(),
194					category:"standard".to_string(),
195				},
196			);
197		}
198
199		let standard_roles = vec![
200			("user", vec!["file.read", "config.read", "storage.read"]),
201			(
202				"developer",
203				vec!["file.read", "file.write", "config.read", "storage.read", "storage.write"],
204			),
205			(
206				"admin",
207				vec![
208					"file.read",
209					"file.write",
210					"config.read",
211					"config.update",
212					"storage.read",
213					"storage.write",
214					"system.external",
215				],
216			),
217		];
218
219		for (name, role_permissions) in standard_roles {
220			roles.insert(
221				name.to_string(),
222				Role {
223					name:name.to_string(),
224					permissions:role_permissions.iter().map(|p| p.to_string()).collect(),
225					description:format!("{} role with standard permissions", name),
226				},
227			);
228		}
229
230		dev_log!(
231			"ipc",
232			"[PermissionManager] Initialized {} permissions and {} roles",
233			permissions.len(),
234			roles.len()
235		);
236	}
237
238	pub async fn add_role(&self, role:Role) {
239		let role_name = role.name.clone();
240		let mut roles = self.roles.write().await;
241		roles.insert(role_name.clone(), role);
242		dev_log!("ipc", "[PermissionManager] Added role: {}", role_name);
243	}
244
245	pub async fn add_permission(&self, permission:Permission) {
246		let permission_name = permission.name.clone();
247		let mut permissions = self.permissions.write().await;
248		permissions.insert(permission_name.clone(), permission);
249		dev_log!("ipc", "[PermissionManager] Added permission: {}", permission_name);
250	}
251
252	pub async fn clear_audit_log(&self) {
253		let mut audit_log = self.audit_log.write().await;
254		audit_log.clear();
255		dev_log!("ipc", "[PermissionManager] Audit log cleared");
256	}
257
258	pub async fn get_audit_log_stats(&self) -> (usize, Vec<(&'static str, usize)>) {
259		let audit_log = self.audit_log.read().await;
260
261		let mut type_counts:Vec<(&'static str, usize)> = vec![
262			("PermissionDenied", 0),
263			("AccessGranted", 0),
264			("ConfigurationChange", 0),
265			("SecurityViolation", 0),
266			("PerformanceAnomaly", 0),
267		];
268
269		for event in audit_log.iter() {
270			let type_name = match event.event_type {
271				SecurityEventType::PermissionDenied => "PermissionDenied",
272				SecurityEventType::AccessGranted => "AccessGranted",
273				SecurityEventType::ConfigurationChange => "ConfigurationChange",
274				SecurityEventType::SecurityViolation => "SecurityViolation",
275				SecurityEventType::PerformanceAnomaly => "PerformanceAnomaly",
276			};
277			if let Some((_, count)) = type_counts.iter_mut().find(|(name, _)| *name == type_name) {
278				*count += 1;
279			}
280		}
281
282		(audit_log.len(), type_counts)
283	}
284}