1use crate::error::{CollabError, Result};
4use crate::models::UserRole;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
9pub enum Permission {
10 WorkspaceCreate,
12 WorkspaceRead,
13 WorkspaceUpdate,
14 WorkspaceDelete,
15 WorkspaceArchive,
16 WorkspaceManageMembers,
17
18 MockCreate,
20 MockRead,
21 MockUpdate,
22 MockDelete,
23
24 InviteMembers,
26 RemoveMembers,
27 ChangeRoles,
28
29 ViewHistory,
31 CreateSnapshot,
32 RestoreSnapshot,
33
34 ManageSettings,
36 ManageIntegrations,
37
38 ScenarioModifyChaosRules,
41 ScenarioModifyRealityDefaults,
43 ScenarioPromote,
45 ScenarioApprove,
47 ScenarioModifyDriftBudgets,
49}
50
51pub struct RolePermissions;
53
54impl RolePermissions {
55 pub fn get_permissions(role: UserRole) -> Vec<Permission> {
57 match role {
58 UserRole::Admin => vec![
59 Permission::WorkspaceCreate,
61 Permission::WorkspaceRead,
62 Permission::WorkspaceUpdate,
63 Permission::WorkspaceDelete,
64 Permission::WorkspaceArchive,
65 Permission::WorkspaceManageMembers,
66 Permission::MockCreate,
67 Permission::MockRead,
68 Permission::MockUpdate,
69 Permission::MockDelete,
70 Permission::InviteMembers,
71 Permission::RemoveMembers,
72 Permission::ChangeRoles,
73 Permission::ViewHistory,
74 Permission::CreateSnapshot,
75 Permission::RestoreSnapshot,
76 Permission::ManageSettings,
77 Permission::ManageIntegrations,
78 Permission::ScenarioModifyChaosRules,
80 Permission::ScenarioModifyRealityDefaults,
81 Permission::ScenarioPromote,
82 Permission::ScenarioApprove,
83 Permission::ScenarioModifyDriftBudgets,
84 ],
85 UserRole::Editor => vec![
86 Permission::WorkspaceRead,
88 Permission::MockCreate,
89 Permission::MockRead,
90 Permission::MockUpdate,
91 Permission::MockDelete,
92 Permission::ViewHistory,
93 Permission::CreateSnapshot,
94 Permission::ScenarioPromote,
96 ],
97 UserRole::Viewer => vec![
98 Permission::WorkspaceRead,
100 Permission::MockRead,
101 Permission::ViewHistory,
102 ],
103 }
104 }
105
106 pub fn has_permission(role: UserRole, permission: Permission) -> bool {
108 Self::get_permissions(role).contains(&permission)
109 }
110}
111
112pub struct PermissionChecker;
114
115impl PermissionChecker {
116 pub fn check(user_role: UserRole, required_permission: Permission) -> Result<()> {
118 if RolePermissions::has_permission(user_role, required_permission) {
119 Ok(())
120 } else {
121 Err(CollabError::AuthorizationFailed(format!(
122 "Role {:?} does not have permission {:?}",
123 user_role, required_permission
124 )))
125 }
126 }
127
128 pub fn check_all(user_role: UserRole, required_permissions: &[Permission]) -> Result<()> {
130 for permission in required_permissions {
131 Self::check(user_role, *permission)?;
132 }
133 Ok(())
134 }
135
136 pub fn check_any(user_role: UserRole, required_permissions: &[Permission]) -> Result<()> {
138 for permission in required_permissions {
139 if RolePermissions::has_permission(user_role, *permission) {
140 return Ok(());
141 }
142 }
143 Err(CollabError::AuthorizationFailed(format!(
144 "Role {:?} does not have any of the required permissions",
145 user_role
146 )))
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn test_admin_permissions() {
156 let permissions = RolePermissions::get_permissions(UserRole::Admin);
157 assert!(permissions.contains(&Permission::WorkspaceDelete));
158 assert!(permissions.contains(&Permission::MockCreate));
159 assert!(permissions.contains(&Permission::ChangeRoles));
160 }
161
162 #[test]
163 fn test_editor_permissions() {
164 let permissions = RolePermissions::get_permissions(UserRole::Editor);
165 assert!(permissions.contains(&Permission::MockCreate));
166 assert!(permissions.contains(&Permission::MockUpdate));
167 assert!(!permissions.contains(&Permission::WorkspaceDelete));
168 assert!(!permissions.contains(&Permission::ChangeRoles));
169 }
170
171 #[test]
172 fn test_viewer_permissions() {
173 let permissions = RolePermissions::get_permissions(UserRole::Viewer);
174 assert!(permissions.contains(&Permission::WorkspaceRead));
175 assert!(permissions.contains(&Permission::MockRead));
176 assert!(!permissions.contains(&Permission::MockCreate));
177 assert!(!permissions.contains(&Permission::MockUpdate));
178 }
179
180 #[test]
181 fn test_permission_check() {
182 assert!(PermissionChecker::check(UserRole::Admin, Permission::WorkspaceDelete).is_ok());
183 assert!(PermissionChecker::check(UserRole::Editor, Permission::MockCreate).is_ok());
184 assert!(PermissionChecker::check(UserRole::Viewer, Permission::MockCreate).is_err());
185 }
186
187 #[test]
188 fn test_check_all() {
189 let permissions = vec![Permission::MockRead, Permission::MockCreate];
190 assert!(PermissionChecker::check_all(UserRole::Editor, &permissions).is_ok());
191 assert!(PermissionChecker::check_all(UserRole::Viewer, &permissions).is_err());
192 }
193
194 #[test]
195 fn test_check_any() {
196 let permissions = vec![Permission::MockCreate, Permission::WorkspaceDelete];
197 assert!(PermissionChecker::check_any(UserRole::Editor, &permissions).is_ok());
198
199 let admin_only = vec![Permission::WorkspaceDelete, Permission::ChangeRoles];
200 assert!(PermissionChecker::check_any(UserRole::Viewer, &admin_only).is_err());
201 }
202}