starlane_core/
permissions.rs

1use std::collections::HashSet;
2
3use serde::{Deserialize, Serialize};
4
5use crate::crypt::JwtDecoder;
6use crate::error::Error;
7use crate::resource::{ResourceKey, UserKey};
8use starlane_resources::Labels;
9
10#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
11pub struct AuthToken {
12    pub user: User,
13}
14
15impl AuthToken {
16    pub fn decode(&self, _decoder: JwtDecoder) -> Authentication {
17        unimplemented!();
18    }
19}
20
21#[derive(Clone)]
22pub struct Authentication {
23    pub user: UserKey,
24}
25
26impl Authentication {
27    pub fn mock(user: UserKey) -> Self {
28        Authentication { user: user }
29    }
30}
31
32pub enum TokenError {
33    Error(Error),
34    Invalid,
35}
36
37#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
38pub struct User {
39    pub name: String,
40    pub key: UserKey,
41    pub labels: Option<Labels>,
42    pub kind: UserKind,
43}
44
45#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
46pub enum UserKind {
47    Super,
48    Developer,
49    User,
50    Guest,
51    Custom(String),
52}
53
54#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
55pub enum UserRole {
56    Owner,
57    Developer,
58    User,
59    Guest,
60    Observer,
61}
62
63pub struct RoleBinding {
64    user: UserKey,
65    resource: ResourceKey,
66    role: UserRole,
67}
68
69pub struct Grant {
70    pub user: UserKey,
71    pub resource: ResourceKey,
72    pub priviledge: Priviledge,
73}
74
75pub enum Priviledge {
76    Access(HashSet<Access>),
77    Role(UserRole),
78}
79
80#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
81pub enum UserPattern {
82    None,
83    Any,
84    Exact(String),
85    Kind(UserKind),
86}
87
88impl UserPattern {
89    pub fn is_match(&self, user: &User) -> bool {
90        match &self {
91            UserPattern::None => false,
92            UserPattern::Any => true,
93            UserPattern::Kind(kind) => *kind == user.kind,
94            UserPattern::Exact(name) => {
95                if *name == user.name {
96                    true
97                } else {
98                    false
99                }
100            }
101        }
102    }
103}
104
105#[derive(Clone, Serialize, Deserialize, Eq, PartialEq)]
106pub struct Permissions {
107    pub patterns: Vec<UserPattern>,
108    pub access: HashSet<Access>,
109}
110
111impl Permissions {
112    pub fn is_permitted(&self, user: &User) -> bool {
113        for pattern in &self.patterns {
114            if pattern.is_match(user) {
115                return true;
116            }
117        }
118        return false;
119    }
120}
121
122pub struct Priviledges {
123    pub hyper: HashSet<HyperSpaceAccess>,
124    pub space: HashSet<SpaceAccess>,
125    pub app: HashSet<AppAccess>,
126    pub actor: HashSet<ActorAccess>,
127}
128
129impl Priviledges {
130    pub fn new() -> Self {
131        Priviledges {
132            hyper: HashSet::new(),
133            space: HashSet::new(),
134            app: HashSet::new(),
135            actor: HashSet::new(),
136        }
137    }
138
139    pub fn all() -> Self {
140        let rtn = Self::new();
141        rtn.hyper
142            .union(&HyperSpaceAccess::all().into_iter().collect());
143        rtn.space.union(&SpaceAccess::all().into_iter().collect());
144        rtn.app.union(&AppAccess::all().into_iter().collect());
145        rtn.actor.union(&ActorAccess::all().into_iter().collect());
146
147        rtn
148    }
149
150    pub fn new_union(&self, other: &Priviledges) -> Self {
151        let mut rtn = Priviledges::new();
152        rtn.union(self);
153        rtn.union(other);
154        rtn
155    }
156
157    pub fn union(&mut self, other: &Priviledges) {
158        self.hyper.union(&other.hyper.clone());
159        self.space.union(&other.space.clone());
160        self.app.union(&other.app.clone());
161        self.actor.union(&other.actor.clone());
162    }
163}
164
165#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
166pub enum Access {
167    Hyper(HyperSpaceAccess),
168    Space(SpaceAccess),
169    App(AppAccess),
170    Actor(ActorAccess),
171}
172
173#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
174pub enum AppAccess {
175    CreateActor,
176    DestroyActor,
177    DestroyApp,
178    Watch,
179}
180
181impl AppAccess {
182    pub fn all() -> Vec<Self> {
183        vec![
184            Self::CreateActor,
185            Self::DestroyActor,
186            Self::DestroyApp,
187            Self::Watch,
188        ]
189    }
190    pub fn role(role: UserRole) -> Vec<Self> {
191        match role {
192            UserRole::Owner => Self::all(),
193            UserRole::Developer => {
194                vec![Self::CreateActor, Self::DestroyActor, Self::Watch]
195            }
196            UserRole::User => {
197                vec![Self::CreateActor, Self::Watch]
198            }
199            _ => {
200                vec![Self::Watch]
201            }
202        }
203    }
204}
205
206#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
207pub enum HyperSpaceAccess {
208    CreateSpaces,
209    DestroySpaces,
210    ViewSpaces,
211    ElevateToHyperUser,
212}
213
214impl HyperSpaceAccess {
215    pub fn all() -> Vec<Self> {
216        vec![
217            Self::CreateSpaces,
218            Self::ViewSpaces,
219            Self::DestroySpaces,
220            Self::ElevateToHyperUser,
221        ]
222    }
223
224    pub fn role(role: UserRole) -> Vec<Self> {
225        match role {
226            UserRole::Owner => Self::all(),
227            UserRole::Developer => {
228                vec![
229                    Self::CreateSpaces,
230                    Self::ViewSpaces,
231                    Self::DestroySpaces,
232                    Self::ElevateToHyperUser,
233                ]
234            }
235            UserRole::User => {
236                vec![
237                    Self::CreateSpaces,
238                    Self::ViewSpaces,
239                    Self::ElevateToHyperUser,
240                ]
241            }
242            UserRole::Guest => {
243                vec![Self::ViewSpaces]
244            }
245            _ => {
246                vec![]
247            }
248        }
249    }
250}
251
252#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
253pub enum SpaceAccess {
254    CreateUser,
255    ModifyUser,
256    ViewUser,
257    DestroyUser,
258    CreateSubSpace,
259    ViewSubSpace,
260    DestroySubSpace,
261    ElevateToSuperUser,
262}
263
264impl SpaceAccess {
265    pub fn all() -> Vec<Self> {
266        vec![
267            Self::CreateUser,
268            Self::ModifyUser,
269            Self::ViewUser,
270            Self::DestroyUser,
271            Self::CreateSubSpace,
272            Self::ViewSubSpace,
273            Self::DestroySubSpace,
274            Self::ElevateToSuperUser,
275        ]
276    }
277
278    pub fn role(role: UserRole) -> Vec<Self> {
279        match role {
280            UserRole::Owner => Self::all(),
281            UserRole::Developer => {
282                vec![
283                    Self::CreateUser,
284                    Self::ModifyUser,
285                    Self::ViewUser,
286                    Self::DestroyUser,
287                    Self::CreateSubSpace,
288                    Self::ViewSubSpace,
289                    Self::DestroySubSpace,
290                ]
291            }
292            UserRole::User => {
293                vec![
294                    Self::CreateUser,
295                    Self::ModifyUser,
296                    Self::ViewUser,
297                    Self::CreateSubSpace,
298                    Self::ViewSubSpace,
299                ]
300            }
301            _ => {
302                vec![Self::ViewUser, Self::ViewSubSpace]
303            }
304        }
305    }
306}
307
308#[derive(Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
309pub enum ActorAccess {
310    Create,
311    Modify,
312    Message,
313    Watch,
314    Destroy,
315}
316
317impl ActorAccess {
318    pub fn all() -> Vec<Self> {
319        vec![
320            Self::Create,
321            Self::Watch,
322            Self::Message,
323            Self::Modify,
324            Self::Destroy,
325        ]
326    }
327
328    pub fn role(role: UserRole) -> Vec<Self> {
329        match role {
330            UserRole::Owner => Self::all(),
331            UserRole::Developer => {
332                vec![
333                    Self::Create,
334                    Self::Modify,
335                    Self::Message,
336                    Self::Watch,
337                    Self::Destroy,
338                ]
339            }
340            UserRole::User => {
341                vec![Self::Watch, Self::Message, Self::Modify]
342            }
343            UserRole::Guest => {
344                vec![Self::Watch, Self::Message]
345            }
346            UserRole::Observer => {
347                vec![Self::Watch]
348            }
349        }
350    }
351}
352
353#[derive(Clone)]
354pub struct AuthTokenSource {}
355
356impl AuthTokenSource {
357    pub fn new() -> Self {
358        AuthTokenSource {}
359    }
360
361    pub async fn auth(&self, _creds: &Credentials) -> Result<AuthToken, Error> {
362        unimplemented!()
363        /*        Ok(AuthToken{
364                   user: User{
365                       name: "someuser".to_string(),
366                       key: creds.user.clone(),
367                       labels: None,
368                       kind: match creds.user.id{
369                           UserId::Super => UserKind::Super,
370                           UserId::Annonymous => UserKind::Guest,
371                           UserId::Uuid(_) => UserKind::User
372                       }
373                   }
374               })
375
376        */
377    }
378}
379
380#[derive(Clone)]
381pub struct Credentials {
382    pub user: UserKey,
383}
384
385impl Credentials {
386    pub fn mock(user: UserKey) -> Self {
387        Credentials { user: user }
388    }
389}