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