isb_server/auth/
actors.rs1use super::{OrgId, Principal, PrincipalKind, Role, User};
7use crate::audit::{Actor, ActorKind};
8
9pub const WORKSPACE_ACTOR: &str = "workspace";
11
12impl Principal {
13 pub fn scopes(&self) -> &[String] {
15 match &self.kind {
16 PrincipalKind::ApiToken { scopes, .. } => scopes,
17 _ => &[],
18 }
19 }
20
21 pub fn restricted(&self) -> bool {
23 let s = self.scopes();
24 !s.is_empty() && !s.iter().any(|x| x == "admin")
25 }
26
27 pub fn downscoped_to(&self, org: &OrgId) -> Principal {
31 let privileged =
32 self.platform_admin || matches!(self.kind, PrincipalKind::Superadmin { .. });
33 if !privileged {
34 return self.clone();
35 }
36 let role = self
37 .role_in(org)
38 .map_or(Role::Admin, |r| r.max(Role::Admin));
39 let mut p = self.clone();
40 p.platform_admin = false;
41 p.user.platform_admin = false;
42 p.orgs = vec![(org.clone(), role)];
43 p.downscoped = Some(org.clone());
44 p
45 }
46
47 pub fn workspace(org: &OrgId, name: &str, role: Role) -> Principal {
50 Principal {
51 user: User {
52 id: 0,
53 email: WORKSPACE_ACTOR.into(),
54 name: format!("workspace {name} in {org}"),
55 platform_admin: false,
56 created_at: 0,
57 disabled: false,
58 has_password: false,
59 },
60 kind: PrincipalKind::Workspace {
61 org: org.clone(),
62 name: name.to_string(),
63 },
64 orgs: vec![(org.clone(), role)],
65 platform_admin: false,
66 downscoped: None,
67 }
68 }
69
70 pub fn is_workspace(&self) -> bool {
72 matches!(self.kind, PrincipalKind::Workspace { .. })
73 }
74
75 pub fn agent(label: &str, orgs: Vec<(OrgId, Role)>) -> Principal {
79 Principal {
80 user: User {
81 id: 0,
82 email: label.to_string(),
83 name: label.to_string(),
84 platform_admin: false,
85 created_at: 0,
86 disabled: false,
87 has_password: false,
88 },
89 kind: PrincipalKind::Agent {
90 label: label.to_string(),
91 },
92 orgs,
93 platform_admin: false,
94 downscoped: None,
95 }
96 }
97
98 pub fn is_agent(&self) -> bool {
100 matches!(self.kind, PrincipalKind::Agent { .. })
101 }
102}
103
104impl Actor {
105 pub(crate) fn as_workspace(&mut self, name: &str) {
107 self.name = WORKSPACE_ACTOR.into();
108 self.kind = Some(ActorKind::Agent);
109 self.user_id = None;
110 self.email = None;
111 self.token_name = Some(format!("workspace:{name}"));
112 }
113
114 pub(crate) fn as_agent(&mut self, label: &str) {
116 self.name = label.to_string();
117 self.kind = Some(ActorKind::Agent);
118 self.user_id = None;
119 self.email = None;
120 }
121}