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