1use serde::{Deserialize, Serialize};
6use std::fmt;
7
8#[derive(Debug, Clone, thiserror::Error)]
10pub enum AuthorizationError {
11 #[error("User not found: {0}")]
12 UserNotFound(String),
13
14 #[error("Permission denied: {0}")]
15 PermissionDenied(String),
16
17 #[error("Invalid token: {0}")]
18 InvalidToken(String),
19
20 #[error("Configuration error: {0}")]
21 Configuration(String),
22
23 #[error("Database error: {0}")]
24 Database(String),
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct AuthUser {
30 pub user_id: String,
31 pub username: String,
32 pub roles: Vec<String>,
33 pub permissions: Vec<String>,
34 pub expires_at: Option<i64>, }
36
37#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
39#[serde(rename_all = "snake_case")]
40pub enum Action {
41 Create,
42 Read,
43 Update,
44 Delete,
45 List,
46 Restore,
47}
48
49impl Action {
50 pub fn all() -> Vec<Self> {
51 vec![
52 Self::Create,
53 Self::Read,
54 Self::Update,
55 Self::Delete,
56 Self::List,
57 Self::Restore,
58 ]
59 }
60}
61
62impl fmt::Display for Action {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 match self {
65 Self::Create => write!(f, "create"),
66 Self::Read => write!(f, "read"),
67 Self::Update => write!(f, "update"),
68 Self::Delete => write!(f, "delete"),
69 Self::List => write!(f, "list"),
70 Self::Restore => write!(f, "restore"),
71 }
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
77#[serde(rename_all = "snake_case")]
78pub enum Resource {
79 User,
80 Role,
81 Permission,
82 Settings,
83}
84
85impl Resource {
86 pub fn all() -> Vec<Self> {
87 vec![
88 Self::User,
89 Self::Role,
90 Self::Permission,
91 Self::Settings,
92 ]
93 }
94}
95
96impl fmt::Display for Resource {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Self::User => write!(f, "user"),
100 Self::Role => write!(f, "role"),
101 Self::Permission => write!(f, "permission"),
102 Self::Settings => write!(f, "settings"),
103 }
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
109#[serde(rename_all = "snake_case")]
110pub enum Role {
111 SuperAdmin,
112 Admin,
113 User,
114 Guest,
115}
116
117impl Role {
118 pub fn all() -> Vec<&'static str> {
119 vec![
120 "super_admin",
121 "admin",
122 "user",
123 "guest",
124 ]
125 }
126
127 pub fn as_str(&self) -> &'static str {
128 match self {
129 Self::SuperAdmin => "super_admin",
130 Self::Admin => "admin",
131 Self::User => "user",
132 Self::Guest => "guest",
133 }
134 }
135
136 pub fn from_str(s: &str) -> Option<Self> {
137 match s {
138 "super_admin" => Some(Self::SuperAdmin),
139 "admin" => Some(Self::Admin),
140 "user" => Some(Self::User),
141 "guest" => Some(Self::Guest),
142 _ => None,
143 }
144 }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct PermissionCheck {
150 pub allowed: bool,
151 pub permission: Permission,
152 pub reason: String,
153}
154
155#[derive(Debug, Clone)]
157pub struct AuthorizationRequest {
158 pub user: AuthUser,
159 pub resource: Resource,
160 pub action: Action,
161 pub resource_id: Option<String>,
162}
163
164#[derive(Debug, Clone)]
166pub struct AuthorizationResponse {
167 pub allowed: bool,
168 pub checks: Vec<PermissionCheck>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct AuthorizationConfig {
174 pub cache_ttl_seconds: u64,
175 pub default_role: String,
176 pub enable_permission_caching: bool,
177}
178
179impl Default for AuthorizationConfig {
180 fn default() -> Self {
181 Self {
182 cache_ttl_seconds: 300, default_role: "guest".to_string(),
184 enable_permission_caching: true,
185 }
186 }
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
191#[serde(rename_all = "snake_case")]
192pub enum UserAction {
193 Create,
194 Read,
195 Update,
196 Delete,
197 List,
198 ResetPassword,
199 ChangeRole,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
204#[serde(rename_all = "snake_case")]
205pub enum RoleAction {
206 Create,
207 Read,
208 Update,
209 Delete,
210 List,
211 AssignPermission,
212 RevokePermission,
213}
214
215#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
217#[serde(rename_all = "snake_case")]
218pub enum PermissionAction {
219 Create,
220 Read,
221 Update,
222 Delete,
223 List,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
228#[serde(rename_all = "snake_case")]
229pub enum SettingsAction {
230 Create,
231 Read,
232 Update,
233 Delete,
234 List,
235}
236
237#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
239pub enum Permission {
240 User(UserAction),
241 Role(RoleAction),
242 Permission(PermissionAction),
243 Settings(SettingsAction),
244}
245
246impl Permission {
247 pub fn all_permissions() -> HashSet<Permission> {
249 let mut perms = HashSet::new();
250
251 for action in UserAction::all() {
253 perms.insert(Permission::User(action));
254 }
255
256 for action in RoleAction::all() {
258 perms.insert(Permission::Role(action));
259 }
260
261 for action in PermissionAction::all() {
263 perms.insert(Permission::Permission(action));
264 }
265
266 for action in SettingsAction::all() {
268 perms.insert(Permission::Settings(action));
269 }
270
271 perms
272 }
273
274 pub fn from_action_resource(action: Action, resource: Resource) -> Self {
276 match resource {
277 Resource::User => match action {
278 Action::Create => Permission::User(UserAction::Create),
279 Action::Read => Permission::User(UserAction::Read),
280 Action::Update => Permission::User(UserAction::Update),
281 Action::Delete => Permission::User(UserAction::Delete),
282 Action::List => Permission::User(UserAction::List),
283 Action::Restore => Permission::User(UserAction::ResetPassword),
284 },
285 Resource::Role => match action {
286 Action::Create => Permission::Role(RoleAction::Create),
287 Action::Read => Permission::Role(RoleAction::Read),
288 Action::Update => Permission::Role(RoleAction::Update),
289 Action::Delete => Permission::Role(RoleAction::Delete),
290 Action::List => Permission::Role(RoleAction::List),
291 Action::Restore => Permission::Role(RoleAction::AssignPermission),
292 },
293 Resource::Permission => match action {
294 Action::Create => Permission::Permission(PermissionAction::Create),
295 Action::Read => Permission::Permission(PermissionAction::Read),
296 Action::Update => Permission::Permission(PermissionAction::Update),
297 Action::Delete => Permission::Permission(PermissionAction::Delete),
298 Action::List => Permission::Permission(PermissionAction::List),
299 Action::Restore => Permission::Permission(PermissionAction::Update),
300 },
301 Resource::Settings => match action {
302 Action::Create => Permission::Settings(SettingsAction::Create),
303 Action::Read => Permission::Settings(SettingsAction::Read),
304 Action::Update => Permission::Settings(SettingsAction::Update),
305 Action::Delete => Permission::Settings(SettingsAction::Delete),
306 Action::List => Permission::Settings(SettingsAction::List),
307 Action::Restore => Permission::Settings(SettingsAction::Update),
308 },
309 }
310 }
311}
312
313impl UserAction {
314 pub fn all() -> Vec<Self> {
315 vec![
316 Self::Create,
317 Self::Read,
318 Self::Update,
319 Self::Delete,
320 Self::List,
321 Self::ResetPassword,
322 Self::ChangeRole,
323 ]
324 }
325}
326
327impl RoleAction {
328 pub fn all() -> Vec<Self> {
329 vec![
330 Self::Create,
331 Self::Read,
332 Self::Update,
333 Self::Delete,
334 Self::List,
335 Self::AssignPermission,
336 Self::RevokePermission,
337 ]
338 }
339}
340
341impl PermissionAction {
342 pub fn all() -> Vec<Self> {
343 vec![
344 Self::Create,
345 Self::Read,
346 Self::Update,
347 Self::Delete,
348 Self::List,
349 ]
350 }
351}
352
353impl SettingsAction {
354 pub fn all() -> Vec<Self> {
355 vec![
356 Self::Create,
357 Self::Read,
358 Self::Update,
359 Self::Delete,
360 Self::List,
361 ]
362 }
363}
364
365use std::collections::HashSet;