1use std::net::IpAddr;
8
9use chrono::{DateTime, Utc};
10use rand::Rng;
11use serde::Serialize;
12use ulid::Ulid;
13use url::Url;
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
16pub struct MatrixUser {
17 pub mxid: String,
18 pub display_name: Option<String>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
22pub struct User {
23 pub id: Ulid,
24 pub username: String,
25 pub sub: String,
26 pub created_at: DateTime<Utc>,
27 pub locked_at: Option<DateTime<Utc>>,
28 pub deactivated_at: Option<DateTime<Utc>>,
29 pub can_request_admin: bool,
30 pub is_guest: bool,
31}
32
33impl User {
34 #[must_use]
36 pub fn is_valid(&self) -> bool {
37 self.locked_at.is_none() && self.deactivated_at.is_none()
38 }
39
40 #[must_use]
50 pub fn is_valid_actor(&self) -> bool {
51 self.deactivated_at.is_none()
52 }
53}
54
55impl User {
56 #[doc(hidden)]
57 #[must_use]
58 pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
59 vec![User {
60 id: Ulid::from_datetime_with_source(now.into(), rng),
61 username: "john".to_owned(),
62 sub: "123-456".to_owned(),
63 created_at: now,
64 locked_at: None,
65 deactivated_at: None,
66 can_request_admin: false,
67 is_guest: false,
68 }]
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
73pub struct Password {
74 pub id: Ulid,
75 pub hashed_password: String,
76 pub version: u16,
77 pub upgraded_from_id: Option<Ulid>,
78 pub created_at: DateTime<Utc>,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
82pub struct Authentication {
83 pub id: Ulid,
84 pub created_at: DateTime<Utc>,
85 pub authentication_method: AuthenticationMethod,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
89pub enum AuthenticationMethod {
90 Password { user_password_id: Ulid },
91 UpstreamOAuth2 { upstream_oauth2_session_id: Ulid },
92 Unknown,
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
101pub struct UserRecoverySession {
102 pub id: Ulid,
103 pub email: String,
104 pub user_agent: String,
105 pub ip_address: Option<IpAddr>,
106 pub locale: String,
107 pub created_at: DateTime<Utc>,
108 pub consumed_at: Option<DateTime<Utc>>,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
117pub struct UserRecoveryTicket {
118 pub id: Ulid,
119 pub user_recovery_session_id: Ulid,
120 pub user_email_id: Ulid,
121 pub ticket: String,
122 pub created_at: DateTime<Utc>,
123 pub expires_at: DateTime<Utc>,
124}
125
126impl UserRecoveryTicket {
127 #[must_use]
128 pub fn active(&self, now: DateTime<Utc>) -> bool {
129 now < self.expires_at
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
135pub struct UserEmailAuthentication {
136 pub id: Ulid,
137 pub user_session_id: Option<Ulid>,
138 pub user_registration_id: Option<Ulid>,
139 pub email: String,
140 pub created_at: DateTime<Utc>,
141 pub completed_at: Option<DateTime<Utc>>,
142}
143
144#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
146pub struct UserEmailAuthenticationCode {
147 pub id: Ulid,
148 pub user_email_authentication_id: Ulid,
149 pub code: String,
150 pub created_at: DateTime<Utc>,
151 pub expires_at: DateTime<Utc>,
152}
153
154#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
155pub struct BrowserSession {
156 pub id: Ulid,
157 pub user: User,
158 pub created_at: DateTime<Utc>,
159 pub finished_at: Option<DateTime<Utc>>,
160 pub user_agent: Option<String>,
161 pub last_active_at: Option<DateTime<Utc>>,
162 pub last_active_ip: Option<IpAddr>,
163}
164
165impl BrowserSession {
166 #[must_use]
167 pub fn active(&self) -> bool {
168 self.finished_at.is_none() && self.user.is_valid()
169 }
170}
171
172impl BrowserSession {
173 #[must_use]
174 pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
175 User::samples(now, rng)
176 .into_iter()
177 .map(|user| BrowserSession {
178 id: Ulid::from_datetime_with_source(now.into(), rng),
179 user,
180 created_at: now,
181 finished_at: None,
182 user_agent: Some(
183 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Safari/537.36".to_owned()
184 ),
185 last_active_at: Some(now),
186 last_active_ip: None,
187 })
188 .collect()
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
193pub struct UserEmail {
194 pub id: Ulid,
195 pub user_id: Ulid,
196 pub email: String,
197 pub created_at: DateTime<Utc>,
198}
199
200impl UserEmail {
201 #[must_use]
202 pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
203 vec![
204 Self {
205 id: Ulid::from_datetime_with_source(now.into(), rng),
206 user_id: Ulid::from_datetime_with_source(now.into(), rng),
207 email: "alice@example.com".to_owned(),
208 created_at: now,
209 },
210 Self {
211 id: Ulid::from_datetime_with_source(now.into(), rng),
212 user_id: Ulid::from_datetime_with_source(now.into(), rng),
213 email: "bob@example.com".to_owned(),
214 created_at: now,
215 },
216 ]
217 }
218}
219
220#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
221pub struct UserRegistrationPassword {
222 pub hashed_password: String,
223 pub version: u16,
224}
225
226#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
227pub struct UserRegistrationToken {
228 pub id: Ulid,
229 pub token: String,
230 pub usage_limit: Option<u32>,
231 pub times_used: u32,
232 pub created_at: DateTime<Utc>,
233 pub last_used_at: Option<DateTime<Utc>>,
234 pub expires_at: Option<DateTime<Utc>>,
235 pub revoked_at: Option<DateTime<Utc>>,
236}
237
238impl UserRegistrationToken {
239 #[must_use]
241 pub fn is_valid(&self, now: DateTime<Utc>) -> bool {
242 if self.revoked_at.is_some() {
244 return false;
245 }
246
247 if let Some(expires_at) = self.expires_at
249 && now >= expires_at
250 {
251 return false;
252 }
253
254 if let Some(usage_limit) = self.usage_limit
256 && self.times_used >= usage_limit
257 {
258 return false;
259 }
260
261 true
262 }
263
264 #[must_use]
267 pub fn can_be_used(&self, now: DateTime<Utc>) -> bool {
268 self.is_valid(now)
269 }
270}
271
272#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
273pub struct UserRegistration {
274 pub id: Ulid,
275 pub username: String,
276 pub display_name: Option<String>,
277 pub terms_url: Option<Url>,
278 pub email_authentication_id: Option<Ulid>,
279 pub user_registration_token_id: Option<Ulid>,
280 pub password: Option<UserRegistrationPassword>,
281 pub upstream_oauth_authorization_session_id: Option<Ulid>,
282 pub post_auth_action: Option<serde_json::Value>,
283 pub ip_address: Option<IpAddr>,
284 pub user_agent: Option<String>,
285 pub created_at: DateTime<Utc>,
286 pub completed_at: Option<DateTime<Utc>>,
287}