Skip to content

Commit 52c04c1

Browse files
committed
Add expires filter to personal sessions list
1 parent 78b010d commit 52c04c1

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

crates/handlers/src/admin/v1/personal_sessions/list.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ pub struct FilterParams {
7575
/// Filter by access token expiry date
7676
#[serde(rename = "filter[expires_after]")]
7777
expires_after: Option<DateTime<Utc>>,
78+
79+
/// Filter by whether the access token has an expiry time
80+
#[serde(rename = "filter[expires]")]
81+
expires: Option<bool>,
7882
}
7983

8084
impl std::fmt::Display for FilterParams {
@@ -113,6 +117,10 @@ impl std::fmt::Display for FilterParams {
113117
)?;
114118
sep = '&';
115119
}
120+
if let Some(expires) = self.expires {
121+
write!(f, "{sep}filter[expires]={}", expires)?;
122+
sep = '&';
123+
}
116124

117125
let _ = sep;
118126
Ok(())
@@ -270,6 +278,12 @@ pub async fn handler(
270278
filter
271279
};
272280

281+
let filter = if let Some(expires) = params.expires {
282+
filter.with_expires(expires)
283+
} else {
284+
filter
285+
};
286+
273287
let response = match include_count {
274288
IncludeCount::True => {
275289
let page = repo.personal_session().list(filter, pagination).await?;
@@ -514,6 +528,11 @@ mod tests {
514528
&["01FSHN9AG0YQYAR04VCYTHJ8SK", "01FSPT2RG08Y11Y5BM4VZ4CN8K"],
515529
),
516530
("filter[status]=revoked", &["01FSM7P1G0VBGAMK9D9QMGQ5MY"]),
531+
(
532+
"filter[expires]=true",
533+
&["01FSHN9AG0YQYAR04VCYTHJ8SK", "01FSPT2RG08Y11Y5BM4VZ4CN8K"],
534+
),
535+
("filter[expires]=false", &["01FSM7P1G0VBGAMK9D9QMGQ5MY"]),
517536
];
518537

519538
for (filter, expected_ids) in filters_and_expected {

crates/storage-pg/src/personal/session.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,5 +567,15 @@ impl Filter for PersonalSessionFilter<'_> {
567567
Expr::col((PersonalAccessTokens::Table, PersonalAccessTokens::ExpiresAt))
568568
.gt(expires_after)
569569
}))
570+
.add_option(self.expires().map(|expires| {
571+
let column =
572+
Expr::col((PersonalAccessTokens::Table, PersonalAccessTokens::ExpiresAt));
573+
574+
if expires {
575+
column.is_not_null()
576+
} else {
577+
column.is_null()
578+
}
579+
}))
570580
}
571581
}

crates/storage/src/personal/session.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ pub struct PersonalSessionFilter<'a> {
156156
last_active_after: Option<DateTime<Utc>>,
157157
expires_before: Option<DateTime<Utc>>,
158158
expires_after: Option<DateTime<Utc>>,
159+
expires: Option<bool>,
159160
}
160161

161162
/// Filter for what state a personal session is in.
@@ -332,4 +333,20 @@ impl<'a> PersonalSessionFilter<'a> {
332333
pub fn expires_after(&self) -> Option<DateTime<Utc>> {
333334
self.expires_after
334335
}
336+
337+
/// Only return sessions whose access tokens have, or don't have,
338+
/// an expiry time set
339+
#[must_use]
340+
pub fn with_expires(mut self, expires: bool) -> Self {
341+
self.expires = Some(expires);
342+
self
343+
}
344+
345+
/// Get the expires filter
346+
///
347+
/// Returns [`None`] if no expires filter was set
348+
#[must_use]
349+
pub fn expires(&self) -> Option<bool> {
350+
self.expires
351+
}
335352
}

0 commit comments

Comments
 (0)