Skip to main content

backbone_authorization/
types.rs

1//! Authorization types
2//!
3//! Core types for authorization system.
4
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8/// Authorization error
9#[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/// User information with roles and permissions
28#[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>, // Unix timestamp
35}
36
37/// Action types for permissions
38#[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/// Resource types for permissions
76#[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/// Standard roles
108#[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/// Permission check result
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct PermissionCheck {
150    pub allowed: bool,
151    pub permission: Permission,
152    pub reason: String,
153}
154
155/// Authorization request
156#[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/// Authorization response
165#[derive(Debug, Clone)]
166pub struct AuthorizationResponse {
167    pub allowed: bool,
168    pub checks: Vec<PermissionCheck>,
169}
170
171/// Authorization configuration
172#[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, // 5 minutes
183            default_role: "guest".to_string(),
184            enable_permission_caching: true,
185        }
186    }
187}
188
189/// User actions
190#[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/// Role actions
203#[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/// Permission actions
216#[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/// Settings actions
227#[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/// Permission definition
238#[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    /// Get all possible permissions
248    pub fn all_permissions() -> HashSet<Permission> {
249        let mut perms = HashSet::new();
250
251        // User permissions
252        for action in UserAction::all() {
253            perms.insert(Permission::User(action));
254        }
255
256        // Role permissions
257        for action in RoleAction::all() {
258            perms.insert(Permission::Role(action));
259        }
260
261        // Permission permissions
262        for action in PermissionAction::all() {
263            perms.insert(Permission::Permission(action));
264        }
265
266        // Settings permissions
267        for action in SettingsAction::all() {
268            perms.insert(Permission::Settings(action));
269        }
270
271        perms
272    }
273
274    /// Create permission from action and resource
275    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;