1use serde::{Deserialize, Serialize};
6use std::fmt;
7
8#[derive(Debug, Clone, thiserror::Error)]
10pub enum AuthorizationError {
11 #[error("User not found: {0}")]
13 UserNotFound(String),
14
15 #[error("Permission denied: {0}")]
17 PermissionDenied(String),
18
19 #[error("Invalid token: {0}")]
21 InvalidToken(String),
22
23 #[error("Configuration error: {0}")]
25 Configuration(String),
26
27 #[error("Database error: {0}")]
29 Database(String),
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct AuthUser {
35 pub user_id: String,
37 pub username: String,
39 pub roles: Vec<String>,
41 pub permissions: Vec<String>,
43 pub expires_at: Option<i64>,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
49#[serde(rename_all = "snake_case")]
50pub enum Action {
51 Create,
53 Read,
55 Update,
57 Delete,
59 List,
61 Restore,
63}
64
65impl Action {
66 pub fn all() -> Vec<Self> {
68 vec![
69 Self::Create,
70 Self::Read,
71 Self::Update,
72 Self::Delete,
73 Self::List,
74 Self::Restore,
75 ]
76 }
77}
78
79impl fmt::Display for Action {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match self {
82 Self::Create => write!(f, "create"),
83 Self::Read => write!(f, "read"),
84 Self::Update => write!(f, "update"),
85 Self::Delete => write!(f, "delete"),
86 Self::List => write!(f, "list"),
87 Self::Restore => write!(f, "restore"),
88 }
89 }
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
94#[serde(rename_all = "snake_case")]
95pub enum Resource {
96 User,
98 Role,
100 Permission,
102 Settings,
104}
105
106impl Resource {
107 pub fn all() -> Vec<Self> {
109 vec![
110 Self::User,
111 Self::Role,
112 Self::Permission,
113 Self::Settings,
114 ]
115 }
116}
117
118impl fmt::Display for Resource {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 match self {
121 Self::User => write!(f, "user"),
122 Self::Role => write!(f, "role"),
123 Self::Permission => write!(f, "permission"),
124 Self::Settings => write!(f, "settings"),
125 }
126 }
127}
128
129#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
131#[serde(rename_all = "snake_case")]
132pub enum Role {
133 SuperAdmin,
135 Admin,
137 User,
139 Guest,
141}
142
143impl Role {
144 pub fn all() -> Vec<&'static str> {
146 vec![
147 "super_admin",
148 "admin",
149 "user",
150 "guest",
151 ]
152 }
153
154 pub fn as_str(&self) -> &'static str {
156 match self {
157 Self::SuperAdmin => "super_admin",
158 Self::Admin => "admin",
159 Self::User => "user",
160 Self::Guest => "guest",
161 }
162 }
163
164 pub fn from_str(s: &str) -> Option<Self> {
166 match s {
167 "super_admin" => Some(Self::SuperAdmin),
168 "admin" => Some(Self::Admin),
169 "user" => Some(Self::User),
170 "guest" => Some(Self::Guest),
171 _ => None,
172 }
173 }
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct PermissionCheck {
179 pub allowed: bool,
181 pub permission: Permission,
183 pub reason: String,
185}
186
187#[derive(Debug, Clone)]
189pub struct AuthorizationRequest {
190 pub user: AuthUser,
192 pub resource: Resource,
194 pub action: Action,
196 pub resource_id: Option<String>,
198}
199
200#[derive(Debug, Clone)]
202pub struct AuthorizationResponse {
203 pub allowed: bool,
205 pub checks: Vec<PermissionCheck>,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct AuthorizationConfig {
212 pub cache_ttl_seconds: u64,
214 pub default_role: String,
216 pub enable_permission_caching: bool,
218}
219
220impl Default for AuthorizationConfig {
221 fn default() -> Self {
222 Self {
223 cache_ttl_seconds: 300, default_role: "guest".to_string(),
225 enable_permission_caching: true,
226 }
227 }
228}
229
230#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
232#[serde(rename_all = "snake_case")]
233pub enum UserAction {
234 Create,
236 Read,
238 Update,
240 Delete,
242 List,
244 ResetPassword,
246 ChangeRole,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
252#[serde(rename_all = "snake_case")]
253pub enum RoleAction {
254 Create,
256 Read,
258 Update,
260 Delete,
262 List,
264 AssignPermission,
266 RevokePermission,
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
272#[serde(rename_all = "snake_case")]
273pub enum PermissionAction {
274 Create,
276 Read,
278 Update,
280 Delete,
282 List,
284}
285
286#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
288#[serde(rename_all = "snake_case")]
289pub enum SettingsAction {
290 Create,
292 Read,
294 Update,
296 Delete,
298 List,
300}
301
302#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
304pub enum Permission {
305 User(UserAction),
307 Role(RoleAction),
309 Permission(PermissionAction),
311 Settings(SettingsAction),
313}
314
315impl Permission {
316 pub fn all_permissions() -> HashSet<Permission> {
318 let mut perms = HashSet::new();
319
320 for action in UserAction::all() {
322 perms.insert(Permission::User(action));
323 }
324
325 for action in RoleAction::all() {
327 perms.insert(Permission::Role(action));
328 }
329
330 for action in PermissionAction::all() {
332 perms.insert(Permission::Permission(action));
333 }
334
335 for action in SettingsAction::all() {
337 perms.insert(Permission::Settings(action));
338 }
339
340 perms
341 }
342
343 pub fn from_action_resource(action: Action, resource: Resource) -> Self {
345 match resource {
346 Resource::User => match action {
347 Action::Create => Permission::User(UserAction::Create),
348 Action::Read => Permission::User(UserAction::Read),
349 Action::Update => Permission::User(UserAction::Update),
350 Action::Delete => Permission::User(UserAction::Delete),
351 Action::List => Permission::User(UserAction::List),
352 Action::Restore => Permission::User(UserAction::ResetPassword),
353 },
354 Resource::Role => match action {
355 Action::Create => Permission::Role(RoleAction::Create),
356 Action::Read => Permission::Role(RoleAction::Read),
357 Action::Update => Permission::Role(RoleAction::Update),
358 Action::Delete => Permission::Role(RoleAction::Delete),
359 Action::List => Permission::Role(RoleAction::List),
360 Action::Restore => Permission::Role(RoleAction::AssignPermission),
361 },
362 Resource::Permission => match action {
363 Action::Create => Permission::Permission(PermissionAction::Create),
364 Action::Read => Permission::Permission(PermissionAction::Read),
365 Action::Update => Permission::Permission(PermissionAction::Update),
366 Action::Delete => Permission::Permission(PermissionAction::Delete),
367 Action::List => Permission::Permission(PermissionAction::List),
368 Action::Restore => Permission::Permission(PermissionAction::Update),
369 },
370 Resource::Settings => match action {
371 Action::Create => Permission::Settings(SettingsAction::Create),
372 Action::Read => Permission::Settings(SettingsAction::Read),
373 Action::Update => Permission::Settings(SettingsAction::Update),
374 Action::Delete => Permission::Settings(SettingsAction::Delete),
375 Action::List => Permission::Settings(SettingsAction::List),
376 Action::Restore => Permission::Settings(SettingsAction::Update),
377 },
378 }
379 }
380}
381
382impl UserAction {
383 pub fn all() -> Vec<Self> {
385 vec![
386 Self::Create,
387 Self::Read,
388 Self::Update,
389 Self::Delete,
390 Self::List,
391 Self::ResetPassword,
392 Self::ChangeRole,
393 ]
394 }
395}
396
397impl RoleAction {
398 pub fn all() -> Vec<Self> {
400 vec![
401 Self::Create,
402 Self::Read,
403 Self::Update,
404 Self::Delete,
405 Self::List,
406 Self::AssignPermission,
407 Self::RevokePermission,
408 ]
409 }
410}
411
412impl PermissionAction {
413 pub fn all() -> Vec<Self> {
415 vec![
416 Self::Create,
417 Self::Read,
418 Self::Update,
419 Self::Delete,
420 Self::List,
421 ]
422 }
423}
424
425impl SettingsAction {
426 pub fn all() -> Vec<Self> {
428 vec![
429 Self::Create,
430 Self::Read,
431 Self::Update,
432 Self::Delete,
433 Self::List,
434 ]
435 }
436}
437
438use std::collections::HashSet;