For impersonating access tokens, store impersonatee in the new column

This way, we don't need an index on both columns
This commit is contained in:
Max Brunsfeld 2024-01-17 17:58:59 -08:00
parent 69bff7bb77
commit 9f04fd9019
8 changed files with 38 additions and 45 deletions

View file

@ -6,7 +6,7 @@ impl Database {
pub async fn create_access_token(
&self,
user_id: UserId,
impersonator_id: Option<UserId>,
impersonated_user_id: Option<UserId>,
access_token_hash: &str,
max_access_token_count: usize,
) -> Result<AccessTokenId> {
@ -15,28 +15,20 @@ impl Database {
let token = access_token::ActiveModel {
user_id: ActiveValue::set(user_id),
impersonator_id: ActiveValue::set(impersonator_id),
impersonated_user_id: ActiveValue::set(impersonated_user_id),
hash: ActiveValue::set(access_token_hash.into()),
..Default::default()
}
.insert(&*tx)
.await?;
let existing_token_filter = if let Some(impersonator_id) = impersonator_id {
access_token::Column::ImpersonatorId.eq(impersonator_id)
} else {
access_token::Column::UserId
.eq(user_id)
.and(access_token::Column::ImpersonatorId.is_null())
};
access_token::Entity::delete_many()
.filter(
access_token::Column::Id.in_subquery(
Query::select()
.column(access_token::Column::Id)
.from(access_token::Entity)
.cond_where(existing_token_filter)
.and_where(access_token::Column::UserId.eq(user_id))
.order_by(access_token::Column::Id, sea_orm::Order::Desc)
.limit(10000)
.offset(max_access_token_count as u64)

View file

@ -7,7 +7,7 @@ pub struct Model {
#[sea_orm(primary_key)]
pub id: AccessTokenId,
pub user_id: UserId,
pub impersonator_id: Option<UserId>,
pub impersonated_user_id: Option<UserId>,
pub hash: String,
}

View file

@ -178,7 +178,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_1,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h1".into(),
}
);
@ -187,7 +187,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_2,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h2".into()
}
);
@ -198,7 +198,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_3,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h3".into()
}
);
@ -207,7 +207,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_2,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h2".into()
}
);
@ -219,7 +219,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_4,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h4".into()
}
);
@ -228,7 +228,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_3,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h3".into()
}
);
@ -238,15 +238,15 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
// An access token for user 2 impersonating user 1 does not
// count against user 1's access token limit (of 2).
let token_5 = db
.create_access_token(user_1, Some(user_2), "h5", 2)
.create_access_token(user_2, Some(user_1), "h5", 2)
.await
.unwrap();
assert_eq!(
db.get_access_token(token_5).await.unwrap(),
access_token::Model {
id: token_5,
user_id: user_1,
impersonator_id: Some(user_2),
user_id: user_2,
impersonated_user_id: Some(user_1),
hash: "h5".into()
}
);
@ -255,7 +255,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_3,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h3".into()
}
);
@ -263,19 +263,19 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
// Only a limited number (2) of access tokens are stored for user 2
// impersonating other users.
let token_6 = db
.create_access_token(user_1, Some(user_2), "h6", 2)
.create_access_token(user_2, Some(user_1), "h6", 2)
.await
.unwrap();
let token_7 = db
.create_access_token(user_1, Some(user_2), "h7", 2)
.create_access_token(user_2, Some(user_1), "h7", 2)
.await
.unwrap();
assert_eq!(
db.get_access_token(token_6).await.unwrap(),
access_token::Model {
id: token_6,
user_id: user_1,
impersonator_id: Some(user_2),
user_id: user_2,
impersonated_user_id: Some(user_1),
hash: "h6".into()
}
);
@ -283,8 +283,8 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
db.get_access_token(token_7).await.unwrap(),
access_token::Model {
id: token_7,
user_id: user_1,
impersonator_id: Some(user_2),
user_id: user_2,
impersonated_user_id: Some(user_1),
hash: "h7".into()
}
);
@ -294,7 +294,7 @@ async fn test_create_access_tokens(db: &Arc<Database>) {
access_token::Model {
id: token_3,
user_id: user_1,
impersonator_id: None,
impersonated_user_id: None,
hash: "h3".into()
}
);