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