1use serde::{Deserialize, Serialize};
4use std::collections::HashSet;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum Permission {
10 Read,
12 Write,
14 Update,
16 Delete,
18 Share,
20 Admin,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
26#[serde(rename_all = "snake_case")]
27pub enum ResourceType {
28 Memory,
30 CrossRef,
32 Tag,
34 Namespace,
36 User,
38 ApiKey,
40 System,
42}
43
44#[derive(Debug, Clone, Default, Serialize, Deserialize)]
46pub struct PermissionSet {
47 permissions: HashSet<(Permission, ResourceType)>,
49 is_admin: bool,
51}
52
53impl PermissionSet {
54 pub fn new() -> Self {
56 Self::default()
57 }
58
59 pub fn from_permissions(perms: Vec<(Permission, ResourceType)>) -> Self {
61 Self {
62 permissions: perms.into_iter().collect(),
63 is_admin: false,
64 }
65 }
66
67 pub fn admin() -> Self {
69 Self {
70 permissions: HashSet::new(),
71 is_admin: true,
72 }
73 }
74
75 pub fn read_only() -> Self {
77 let mut permissions = HashSet::new();
78 permissions.insert((Permission::Read, ResourceType::Memory));
79 permissions.insert((Permission::Read, ResourceType::CrossRef));
80 permissions.insert((Permission::Read, ResourceType::Tag));
81 Self {
82 permissions,
83 is_admin: false,
84 }
85 }
86
87 pub fn standard_user() -> Self {
89 let resources = [
90 ResourceType::Memory,
91 ResourceType::CrossRef,
92 ResourceType::Tag,
93 ];
94 let permissions = [
95 Permission::Read,
96 Permission::Write,
97 Permission::Update,
98 Permission::Delete,
99 ];
100
101 let mut set = HashSet::new();
102 for resource in resources {
103 for permission in permissions {
104 set.insert((permission, resource));
105 }
106 }
107
108 set.insert((Permission::Read, ResourceType::ApiKey));
110 set.insert((Permission::Write, ResourceType::ApiKey));
111 set.insert((Permission::Delete, ResourceType::ApiKey));
112
113 Self {
114 permissions: set,
115 is_admin: false,
116 }
117 }
118
119 pub fn add(&mut self, permission: Permission, resource: ResourceType) {
121 self.permissions.insert((permission, resource));
122 }
123
124 pub fn remove(&mut self, permission: Permission, resource: ResourceType) {
126 self.permissions.remove(&(permission, resource));
127 }
128
129 pub fn has_permission(&self, permission: Permission, resource: ResourceType) -> bool {
131 if self.is_admin {
132 return true;
133 }
134 self.permissions.contains(&(permission, resource))
135 }
136
137 pub fn is_admin(&self) -> bool {
139 self.is_admin
140 }
141
142 pub fn merge(&mut self, other: &PermissionSet) {
144 if other.is_admin {
145 self.is_admin = true;
146 }
147 self.permissions.extend(other.permissions.iter().cloned());
148 }
149
150 pub fn to_vec(&self) -> Vec<(Permission, ResourceType)> {
152 self.permissions.iter().cloned().collect()
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn test_permission_set_basic() {
162 let mut set = PermissionSet::new();
163 set.add(Permission::Read, ResourceType::Memory);
164
165 assert!(set.has_permission(Permission::Read, ResourceType::Memory));
166 assert!(!set.has_permission(Permission::Write, ResourceType::Memory));
167 assert!(!set.has_permission(Permission::Read, ResourceType::User));
168 }
169
170 #[test]
171 fn test_admin_set() {
172 let set = PermissionSet::admin();
173 assert!(set.has_permission(Permission::Admin, ResourceType::System));
174 assert!(set.has_permission(Permission::Delete, ResourceType::User));
175 assert!(set.has_permission(Permission::Read, ResourceType::Memory));
176 }
177
178 #[test]
179 fn test_standard_user() {
180 let set = PermissionSet::standard_user();
181 assert!(set.has_permission(Permission::Read, ResourceType::Memory));
182 assert!(set.has_permission(Permission::Write, ResourceType::Memory));
183 assert!(set.has_permission(Permission::Delete, ResourceType::Memory));
184 assert!(!set.has_permission(Permission::Admin, ResourceType::System));
185 assert!(!set.has_permission(Permission::Delete, ResourceType::User));
186 }
187
188 #[test]
189 fn test_merge() {
190 let mut set1 = PermissionSet::new();
191 set1.add(Permission::Read, ResourceType::Memory);
192
193 let mut set2 = PermissionSet::new();
194 set2.add(Permission::Write, ResourceType::Memory);
195
196 set1.merge(&set2);
197
198 assert!(set1.has_permission(Permission::Read, ResourceType::Memory));
199 assert!(set1.has_permission(Permission::Write, ResourceType::Memory));
200 }
201
202 #[test]
203 fn test_serialization() {
204 let set = PermissionSet::standard_user();
205 let json = serde_json::to_string(&set).unwrap();
206 let restored: PermissionSet = serde_json::from_str(&json).unwrap();
207
208 assert!(restored.has_permission(Permission::Read, ResourceType::Memory));
209 assert!(restored.has_permission(Permission::Write, ResourceType::Memory));
210 }
211}