use anyhow::{Context, anyhow}; use oauth2::CsrfToken; use tower_sessions::{CachingSessionStore, SessionStore, session::Id}; use tower_sessions_moka_store::MokaStore; use tower_sessions_sqlx_store::PostgresStore; use crate::{ error::AppError, server::{CSRF_TOKEN, routes::authorised::AuthRequest}, }; pub async fn csrf_token_validation_workflow( auth_request: &AuthRequest, store: &CachingSessionStore, oauth_session_id: Id, ) -> Result<(), AppError> { let oauth_session = store.load(&oauth_session_id).await.unwrap().unwrap(); // Extract the CSRF token from the session let csrf_token_serialized = oauth_session .data .get(CSRF_TOKEN) .context("failed to get value from session")?; let csrf_token = serde_json::from_value::(csrf_token_serialized.clone()) .context("CSRF token not found in session")? .to_owned(); // Cleanup the CSRF token session store .delete(&oauth_session_id) .await .context("Failed to destroy old session")?; // Validate CSRF token is the same as the one in the auth request if *csrf_token.secret() != auth_request.state { return Err(anyhow!("CSRF token mismatch").into()); } Ok(()) }