1use std::cmp::Ordering;
2use std::collections::{HashMap, HashSet};
3use std::ops;
4use std::ops::{Deref, DerefMut};
5use std::str::FromStr;
6
7use nom::combinator::all_consuming;
8use nom_supreme::parser_ext::MapRes;
9use serde::{Deserialize, Serialize};
10
11use cosmic_nom::new_span;
12
13use crate::err::SpaceErr;
14use crate::point::Point;
15use crate::parse::error::result;
16use crate::parse::{particle_perms, permissions, permissions_mask, privilege, MapResolver};
17use crate::selector::{PointHierarchy, Selector};
18use crate::wave::ScopeGrant;
19use crate::Agent;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub enum Access {
23 Super,
24 Owner,
25 SuperOwner,
28 Enumerated(EnumeratedAccess),
29}
30
31impl Access {
32 pub fn has_super(&self) -> bool {
33 match self {
34 Access::Super => true,
35 Access::SuperOwner => true,
36 _ => false,
37 }
38 }
39
40 pub fn has_owner(&self) -> bool {
41 match self {
42 Access::Owner => true,
43 Access::SuperOwner => true,
44 _ => false,
45 }
46 }
47
48 pub fn has_full(&self) -> bool {
49 match self {
50 Access::Super => true,
51 Access::Owner => true,
52 Access::SuperOwner => true,
53 Access::Enumerated(_) => false,
54 }
55 }
56
57 pub fn none() -> Self {
58 Self::Enumerated(EnumeratedAccess::none())
59 }
60
61 pub fn permissions(&self) -> Permissions {
62 match self {
63 Access::Super => Permissions::full(),
64 Access::Owner => Permissions::full(),
65 Access::SuperOwner => Permissions::full(),
66 Access::Enumerated(enumerated) => enumerated.permissions.clone(),
67 }
68 }
69
70 pub fn check_privilege(&self, privilege: &str) -> Result<(), SpaceErr> {
71 match self {
72 Access::Super => Ok(()),
73 Access::Owner => Ok(()),
74 Access::SuperOwner => Ok(()),
75 Access::Enumerated(enumerated) => match enumerated.privileges.has(privilege).is_ok() {
76 true => Ok(()),
77 false => Err(format!("'{}'", privilege).into()),
78 },
79 }
80 }
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub enum Privileges {
85 Full,
86 Enumerated(EnumeratedPrivileges),
87}
88
89impl Privileges {
90 pub fn has(&self, privilege: &str) -> Result<(), ()> {
91 match self {
92 Privileges::Full => Ok(()),
93 Privileges::Enumerated(privileges) => privileges.has(privilege),
94 }
95 }
96
97 pub fn none() -> Self {
98 Self::Enumerated(EnumeratedPrivileges::none())
99 }
100
101 pub fn or(mut self, other: &Self) -> Self {
102 match self {
103 Privileges::Full => self,
104 Privileges::Enumerated(privileges) => match other {
105 Privileges::Full => Privileges::Full,
106 Privileges::Enumerated(other) => Privileges::Enumerated(privileges.or(other)),
107 },
108 }
109 }
110
111 pub fn and(self, other: &Self) -> Privileges {
112 match other {
113 Privileges::Full => self,
114 Privileges::Enumerated(enumerated_other) => match self {
115 Privileges::Full => other.clone(),
116 Privileges::Enumerated(enumerated_self) => {
117 Privileges::Enumerated(enumerated_self.and(enumerated_other))
118 }
119 },
120 }
121 }
122}
123
124impl ops::BitOr<&Privilege> for &Privileges {
125 type Output = Privileges;
126
127 fn bitor(self, rhs: &Privilege) -> Self::Output {
128 match rhs {
129 Privilege::Full => Privileges::Full,
130 Privilege::Single(p) => match self {
131 Privileges::Full => Privileges::Full,
132 Privileges::Enumerated(enumerated) => {
133 let mut enumerated = enumerated.clone();
134 enumerated.set.insert(p.to_string());
135 Privileges::Enumerated(enumerated)
136 }
137 },
138 }
139 }
140}
141
142impl ops::BitOr<&Privilege> for Privileges {
143 type Output = Privileges;
144
145 fn bitor(self, rhs: &Privilege) -> Self::Output {
146 match rhs {
147 Privilege::Full => Privileges::Full,
148 Privilege::Single(p) => match self {
149 Privileges::Full => Privileges::Full,
150 Privileges::Enumerated(enumerated) => {
151 let mut enumerated = enumerated.clone();
152 enumerated.set.insert(p.to_string());
153 Privileges::Enumerated(enumerated)
154 }
155 },
156 }
157 }
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct EnumeratedPrivileges {
162 set: HashSet<String>,
163}
164
165impl EnumeratedPrivileges {
166 pub fn new() -> Self {
167 Self {
168 set: HashSet::new(),
169 }
170 }
171
172 pub fn none() -> Self {
173 Self {
174 set: HashSet::new(),
175 }
176 }
177
178 pub fn or(mut self, other: &Self) -> Self {
179 for p in other.set.iter() {
180 if self.has(p).is_err() {
181 self.add(p.as_str());
182 }
183 }
184 self
185 }
186
187 pub fn and(mut self, other: &Self) -> Self {
188 self.set.retain(|p| other.has(p).is_ok());
189 self
190 }
191
192 pub fn add(&mut self, privilege: &str) {
193 self.set.insert(privilege.to_string());
194 }
195
196 pub fn has(&self, privilege: &str) -> Result<(), ()> {
197 let privilege = privilege.to_string();
198 if self.set.contains(&privilege) {
199 Ok(())
200 } else {
201 Err(())
202 }
203 }
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
207pub enum Privilege {
208 Full,
209 Single(String),
210}
211
212impl ToString for Privilege {
213 fn to_string(&self) -> String {
214 match self {
215 Privilege::Full => "*".to_string(),
216 Privilege::Single(name) => name.clone(),
217 }
218 }
219}
220
221impl FromStr for Privilege {
222 type Err = SpaceErr;
223
224 fn from_str(s: &str) -> Result<Self, Self::Err> {
225 let span = new_span(s);
226 Ok(result(all_consuming(privilege)(span))?)
227 }
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct EnumeratedAccess {
232 pub permissions: Permissions,
233 pub privileges: Privileges,
234}
235
236impl EnumeratedAccess {
237 pub fn mask(&mut self, scope_grant: &ScopeGrant) {}
238
239 pub fn full() -> Self {
240 Self {
241 permissions: Permissions::full(),
242 privileges: Privileges::Full,
243 }
244 }
245
246 pub fn none() -> Self {
247 Self {
248 permissions: Permissions::none(),
249 privileges: Privileges::none(),
250 }
251 }
252
253 pub fn and(&mut self, access: &Self) {
254 self.permissions.and(&access.permissions);
255 self.privileges = self.privileges.clone().and(&access.privileges);
256 }
257
258 pub fn clear_privs(&mut self) {
259 self.privileges = Privileges::none()
260 }
261
262 pub fn add(&mut self, grant: &AccessGrant) {
263 match &grant.kind {
264 AccessGrantKindDef::Super => {
265 }
267 AccessGrantKindDef::Privilege(prv) => {
268 self.privileges = self.privileges.clone() | prv;
269 }
270 AccessGrantKindDef::PermissionsMask(mask) => match mask.kind {
271 PermissionsMaskKind::Or => self.permissions.or(&mask.permissions),
272 PermissionsMaskKind::And => self.permissions.and(&mask.permissions),
273 },
274 }
275 }
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
279pub struct PermissionsMask {
280 pub kind: PermissionsMaskKind,
281 pub permissions: Permissions,
282}
283
284impl FromStr for PermissionsMask {
285 type Err = SpaceErr;
286
287 fn from_str(s: &str) -> Result<Self, Self::Err> {
288 let s = new_span(s);
289 Ok(result(all_consuming(permissions_mask)(s))?)
290 }
291}
292
293impl ToString for PermissionsMask {
294 fn to_string(&self) -> String {
295 match self.kind {
296 PermissionsMaskKind::Or => format!("+{}", self.permissions.to_string()),
297 PermissionsMaskKind::And => format!("&{}", self.permissions.to_string()),
298 }
299 }
300}
301
302#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
303pub struct Permissions {
304 pub child: ChildPerms,
305 pub particle: ParticlePerms,
306}
307
308impl FromStr for Permissions {
309 type Err = SpaceErr;
310
311 fn from_str(s: &str) -> Result<Self, Self::Err> {
312 result(permissions(new_span(s)))
313 }
314}
315
316impl Permissions {
317 pub fn full() -> Self {
318 Self {
319 child: ChildPerms::full(),
320 particle: ParticlePerms::full(),
321 }
322 }
323
324 pub fn none() -> Self {
325 Self {
326 child: ChildPerms::none(),
327 particle: ParticlePerms::none(),
328 }
329 }
330
331 pub fn or(&mut self, permissions: &Permissions) {
332 self.child.or(&permissions.child);
333 self.particle.or(&permissions.particle);
334 }
335
336 pub fn and(&mut self, permissions: &Permissions) {
337 self.child.and(&permissions.child);
338 self.particle.and(&permissions.particle);
339 }
340}
341
342impl ToString for Permissions {
343 fn to_string(&self) -> String {
344 format!("{}-{}", self.child.to_string(), self.particle.to_string())
345 }
346}
347
348#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
349pub struct ChildPerms {
350 pub create: bool,
351 pub select: bool,
352 pub delete: bool,
353}
354
355impl ChildPerms {
356 pub fn full() -> Self {
357 Self {
358 create: true,
359 select: true,
360 delete: true,
361 }
362 }
363
364 pub fn none() -> Self {
365 Self {
366 create: false,
367 select: false,
368 delete: false,
369 }
370 }
371
372 pub fn or(&mut self, block: &ChildPerms) {
373 self.create |= block.create;
374 self.select |= block.select;
375 self.delete |= block.delete;
376 }
377
378 pub fn and(&mut self, block: &ChildPerms) {
379 self.create &= block.create;
380 self.select &= block.select;
381 self.delete &= block.delete;
382 }
383}
384
385impl ToString for ChildPerms {
386 fn to_string(&self) -> String {
387 let mut rtn = String::new();
388
389 if self.create {
390 rtn.push_str("C");
391 } else {
392 rtn.push_str("c");
393 }
394
395 if self.select {
396 rtn.push_str("S");
397 } else {
398 rtn.push_str("s");
399 }
400
401 if self.delete {
402 rtn.push_str("D");
403 } else {
404 rtn.push_str("d");
405 }
406
407 rtn
408 }
409}
410
411#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
412pub struct ParticlePerms {
413 pub read: bool,
414 pub write: bool,
415 pub execute: bool,
416}
417
418impl ParticlePerms {
419 pub fn full() -> Self {
420 Self {
421 read: true,
422 write: true,
423 execute: true,
424 }
425 }
426
427 pub fn none() -> Self {
428 Self {
429 read: false,
430 write: false,
431 execute: false,
432 }
433 }
434
435 pub fn or(&mut self, block: &ParticlePerms) {
436 self.read |= block.read;
437 self.write |= block.write;
438 self.execute |= block.execute;
439 }
440
441 pub fn and(&mut self, block: &ParticlePerms) {
442 self.read &= block.read;
443 self.write &= block.write;
444 self.execute &= block.execute;
445 }
446}
447
448impl FromStr for ParticlePerms {
449 type Err = SpaceErr;
450
451 fn from_str(s: &str) -> Result<Self, Self::Err> {
452 let s = new_span(s);
453 Ok(result(all_consuming(particle_perms)(s))?)
454 }
455}
456
457impl ToString for ParticlePerms {
458 fn to_string(&self) -> String {
459 let mut rtn = String::new();
460
461 if self.read {
462 rtn.push_str("R");
463 } else {
464 rtn.push_str("r");
465 }
466
467 if self.write {
468 rtn.push_str("W");
469 } else {
470 rtn.push_str("w");
471 }
472
473 if self.execute {
474 rtn.push_str("X");
475 } else {
476 rtn.push_str("x");
477 }
478
479 rtn
480 }
481}
482
483#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
484pub enum PermissionsMaskKind {
485 Or,
486 And,
487}
488
489#[derive(Debug, Clone, Serialize, Deserialize)]
490pub struct AccessGrantDef<Priv, PermMask, PointSelector, Point> {
491 pub kind: AccessGrantKindDef<Priv, PermMask>,
492 pub on_point: PointSelector,
493 pub to_point: PointSelector,
494 pub by_particle: Point,
495}
496
497pub type GrantTo = GrantToDef<Selector>;
498pub enum GrantToDef<PointSelector> {
499 World,
500 PointSelector(PointSelector),
501}
502
503impl GrantTo {
504 pub fn is_match(&self, hierarchy: &PointHierarchy) -> Result<(), ()> {
505 match self {
506 GrantTo::World => Ok(()),
507 GrantTo::PointSelector(selector) => match selector.matches(hierarchy) {
508 true => Ok(()),
509 false => Err(()),
510 },
511 }
512 }
513}
514
515pub type AccessGrant = AccessGrantDef<Privilege, PermissionsMask, Selector, Point>;
516pub type AccessGrantKind = AccessGrantKindDef<Privilege, PermissionsMask>;
517
518#[derive(Debug, Clone, Serialize, Deserialize)]
519pub enum AccessGrantKindDef<Priv, PermMask> {
520 Super,
521 Privilege(Priv),
522 PermissionsMask(PermMask),
523}
524
525impl<Priv, PermMask> ToString for AccessGrantKindDef<Priv, PermMask> {
526 fn to_string(&self) -> String {
527 match self {
528 AccessGrantKindDef::Super => "super".to_string(),
529 AccessGrantKindDef::Privilege(_) => "priv".to_string(),
530 AccessGrantKindDef::PermissionsMask(_) => "perm".to_string(),
531 }
532 }
533}
534
535impl Ord for IndexedAccessGrant {
536 fn cmp(&self, other: &Self) -> Ordering {
537 if self.id < other.id {
538 Ordering::Greater
539 } else if self.id < other.id {
540 Ordering::Less
541 } else {
542 Ordering::Equal
543 }
544 }
545}
546
547#[derive(Debug, Clone)]
548pub struct IndexedAccessGrant {
549 pub id: i32,
550 pub access_grant: AccessGrant,
551}
552
553impl Eq for IndexedAccessGrant {}
554
555impl PartialEq<Self> for IndexedAccessGrant {
556 fn eq(&self, other: &Self) -> bool {
557 self.id == other.id
558 }
559}
560
561impl PartialOrd<Self> for IndexedAccessGrant {
562 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
563 if self.id < other.id {
564 Some(Ordering::Greater)
565 } else if self.id < other.id {
566 Some(Ordering::Less)
567 } else {
568 Some(Ordering::Equal)
569 }
570 }
571}
572
573impl Deref for IndexedAccessGrant {
574 type Target = AccessGrant;
575
576 fn deref(&self) -> &Self::Target {
577 &self.access_grant
578 }
579}
580
581impl Into<AccessGrant> for IndexedAccessGrant {
582 fn into(self) -> AccessGrant {
583 self.access_grant
584 }
585}
586
587pub trait AccessProvider: Send + Sync {
588 fn access(&self, to: &Agent, on: &Point) -> Result<Access, SpaceErr>;
589}
590
591pub struct AllAccessProvider();
592
593impl AccessProvider for AllAccessProvider {
594 fn access(&self, _: &Agent, _: &Point) -> Result<Access, SpaceErr> {
595 Ok(Access::SuperOwner)
596 }
597}