reinhardt_auth/core/user.rs
1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3
4/// User trait - Core authentication trait
5///
6/// This trait defines the basic interface that all user types must implement
7/// in the Reinhardt authentication system. It provides methods for checking
8/// user status and permissions.
9///
10/// # Examples
11///
12/// ```
13/// use reinhardt_auth::{User, SimpleUser};
14/// use uuid::Uuid;
15///
16/// let user = SimpleUser {
17/// id: Uuid::new_v4(),
18/// username: "alice".to_string(),
19/// email: "alice@example.com".to_string(),
20/// is_active: true,
21/// is_admin: false,
22/// is_staff: false,
23/// is_superuser: false,
24/// };
25///
26/// assert!(user.is_authenticated());
27/// assert!(user.is_active());
28/// assert_eq!(user.username(), "alice");
29/// ```
30pub trait User: Send + Sync {
31 /// Returns the unique identifier for this user
32 fn id(&self) -> String;
33
34 /// Returns the username for this user
35 fn username(&self) -> &str;
36
37 /// Returns the username (alias for `username()`)
38 ///
39 /// This method exists for Django compatibility.
40 fn get_username(&self) -> &str {
41 self.username()
42 }
43
44 /// Returns whether this user is authenticated
45 ///
46 /// For concrete user types, this should always return `true`.
47 /// `AnonymousUser` should return `false`.
48 fn is_authenticated(&self) -> bool;
49
50 /// Returns whether this user account is active
51 ///
52 /// Inactive users cannot log in and should be denied access.
53 fn is_active(&self) -> bool;
54
55 /// Returns whether this user is an administrator
56 ///
57 /// Admin users typically have elevated privileges in the system.
58 fn is_admin(&self) -> bool;
59
60 /// Returns whether this user is a staff member
61 ///
62 /// Staff members typically have access to the admin interface.
63 fn is_staff(&self) -> bool;
64
65 /// Returns whether this user is a superuser
66 ///
67 /// Superusers have all permissions without explicit assignment.
68 fn is_superuser(&self) -> bool;
69}
70
71/// Simple user implementation with basic fields
72///
73/// This is a lightweight user struct suitable for most applications.
74///
75/// # Examples
76///
77/// ```
78/// use reinhardt_auth::{User, SimpleUser};
79/// use uuid::Uuid;
80///
81/// let user = SimpleUser {
82/// id: Uuid::new_v4(),
83/// username: "bob".to_string(),
84/// email: "bob@example.com".to_string(),
85/// is_active: true,
86/// is_admin: true,
87/// is_staff: true,
88/// is_superuser: false,
89/// };
90///
91/// assert!(user.is_authenticated());
92/// assert!(user.is_admin());
93/// assert!(user.is_staff());
94/// ```
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct SimpleUser {
97 pub id: Uuid,
98 pub username: String,
99 pub email: String,
100 pub is_active: bool,
101 pub is_admin: bool,
102 pub is_staff: bool,
103 pub is_superuser: bool,
104}
105
106impl User for SimpleUser {
107 fn id(&self) -> String {
108 self.id.to_string()
109 }
110
111 fn username(&self) -> &str {
112 &self.username
113 }
114
115 fn is_authenticated(&self) -> bool {
116 true
117 }
118
119 fn is_active(&self) -> bool {
120 self.is_active
121 }
122
123 fn is_admin(&self) -> bool {
124 self.is_admin
125 }
126
127 fn is_staff(&self) -> bool {
128 self.is_staff
129 }
130
131 fn is_superuser(&self) -> bool {
132 self.is_superuser
133 }
134}
135
136/// Anonymous user - represents a non-authenticated visitor
137///
138/// This type is used to represent users who are not logged in.
139/// All permission checks return `false`, and `is_authenticated()` returns `false`.
140///
141/// # Examples
142///
143/// ```
144/// use reinhardt_auth::{User, AnonymousUser};
145///
146/// let anon = AnonymousUser;
147///
148/// assert!(!anon.is_authenticated());
149/// assert!(!anon.is_active());
150/// assert!(!anon.is_admin());
151/// assert_eq!(anon.username(), "");
152/// assert_eq!(anon.id(), "");
153/// ```
154pub struct AnonymousUser;
155
156impl User for AnonymousUser {
157 fn id(&self) -> String {
158 String::new()
159 }
160
161 fn username(&self) -> &str {
162 ""
163 }
164
165 fn is_authenticated(&self) -> bool {
166 false
167 }
168
169 fn is_active(&self) -> bool {
170 false
171 }
172
173 fn is_admin(&self) -> bool {
174 false
175 }
176
177 fn is_staff(&self) -> bool {
178 false
179 }
180
181 fn is_superuser(&self) -> bool {
182 false
183 }
184}