access_tokens.rs

 1use super::*;
 2use sea_orm::sea_query::Query;
 3
 4impl Database {
 5    /// Creates a new access token for the given user.
 6    pub async fn create_access_token(
 7        &self,
 8        user_id: UserId,
 9        impersonated_user_id: Option<UserId>,
10        access_token_hash: &str,
11        max_access_token_count: usize,
12    ) -> Result<AccessTokenId> {
13        self.transaction(|tx| async {
14            let tx = tx;
15
16            let token = access_token::ActiveModel {
17                user_id: ActiveValue::set(user_id),
18                impersonated_user_id: ActiveValue::set(impersonated_user_id),
19                hash: ActiveValue::set(access_token_hash.into()),
20                ..Default::default()
21            }
22            .insert(&*tx)
23            .await?;
24
25            access_token::Entity::delete_many()
26                .filter(
27                    access_token::Column::Id.in_subquery(
28                        Query::select()
29                            .column(access_token::Column::Id)
30                            .from(access_token::Entity)
31                            .and_where(access_token::Column::UserId.eq(user_id))
32                            .order_by(access_token::Column::Id, sea_orm::Order::Desc)
33                            .limit(10000)
34                            .offset(max_access_token_count as u64)
35                            .to_owned(),
36                    ),
37                )
38                .exec(&*tx)
39                .await?;
40            Ok(token.id)
41        })
42        .await
43    }
44
45    /// Retrieves the access token with the given ID.
46    pub async fn get_access_token(
47        &self,
48        access_token_id: AccessTokenId,
49    ) -> Result<access_token::Model> {
50        self.transaction(|tx| async move {
51            Ok(access_token::Entity::find_by_id(access_token_id)
52                .one(&*tx)
53                .await?
54                .ok_or_else(|| anyhow!("no such access token"))?)
55        })
56        .await
57    }
58
59    /// Retrieves the access token with the given ID.
60    pub async fn update_access_token_hash(
61        &self,
62        id: AccessTokenId,
63        new_hash: &str,
64    ) -> Result<access_token::Model> {
65        self.transaction(|tx| async move {
66            Ok(access_token::Entity::update(access_token::ActiveModel {
67                id: ActiveValue::unchanged(id),
68                hash: ActiveValue::set(new_hash.into()),
69                ..Default::default()
70            })
71            .exec(&*tx)
72            .await?)
73        })
74        .await
75    }
76}