mas_storage/personal/
session.rs1use async_trait::async_trait;
7use chrono::{DateTime, Utc};
8use mas_data_model::{
9 Client, Clock, Device, User,
10 personal::{
11 PersonalAccessToken,
12 session::{PersonalSession, PersonalSessionOwner},
13 },
14};
15use oauth2_types::scope::Scope;
16use rand_core::RngCore;
17use ulid::Ulid;
18
19use crate::{Page, Pagination, repository_impl};
20
21#[async_trait]
24pub trait PersonalSessionRepository: Send + Sync {
25 type Error;
27
28 async fn lookup(&mut self, id: Ulid) -> Result<Option<PersonalSession>, Self::Error>;
40
41 async fn add(
61 &mut self,
62 rng: &mut (dyn RngCore + Send),
63 clock: &dyn Clock,
64 owner: PersonalSessionOwner,
65 actor_user: &User,
66 human_name: String,
67 scope: Scope,
68 ) -> Result<PersonalSession, Self::Error>;
69
70 async fn revoke(
83 &mut self,
84 clock: &dyn Clock,
85 personal_session: PersonalSession,
86 ) -> Result<PersonalSession, Self::Error>;
87
88 async fn list(
100 &mut self,
101 filter: PersonalSessionFilter<'_>,
102 pagination: Pagination,
103 ) -> Result<Page<(PersonalSession, Option<PersonalAccessToken>)>, Self::Error>;
104
105 async fn count(&mut self, filter: PersonalSessionFilter<'_>) -> Result<usize, Self::Error>;
115}
116
117repository_impl!(PersonalSessionRepository:
118 async fn lookup(&mut self, id: Ulid) -> Result<Option<PersonalSession>, Self::Error>;
119
120 async fn add(
121 &mut self,
122 rng: &mut (dyn RngCore + Send),
123 clock: &dyn Clock,
124 owner: PersonalSessionOwner,
125 actor_user: &User,
126 human_name: String,
127 scope: Scope,
128 ) -> Result<PersonalSession, Self::Error>;
129
130 async fn revoke(
131 &mut self,
132 clock: &dyn Clock,
133 personal_session: PersonalSession,
134 ) -> Result<PersonalSession, Self::Error>;
135
136 async fn list(
137 &mut self,
138 filter: PersonalSessionFilter<'_>,
139 pagination: Pagination,
140 ) -> Result<Page<(PersonalSession, Option<PersonalAccessToken>)>, Self::Error>;
141
142 async fn count(&mut self, filter: PersonalSessionFilter<'_>) -> Result<usize, Self::Error>;
143);
144
145#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
148pub struct PersonalSessionFilter<'a> {
149 owner_user: Option<&'a User>,
150 owner_oauth2_client: Option<&'a Client>,
151 actor_user: Option<&'a User>,
152 device: Option<&'a Device>,
153 state: Option<PersonalSessionState>,
154 scope: Option<&'a Scope>,
155 last_active_before: Option<DateTime<Utc>>,
156 last_active_after: Option<DateTime<Utc>>,
157 expires_before: Option<DateTime<Utc>>,
158 expires_after: Option<DateTime<Utc>>,
159 expires: Option<bool>,
160}
161
162#[derive(Clone, Copy, Debug, PartialEq, Eq)]
164pub enum PersonalSessionState {
165 Active,
168 Revoked,
171}
172
173impl<'a> PersonalSessionFilter<'a> {
174 #[must_use]
176 pub fn new() -> Self {
177 Self::default()
178 }
179
180 #[must_use]
182 pub fn for_owner_user(mut self, user: &'a User) -> Self {
183 self.owner_user = Some(user);
184 self
185 }
186
187 #[must_use]
191 pub fn owner_oauth2_client(&self) -> Option<&'a Client> {
192 self.owner_oauth2_client
193 }
194
195 #[must_use]
197 pub fn for_owner_oauth2_client(mut self, client: &'a Client) -> Self {
198 self.owner_oauth2_client = Some(client);
199 self
200 }
201
202 #[must_use]
206 pub fn owner_user(&self) -> Option<&'a User> {
207 self.owner_user
208 }
209
210 #[must_use]
212 pub fn for_actor_user(mut self, user: &'a User) -> Self {
213 self.actor_user = Some(user);
214 self
215 }
216
217 #[must_use]
221 pub fn actor_user(&self) -> Option<&'a User> {
222 self.actor_user
223 }
224
225 #[must_use]
227 pub fn with_last_active_before(mut self, last_active_before: DateTime<Utc>) -> Self {
228 self.last_active_before = Some(last_active_before);
229 self
230 }
231
232 #[must_use]
234 pub fn with_last_active_after(mut self, last_active_after: DateTime<Utc>) -> Self {
235 self.last_active_after = Some(last_active_after);
236 self
237 }
238
239 #[must_use]
243 pub fn last_active_before(&self) -> Option<DateTime<Utc>> {
244 self.last_active_before
245 }
246
247 #[must_use]
251 pub fn last_active_after(&self) -> Option<DateTime<Utc>> {
252 self.last_active_after
253 }
254
255 #[must_use]
257 pub fn active_only(mut self) -> Self {
258 self.state = Some(PersonalSessionState::Active);
259 self
260 }
261
262 #[must_use]
264 pub fn finished_only(mut self) -> Self {
265 self.state = Some(PersonalSessionState::Revoked);
266 self
267 }
268
269 #[must_use]
273 pub fn state(&self) -> Option<PersonalSessionState> {
274 self.state
275 }
276
277 #[must_use]
279 pub fn with_scope(mut self, scope: &'a Scope) -> Self {
280 self.scope = Some(scope);
281 self
282 }
283
284 #[must_use]
288 pub fn scope(&self) -> Option<&'a Scope> {
289 self.scope
290 }
291
292 #[must_use]
294 pub fn for_device(mut self, device: &'a Device) -> Self {
295 self.device = Some(device);
296 self
297 }
298
299 #[must_use]
303 pub fn device(&self) -> Option<&'a Device> {
304 self.device
305 }
306
307 #[must_use]
309 pub fn with_expires_before(mut self, expires_before: DateTime<Utc>) -> Self {
310 self.expires_before = Some(expires_before);
311 self
312 }
313
314 #[must_use]
318 pub fn expires_before(&self) -> Option<DateTime<Utc>> {
319 self.expires_before
320 }
321
322 #[must_use]
324 pub fn with_expires_after(mut self, expires_after: DateTime<Utc>) -> Self {
325 self.expires_after = Some(expires_after);
326 self
327 }
328
329 #[must_use]
333 pub fn expires_after(&self) -> Option<DateTime<Utc>> {
334 self.expires_after
335 }
336
337 #[must_use]
340 pub fn with_expires(mut self, expires: bool) -> Self {
341 self.expires = Some(expires);
342 self
343 }
344
345 #[must_use]
349 pub fn expires(&self) -> Option<bool> {
350 self.expires
351 }
352}