Skip to content

Commit bfa6c00

Browse files
0xPoeTurbo87
authored andcommitted
refactor: use chrono::TimeDelta and move find_tokens_expiring_within_days out
1 parent f5b6f6b commit bfa6c00

File tree

2 files changed

+29
-29
lines changed

2 files changed

+29
-29
lines changed

src/models/token.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -97,30 +97,6 @@ impl ApiToken {
9797
.or_else(|_| tokens.select(ApiToken::as_select()).first(conn))
9898
.map_err(Into::into)
9999
}
100-
101-
/// Find all tokens that are not revoked and will expire within the specified number of days.
102-
pub fn find_tokens_expiring_within_days(
103-
conn: &mut PgConnection,
104-
days_until_expiry: i64,
105-
) -> QueryResult<Vec<ApiToken>> {
106-
use diesel::dsl::{now, IntervalDsl};
107-
108-
api_tokens::table
109-
.filter(api_tokens::revoked.eq(false))
110-
.filter(
111-
api_tokens::expired_at
112-
.is_not_null()
113-
.and(api_tokens::expired_at.assume_not_null().gt(now)) // Ignore already expired tokens
114-
.and(
115-
api_tokens::expired_at
116-
.assume_not_null()
117-
.lt(now + days_until_expiry.days()),
118-
),
119-
)
120-
.filter(api_tokens::expiry_notification_at.is_null())
121-
.select(ApiToken::as_select())
122-
.get_results(conn)
123-
}
124100
}
125101

126102
#[derive(Debug)]

src/worker/jobs/expiry_notification.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ use crate::{email::Email, models::User, worker::Environment, Emails};
44
use anyhow::anyhow;
55
use chrono::SecondsFormat;
66
use crates_io_worker::BackgroundJob;
7+
use diesel::dsl::IntervalDsl;
78
use diesel::{
8-
dsl::now, Connection, ExpressionMethods, NullableExpressionMethods, PgConnection, RunQueryDsl,
9+
dsl::now, BoolExpressionMethods, Connection, ExpressionMethods, NullableExpressionMethods,
10+
PgConnection, QueryDsl, QueryResult, RunQueryDsl, SelectableHelper,
911
};
1012
use std::sync::Arc;
1113

1214
/// The threshold in days for the expiry notification.
13-
const EXPIRY_THRESHOLD: i64 = 3;
15+
const EXPIRY_THRESHOLD: chrono::TimeDelta = chrono::TimeDelta::days(3);
1416

1517
/// A job responsible for monitoring the status of a token.
1618
/// It checks if the token is about to reach its expiry date.
@@ -38,7 +40,7 @@ impl BackgroundJob for CheckAboutToExpireToken {
3840
// Check if the token is about to expire and send a notification if it is.
3941
fn check(emails: &Emails, conn: &mut PgConnection) -> anyhow::Result<()> {
4042
info!("Checking if tokens are about to expire");
41-
let expired_tokens = ApiToken::find_tokens_expiring_within_days(conn, EXPIRY_THRESHOLD)?;
43+
let expired_tokens = find_tokens_expiring_within_days(conn, EXPIRY_THRESHOLD)?;
4244
// Batch send notifications in transactions.
4345
const BATCH_SIZE: usize = 100;
4446
for chunk in expired_tokens.chunks(BATCH_SIZE) {
@@ -73,6 +75,28 @@ fn check(emails: &Emails, conn: &mut PgConnection) -> anyhow::Result<()> {
7375
Ok(())
7476
}
7577

78+
/// Find all tokens that are not revoked and will expire within the specified number of days.
79+
pub fn find_tokens_expiring_within_days(
80+
conn: &mut PgConnection,
81+
days_until_expiry: chrono::TimeDelta,
82+
) -> QueryResult<Vec<ApiToken>> {
83+
api_tokens::table
84+
.filter(api_tokens::revoked.eq(false))
85+
.filter(
86+
api_tokens::expired_at
87+
.is_not_null()
88+
.and(api_tokens::expired_at.assume_not_null().gt(now)) // Ignore already expired tokens
89+
.and(
90+
api_tokens::expired_at
91+
.assume_not_null()
92+
.lt(now + days_until_expiry.num_days().day()),
93+
),
94+
)
95+
.filter(api_tokens::expiry_notification_at.is_null())
96+
.select(ApiToken::as_select())
97+
.get_results(conn)
98+
}
99+
76100
#[derive(Debug, Clone)]
77101
struct ExpiryNotificationEmail<'a> {
78102
name: &'a str,
@@ -130,13 +154,13 @@ mod tests {
130154
api_tokens::user_id.eq(user.id),
131155
api_tokens::name.eq("test_token"),
132156
api_tokens::token.eq(token.hashed()),
133-
api_tokens::expired_at.eq(now.nullable() + (EXPIRY_THRESHOLD - 1).day()),
157+
api_tokens::expired_at.eq(now.nullable() + (EXPIRY_THRESHOLD.num_days() - 1).day()),
134158
))
135159
.returning(ApiToken::as_returning())
136160
.get_result(&mut conn)?;
137161

138162
// Insert a few tokens that are not set to expire.
139-
let not_expired_offset = EXPIRY_THRESHOLD + 1;
163+
let not_expired_offset = EXPIRY_THRESHOLD.num_days() + 1;
140164
for i in 0..3 {
141165
let token = PlainToken::generate();
142166
diesel::insert_into(api_tokens::table)

0 commit comments

Comments
 (0)