From 46045d44bc5bfacfa2105ac97b66f272672b2397 Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Thu, 16 Oct 2025 12:07:58 +0100 Subject: [PATCH] storage: introduce find_active_for_session for PATs --- ...bc38395ab6c6fdf979616fa16fc490897cee3.json | 46 +++++++++++++++++++ ...9c715560d011d4c01112703a9c046170c84f1.json | 2 +- .../storage-pg/src/personal/access_token.rs | 37 +++++++++++++++ crates/storage/src/personal/access_token.rs | 21 +++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 crates/storage-pg/.sqlx/query-d02248136aa6b27636814dee4e0bc38395ab6c6fdf979616fa16fc490897cee3.json diff --git a/crates/storage-pg/.sqlx/query-d02248136aa6b27636814dee4e0bc38395ab6c6fdf979616fa16fc490897cee3.json b/crates/storage-pg/.sqlx/query-d02248136aa6b27636814dee4e0bc38395ab6c6fdf979616fa16fc490897cee3.json new file mode 100644 index 000000000..99df8e139 --- /dev/null +++ b/crates/storage-pg/.sqlx/query-d02248136aa6b27636814dee4e0bc38395ab6c6fdf979616fa16fc490897cee3.json @@ -0,0 +1,46 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT personal_access_token_id\n , personal_session_id\n , created_at\n , expires_at\n , revoked_at\n\n FROM personal_access_tokens\n\n WHERE personal_session_id = $1\n AND revoked_at IS NULL\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "personal_access_token_id", + "type_info": "Uuid" + }, + { + "ordinal": 1, + "name": "personal_session_id", + "type_info": "Uuid" + }, + { + "ordinal": 2, + "name": "created_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 3, + "name": "expires_at", + "type_info": "Timestamptz" + }, + { + "ordinal": 4, + "name": "revoked_at", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Uuid" + ] + }, + "nullable": [ + false, + false, + false, + true, + true + ] + }, + "hash": "d02248136aa6b27636814dee4e0bc38395ab6c6fdf979616fa16fc490897cee3" +} diff --git a/crates/storage-pg/.sqlx/query-fcd8b4b9e003d1540357c6bf1ff9c715560d011d4c01112703a9c046170c84f1.json b/crates/storage-pg/.sqlx/query-fcd8b4b9e003d1540357c6bf1ff9c715560d011d4c01112703a9c046170c84f1.json index f5503fa0e..ef1ac0372 100644 --- a/crates/storage-pg/.sqlx/query-fcd8b4b9e003d1540357c6bf1ff9c715560d011d4c01112703a9c046170c84f1.json +++ b/crates/storage-pg/.sqlx/query-fcd8b4b9e003d1540357c6bf1ff9c715560d011d4c01112703a9c046170c84f1.json @@ -23,7 +23,7 @@ "Left": [] }, "nullable": [ - false, + true, true, null ] diff --git a/crates/storage-pg/src/personal/access_token.rs b/crates/storage-pg/src/personal/access_token.rs index 8c984385a..1af9024aa 100644 --- a/crates/storage-pg/src/personal/access_token.rs +++ b/crates/storage-pg/src/personal/access_token.rs @@ -128,6 +128,43 @@ impl PersonalAccessTokenRepository for PgPersonalAccessTokenRepository<'_> { Ok(Some(res.into())) } + #[tracing::instrument( + name = "db.personal_access_token.find_active_for_session", + skip_all, + fields( + db.query.text, + ), + err, + )] + async fn find_active_for_session( + &mut self, + session_id: Ulid, + ) -> Result, Self::Error> { + let res: Option = sqlx::query_as!( + PersonalAccessTokenLookup, + r#" + SELECT personal_access_token_id + , personal_session_id + , created_at + , expires_at + , revoked_at + + FROM personal_access_tokens + + WHERE personal_session_id = $1 + AND revoked_at IS NULL + "#, + Uuid::from(session_id), + ) + .traced() + .fetch_optional(&mut *self.conn) + .await?; + + let Some(res) = res else { return Ok(None) }; + + Ok(Some(res.into())) + } + #[tracing::instrument( name = "db.personal_access_token.add", skip_all, diff --git a/crates/storage/src/personal/access_token.rs b/crates/storage/src/personal/access_token.rs index 8fdb52ec1..d5607cf2f 100644 --- a/crates/storage/src/personal/access_token.rs +++ b/crates/storage/src/personal/access_token.rs @@ -50,6 +50,22 @@ pub trait PersonalAccessTokenRepository: Send + Sync { access_token: &str, ) -> Result, Self::Error>; + /// Find the active access token belonging to a given session. + /// + /// Returns the active access token if it exists, `None` otherwise + /// + /// # Parameters + /// + /// * `session_id`: The ID of the session to lookup + /// + /// # Errors + /// + /// Returns [`Self::Error`] if the underlying repository fails + async fn find_active_for_session( + &mut self, + session_id: Ulid, + ) -> Result, Self::Error>; + /// Add a new access token to the database /// /// Returns the newly created access token @@ -102,6 +118,11 @@ repository_impl!(PersonalAccessTokenRepository: access_token: &str, ) -> Result, Self::Error>; + async fn find_active_for_session( + &mut self, + session_id: Ulid, + ) -> Result, Self::Error>; + async fn add( &mut self, rng: &mut (dyn RngCore + Send),