Skip to content

Commit 5758792

Browse files
committed
worker: Implement trustpub::DeleteExpiredTokens background job
This job deletes expired tokens from the database.
1 parent 1d78c55 commit 5758792

File tree

5 files changed

+80
-0
lines changed

5 files changed

+80
-0
lines changed

src/bin/crates-admin/enqueue_job.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub enum Command {
4949
name: String,
5050
},
5151
SyncUpdatesFeed,
52+
TrustpubCleanup,
5253
}
5354

5455
pub async fn run(command: Command) -> Result<()> {
@@ -161,6 +162,10 @@ pub async fn run(command: Command) -> Result<()> {
161162
Command::SyncUpdatesFeed => {
162163
jobs::rss::SyncUpdatesFeed.enqueue(&mut conn).await?;
163164
}
165+
Command::TrustpubCleanup => {
166+
let job = jobs::trustpub::DeleteExpiredTokens;
167+
job.enqueue(&mut conn).await?;
168+
}
164169
};
165170

166171
Ok(())

src/worker/jobs/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod readmes;
1212
pub mod rss;
1313
mod send_publish_notifications;
1414
mod sync_admins;
15+
pub mod trustpub;
1516
mod typosquat;
1617
mod update_default_version;
1718

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use crate::worker::Environment;
2+
use crates_io_database::schema::trustpub_tokens;
3+
use crates_io_worker::BackgroundJob;
4+
use diesel::prelude::*;
5+
use diesel_async::RunQueryDsl;
6+
use std::sync::Arc;
7+
8+
/// A background job that deletes expired temporary access
9+
/// tokens from the database.
10+
#[derive(Deserialize, Serialize)]
11+
pub struct DeleteExpiredTokens;
12+
13+
impl BackgroundJob for DeleteExpiredTokens {
14+
const JOB_NAME: &'static str = "trustpub::delete_expired_tokens";
15+
16+
type Context = Arc<Environment>;
17+
18+
async fn run(&self, ctx: Self::Context) -> anyhow::Result<()> {
19+
let mut conn = ctx.deadpool.get().await?;
20+
21+
diesel::delete(trustpub_tokens::table)
22+
.filter(trustpub_tokens::expires_at.lt(diesel::dsl::now))
23+
.execute(&mut conn)
24+
.await?;
25+
26+
Ok(())
27+
}
28+
}
29+
30+
#[cfg(test)]
31+
mod tests {
32+
use super::*;
33+
use crate::tests::util::TestApp;
34+
use chrono::{TimeDelta, Utc};
35+
use crates_io_database::models::trustpub::NewToken;
36+
use insta::assert_compact_debug_snapshot;
37+
38+
#[tokio::test(flavor = "multi_thread")]
39+
async fn test_expiry() -> anyhow::Result<()> {
40+
let (app, _client) = TestApp::full().empty().await;
41+
let mut conn = app.db_conn().await;
42+
43+
let token = NewToken {
44+
expires_at: Utc::now() + TimeDelta::minutes(30),
45+
hashed_token: &[0xC0, 0xFF, 0xEE],
46+
crate_ids: &[1],
47+
};
48+
token.insert(&mut conn).await?;
49+
50+
let token = NewToken {
51+
expires_at: Utc::now() - TimeDelta::minutes(5),
52+
hashed_token: &[0xBA, 0xAD, 0xF0, 0x0D],
53+
crate_ids: &[2],
54+
};
55+
token.insert(&mut conn).await?;
56+
57+
DeleteExpiredTokens.enqueue(&mut conn).await?;
58+
app.run_pending_background_jobs().await;
59+
60+
// Check that the expired token was deleted
61+
let crate_ids: Vec<Vec<Option<i32>>> = trustpub_tokens::table
62+
.select(trustpub_tokens::crate_ids)
63+
.load(&mut conn)
64+
.await?;
65+
66+
assert_compact_debug_snapshot!(crate_ids, @"[[Some(1)]]");
67+
68+
Ok(())
69+
}
70+
}

src/worker/jobs/trustpub/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod delete_tokens;
2+
3+
pub use delete_tokens::DeleteExpiredTokens;

src/worker/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ impl RunnerExt for Runner<Arc<Environment>> {
4343
.register_job_type::<jobs::rss::SyncCrateFeed>()
4444
.register_job_type::<jobs::rss::SyncCratesFeed>()
4545
.register_job_type::<jobs::rss::SyncUpdatesFeed>()
46+
.register_job_type::<jobs::trustpub::DeleteExpiredTokens>()
4647
}
4748
}

0 commit comments

Comments
 (0)