diff options
Diffstat (limited to 'crates/auth/src/server/csrf_token_validation.rs')
-rw-r--r-- | crates/auth/src/server/csrf_token_validation.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/crates/auth/src/server/csrf_token_validation.rs b/crates/auth/src/server/csrf_token_validation.rs new file mode 100644 index 0000000..c9a627c --- /dev/null +++ b/crates/auth/src/server/csrf_token_validation.rs @@ -0,0 +1,49 @@ +use anyhow::{Context, anyhow}; +use axum_extra::headers; +use oauth2::CsrfToken; +use time::OffsetDateTime; +use tower_sessions::{CachingSessionStore, SessionStore, session::Id}; +use tower_sessions_moka_store::MokaStore; +use tower_sessions_sqlx_store::PostgresStore; + +use crate::{ + error::AppError, + server::{COOKIE_NAME, CSRF_TOKEN, routes::authorised::AuthRequest}, + state::AppHandle, +}; + +pub struct Session { + id: String, + expires_at: OffsetDateTime, + user_id: String, +} + +pub async fn csrf_token_validation_workflow( + auth_request: &AuthRequest, + store: &CachingSessionStore<MokaStore, PostgresStore>, + 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::<CsrfToken>(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(()) +} |