kych

OAuth 2.0 API for Swiyu to enable Taler integration of Swiyu for KYC (experimental)
Log | Files | Refs

commit 250ea4db7a7789c35ce0056eebdc591ee436589c
parent af2ae1aeb862616d123486e127192e2e076ba1d1
Author: Henrique Chan Carvalho Machado <henriqueccmachado@tecnico.ulisboa.pt>
Date:   Wed,  5 Nov 2025 00:06:49 +0100

oauth2_gateway: db: refactor sessions status update functions

Diffstat:
Moauth2_gateway/src/db/sessions.rs | 104++++++++++++++++++++++++++++++++++++++-----------------------------------------
1 file changed, 50 insertions(+), 54 deletions(-)

diff --git a/oauth2_gateway/src/db/sessions.rs b/oauth2_gateway/src/db/sessions.rs @@ -37,6 +37,7 @@ pub struct VerificationSession { pub authorized_at: Option<DateTime<Utc>>, pub verified_at: Option<DateTime<Utc>>, pub completed_at: Option<DateTime<Utc>>, + pub failed_at: Option<DateTime<Utc>>, pub expires_at: DateTime<Utc>, } @@ -58,7 +59,7 @@ pub async fn create_session( VALUES ($1, $2, $3, $4, 'pending') RETURNING id, client_id, nonce, scope, verification_url, request_id, status, - created_at, authorized_at, verified_at, completed_at, expires_at + created_at, authorized_at, verified_at, completed_at, failed_at, expires_at "# ) .bind(client_id) @@ -82,7 +83,7 @@ pub async fn get_session_by_nonce( r#" SELECT id, client_id, nonce, scope, verification_url, request_id, status, - created_at, authorized_at, verified_at, completed_at, expires_at + created_at, authorized_at, verified_at, completed_at, failed_at, expires_at FROM oauth2gw.verification_sessions WHERE nonce = $1 "# @@ -105,7 +106,7 @@ pub async fn get_session_by_request_id( r#" SELECT id, client_id, nonce, scope, verification_url, request_id, status, - created_at, authorized_at, verified_at, completed_at, expires_at + created_at, authorized_at, verified_at, completed_at, failed_at, expires_at FROM oauth2gw.verification_sessions WHERE request_id = $1 "# @@ -117,47 +118,53 @@ pub async fn get_session_by_request_id( Ok(session) } -/// Update session with Swiyu verification data after calling /authorize -pub async fn update_session_authorized( +/// Update session status and set timestamp +pub async fn update_session_status_with_timestamp( pool: &PgPool, session_id: Uuid, - verification_url: &str, - request_id: &str, + status: SessionStatus, ) -> Result<()> { - sqlx::query( - r#" - UPDATE oauth2gw.verification_sessions - SET - verification_url = $1, - request_id = $2, - status = 'authorized', - authorized_at = CURRENT_TIMESTAMP - WHERE id = $3 - "# - ) - .bind(verification_url) - .bind(request_id) - .bind(session_id) - .execute(pool) - .await?; + let timestamp_field = match status { + SessionStatus::Authorized => "authorized_at", + SessionStatus::Verified => "verified_at", + SessionStatus::Completed => "completed_at", + SessionStatus::Failed => "failed_at", + SessionStatus::Pending | SessionStatus::Expired => { + return Err(anyhow::anyhow!( + "Status {:?} has no timestamp field. Use set_session_status() instead.", + status + )); + } + }; + + let query = format!( + "UPDATE oauth2gw.verification_sessions SET status = $1, {} = CURRENT_TIMESTAMP WHERE id = $2", + timestamp_field + ); + + sqlx::query(&query) + .bind(status) + .bind(session_id) + .execute(pool) + .await?; Ok(()) } -/// Mark session as verified (called by webhook handler) -pub async fn mark_session_verified( +/// Set session status without updating timestamp +pub async fn set_session_status( pool: &PgPool, session_id: Uuid, + status: SessionStatus, ) -> Result<()> { sqlx::query( r#" UPDATE oauth2gw.verification_sessions - SET - status = 'verified', - verified_at = CURRENT_TIMESTAMP - WHERE id = $1 + SET status = $1 + WHERE id = $2 "# ) + .bind(status) .bind(session_id) .execute(pool) .await?; @@ -165,39 +172,28 @@ pub async fn mark_session_verified( Ok(()) } -/// Mark session as completed (called after /info returns VC) -pub async fn mark_session_completed( +/// Update session with Swiyu verification data after calling /authorize +/// +/// Sets verification_url, request_id, status=authorized, and authorized_at timestamp. +pub async fn set_session_authorized( pool: &PgPool, session_id: Uuid, + verification_url: &str, + request_id: &str, ) -> Result<()> { sqlx::query( r#" UPDATE oauth2gw.verification_sessions SET - status = 'completed', - completed_at = CURRENT_TIMESTAMP - WHERE id = $1 - "# - ) - .bind(session_id) - .execute(pool) - .await?; - - Ok(()) -} - -/// Mark session as failed with error -pub async fn mark_session_failed( - pool: &PgPool, - session_id: Uuid, -) -> Result<()> { - sqlx::query( - r#" - UPDATE oauth2gw.verification_sessions - SET status = 'failed' - WHERE id = $1 + verification_url = $1, + request_id = $2, + status = 'authorized', + authorized_at = CURRENT_TIMESTAMP + WHERE id = $3 "# ) + .bind(verification_url) + .bind(request_id) .bind(session_id) .execute(pool) .await?; @@ -211,7 +207,7 @@ pub async fn get_expired_sessions(pool: &PgPool) -> Result<Vec<VerificationSessi r#" SELECT id, client_id, nonce, scope, verification_url, request_id, status, - created_at, authorized_at, verified_at, completed_at, expires_at + created_at, authorized_at, verified_at, completed_at, failed_at, expires_at FROM oauth2gw.verification_sessions WHERE expires_at < CURRENT_TIMESTAMP AND status NOT IN ('completed', 'expired', 'failed')