Mountain/IPC/Permission/Validate/ValidatePermission/
Validator.rs1#![allow(non_snake_case)]
2
3use std::{
11 collections::HashMap,
12 sync::Arc,
13 time::{Duration, SystemTime},
14};
15
16use tokio::sync::RwLock;
17
18use crate::{
19 IPC::Permission::{
20 Role::ManageRole::{Permission::Struct as Permission, Role::Struct as Role},
21 Validate::ValidatePermission::SecurityContext::Struct as SecurityContext,
22 },
23 dev_log,
24};
25
26pub struct Struct {
27 pub(super) Roles:Arc<RwLock<HashMap<String, Role>>>,
28
29 pub(super) Permissions:Arc<RwLock<HashMap<String, Permission>>>,
30
31 pub(super) OperationPermissions:HashMap<String, Vec<String>>,
32
33 pub(super) ValidationTimeoutMillis:u64,
34}
35
36impl Struct {
37 pub fn New(ValidationTimeoutMillis:u64) -> Self {
38 Self {
39 Roles:Arc::new(RwLock::new(HashMap::new())),
40
41 Permissions:Arc::new(RwLock::new(HashMap::new())),
42
43 OperationPermissions:Self::BuildOperationMapping(),
44
45 ValidationTimeoutMillis,
46 }
47 }
48
49 fn BuildOperationMapping() -> HashMap<String, Vec<String>> {
50 let mut mapping = HashMap::new();
51
52 mapping.insert("file:write".to_string(), vec!["file.write".to_string()]);
53
54 mapping.insert("file:delete".to_string(), vec!["file.write".to_string()]);
55
56 mapping.insert("file:read".to_string(), vec!["file.read".to_string()]);
57
58 mapping.insert("configuration:update".to_string(), vec!["config.update".to_string()]);
59
60 mapping.insert("configuration:read".to_string(), vec!["config.read".to_string()]);
61
62 mapping.insert("storage:set".to_string(), vec!["storage.write".to_string()]);
63
64 mapping.insert("storage:get".to_string(), vec!["storage.read".to_string()]);
65
66 mapping.insert("native:openExternal".to_string(), vec!["system.external".to_string()]);
67
68 mapping.insert("system:execute".to_string(), vec!["system.execute".to_string()]);
69
70 mapping.insert("admin:manage".to_string(), vec!["admin.manage".to_string()]);
71
72 mapping
73 }
74
75 pub fn CreateSecurityContext(
76 UserId:String,
77
78 Roles:Vec<String>,
79
80 IpAddress:String,
81
82 DirectPermissions:Vec<String>,
83 ) -> SecurityContext {
84 let ValidRoles = if Roles.is_empty() { vec!["user".to_string()] } else { Roles };
85
86 let ValidIpAddress = if IpAddress.is_empty() { "127.0.0.1".to_string() } else { IpAddress };
87
88 SecurityContext {
89 UserId,
90
91 Roles:ValidRoles,
92
93 Permissions:DirectPermissions,
94
95 IpAddress:ValidIpAddress,
96
97 Timestamp:SystemTime::now(),
98 }
99 }
100
101 pub async fn ValidatePermission(&self, Operation:&str, Context:&SecurityContext) -> Result<(), String> {
102 let timeout_duration = Duration::from_millis(self.ValidationTimeoutMillis);
103
104 let result = tokio::time::timeout(timeout_duration, async {
105 self.ValidatePermissionInternal(Operation, Context).await
106 })
107 .await;
108
109 match result {
110 Ok(validation_result) => validation_result,
111
112 Err(_) => {
113 dev_log!(
114 "ipc",
115 "error: [PermissionValidator] Permission validation timed out for operation: {}",
116 Operation
117 );
118
119 Err("Permission validation timeout".to_string())
120 },
121 }
122 }
123
124 async fn ValidatePermissionInternal(&self, Operation:&str, Context:&SecurityContext) -> Result<(), String> {
125 if Operation.is_empty() {
126 return Err("Operation name cannot be empty".to_string());
127 }
128
129 if Context.UserId.is_empty() {
130 return Err("User ID cannot be empty".to_string());
131 }
132
133 if Context.Roles.is_empty() && Context.Permissions.is_empty() {
134 return Err("User has no assigned roles or permissions".to_string());
135 }
136
137 let RequiredPermissions = match self.OperationPermissions.get(Operation) {
138 Some(perms) => perms.clone(),
139
140 None => return Ok(()),
141 };
142
143 if RequiredPermissions.is_empty() {
144 return Ok(());
145 }
146
147 let UserPermissions = self.AggregateUserPermissions(Context).await?;
148
149 for RequiredPermission in &RequiredPermissions {
150 if !UserPermissions.contains(RequiredPermission) {
151 return Err(format!("Missing required permission: {}", RequiredPermission));
152 }
153 }
154
155 Ok(())
156 }
157
158 async fn AggregateUserPermissions(&self, Context:&SecurityContext) -> Result<Vec<String>, String> {
159 let mut UserPermissions:Vec<String> = Context.Permissions.clone();
160
161 let roles_read = self.Roles.read().await;
162
163 for RoleName in &Context.Roles {
164 if let Some(role) = roles_read.get(RoleName) {
165 for Permission in &role.Permissions {
166 if !UserPermissions.contains(Permission) {
167 UserPermissions.push(Permission.clone());
168 }
169 }
170 } else {
171 dev_log!("ipc", "[PermissionValidator] Role not found: {}, skipping", RoleName);
172 }
173 }
174
175 Ok(UserPermissions)
176 }
177
178 pub async fn RegisterRole(&self, Role:Role) -> Result<(), String> {
179 if Role.Name.is_empty() {
180 return Err("Role name cannot be empty".to_string());
181 }
182
183 let mut roles = self.Roles.write().await;
184
185 let permissions_read = self.Permissions.read().await;
186
187 for PermissionName in &Role.Permissions {
188 if !permissions_read.contains_key(PermissionName) {
189 dev_log!(
190 "ipc",
191 "warn: [PermissionValidator] Permission '{}' referenced by role '{}' does not exist",
192 PermissionName,
193 Role.Name
194 );
195 }
196 }
197
198 drop(permissions_read);
199
200 let RoleName = Role.Name.clone();
201
202 roles.insert(RoleName.clone(), Role);
203
204 dev_log!("ipc", "[PermissionValidator] Role registered: {}", RoleName);
205
206 Ok(())
207 }
208
209 pub async fn RegisterPermission(&self, Permission:Permission) -> Result<(), String> {
210 if Permission.Name.is_empty() {
211 return Err("Permission name cannot be empty".to_string());
212 }
213
214 if Permission.Description.is_empty() {
215 return Err("Permission description cannot be empty".to_string());
216 }
217
218 let mut permissions = self.Permissions.write().await;
219
220 let PermissionName = Permission.Name.clone();
221
222 permissions.insert(PermissionName.clone(), Permission);
223
224 dev_log!("ipc", "[PermissionValidator] Permission registered: {}", PermissionName);
225
226 Ok(())
227 }
228
229 pub async fn GetRolePermissions(&self, RoleName:&str) -> Vec<String> {
230 let roles = self.Roles.read().await;
231
232 roles.get(RoleName).map(|role| role.Permissions.clone()).unwrap_or_default()
233 }
234
235 pub async fn HasPermission(&self, Context:&SecurityContext, PermissionName:&str) -> bool {
236 if Context.Permissions.contains(&PermissionName.to_string()) {
237 return true;
238 }
239
240 let roles = self.Roles.read().await;
241
242 for RoleName in &Context.Roles {
243 if let Some(role) = roles.get(RoleName) {
244 if role.Permissions.contains(&PermissionName.to_string()) {
245 return true;
246 }
247 }
248 }
249
250 false
251 }
252
253 pub async fn InitializeDefaults(&self) -> Result<(), String> {
254 dev_log!("ipc", "[PermissionValidator] Initializing default roles and permissions");
255
256 let DefaultPermissions = vec![
257 Permission {
258 Name:"file.read".to_string(),
259
260 Description:"Read file operations".to_string(),
261
262 Category:"file".to_string(),
263
264 IsSensitive:false,
265 },
266 Permission {
267 Name:"file.write".to_string(),
268
269 Description:"Write file operations".to_string(),
270
271 Category:"file".to_string(),
272
273 IsSensitive:false,
274 },
275 Permission {
276 Name:"config.read".to_string(),
277
278 Description:"Read configuration".to_string(),
279
280 Category:"config".to_string(),
281
282 IsSensitive:false,
283 },
284 Permission {
285 Name:"config.update".to_string(),
286
287 Description:"Update configuration".to_string(),
288
289 Category:"config".to_string(),
290
291 IsSensitive:false,
292 },
293 Permission {
294 Name:"storage.read".to_string(),
295
296 Description:"Read storage".to_string(),
297
298 Category:"storage".to_string(),
299
300 IsSensitive:false,
301 },
302 Permission {
303 Name:"storage.write".to_string(),
304
305 Description:"Write storage".to_string(),
306
307 Category:"storage".to_string(),
308
309 IsSensitive:false,
310 },
311 Permission {
312 Name:"system.external".to_string(),
313
314 Description:"Access external system resources".to_string(),
315
316 Category:"system".to_string(),
317
318 IsSensitive:true,
319 },
320 Permission {
321 Name:"system.execute".to_string(),
322
323 Description:"Execute system commands".to_string(),
324
325 Category:"system".to_string(),
326
327 IsSensitive:true,
328 },
329 Permission {
330 Name:"admin.manage".to_string(),
331
332 Description:"Administrative management operations".to_string(),
333
334 Category:"admin".to_string(),
335
336 IsSensitive:true,
337 },
338 ];
339
340 for Permission in DefaultPermissions {
341 self.RegisterPermission(Permission).await?;
342 }
343
344 let DefaultRoles = vec![
345 Role {
346 Name:"user".to_string(),
347
348 Permissions:vec!["file.read".to_string(), "config.read".to_string(), "storage.read".to_string()],
349
350 Description:"Standard user with read access".to_string(),
351
352 ParentRole:None,
353
354 Priority:0,
355 },
356 Role {
357 Name:"developer".to_string(),
358
359 Permissions:vec![
360 "file.read".to_string(),
361 "file.write".to_string(),
362 "config.read".to_string(),
363 "storage.read".to_string(),
364 "storage.write".to_string(),
365 ],
366
367 Description:"Developer with read/write access".to_string(),
368
369 ParentRole:None,
370
371 Priority:1,
372 },
373 Role {
374 Name:"admin".to_string(),
375
376 Permissions:vec![
377 "file.read".to_string(),
378 "file.write".to_string(),
379 "config.read".to_string(),
380 "config.update".to_string(),
381 "storage.read".to_string(),
382 "storage.write".to_string(),
383 "system.external".to_string(),
384 "system.execute".to_string(),
385 "admin.manage".to_string(),
386 ],
387
388 Description:"Administrator with full access".to_string(),
389
390 ParentRole:None,
391
392 Priority:2,
393 },
394 ];
395
396 for Role in DefaultRoles {
397 self.RegisterRole(Role).await?;
398 }
399
400 dev_log!(
401 "ipc",
402 "[PermissionValidator] Default roles and permissions initialized successfully"
403 );
404
405 Ok(())
406 }
407}