From 28b7be0500c155018082ac59f51411b9f110da9d Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Sun, 23 May 2021 16:26:24 +0200 Subject: [PATCH] Hash refesh tokens earlier --- src/infra/auth_service.rs | 21 ++++++++++++++------- src/infra/sql_backend_handler.rs | 16 ++-------------- src/infra/tcp_backend_handler.rs | 8 ++++---- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/infra/auth_service.rs b/src/infra/auth_service.rs index 0714c28..4782a2d 100644 --- a/src/infra/auth_service.rs +++ b/src/infra/auth_service.rs @@ -45,12 +45,19 @@ fn create_jwt(key: &Hmac, user: String, groups: HashSet) -> Sign fn get_refresh_token_from_cookie( request: HttpRequest, -) -> std::result::Result<(String, String), HttpResponse> { +) -> std::result::Result<(u64, String), HttpResponse> { match request.cookie("refresh_token") { None => Err(HttpResponse::Unauthorized().body("Missing refresh token")), Some(t) => match t.value().split_once("+") { None => Err(HttpResponse::Unauthorized().body("Invalid refresh token")), - Some((t, u)) => Ok((t.to_string(), u.to_string())), + Some((token, u)) => { + let refresh_token_hash = { + let mut s = DefaultHasher::new(); + token.hash(&mut s); + s.finish() + }; + Ok((refresh_token_hash, u.to_string())) + } }, } } @@ -64,13 +71,13 @@ where { let backend_handler = &data.backend_handler; let jwt_key = &data.jwt_key; - let (refresh_token, user) = match get_refresh_token_from_cookie(request) { + let (refresh_token_hash, user) = match get_refresh_token_from_cookie(request) { Ok(t) => t, Err(http_response) => return http_response, }; let res_found = data .backend_handler - .check_token(&refresh_token, &user) + .check_token(refresh_token_hash, &user) .await; // Async closures are not supported yet. match res_found { @@ -108,13 +115,13 @@ async fn get_logout( where Backend: TcpBackendHandler + BackendHandler + 'static, { - let (refresh_token, user) = match get_refresh_token_from_cookie(request) { + let (refresh_token_hash, user) = match get_refresh_token_from_cookie(request) { Ok(t) => t, Err(http_response) => return http_response, }; if let Err(response) = data .backend_handler - .delete_refresh_token(&refresh_token) + .delete_refresh_token(refresh_token_hash) .map_err(error_to_http_response) .await { @@ -130,8 +137,8 @@ where let mut jwt_blacklist = data.jwt_blacklist.write().unwrap(); for jwt in new_blacklisted_jwts { jwt_blacklist.insert(jwt); + } } - }, Err(response) => return response, }; HttpResponse::Ok() diff --git a/src/infra/sql_backend_handler.rs b/src/infra/sql_backend_handler.rs index d1c1484..0f1ab58 100644 --- a/src/infra/sql_backend_handler.rs +++ b/src/infra/sql_backend_handler.rs @@ -4,9 +4,7 @@ use async_trait::async_trait; use futures_util::StreamExt; use sea_query::{Expr, Iden, Query, SimpleExpr}; use sqlx::Row; -use std::collections::hash_map::DefaultHasher; use std::collections::HashSet; -use std::hash::{Hash, Hasher}; #[async_trait] impl TcpBackendHandler for SqlBackendHandler { @@ -61,12 +59,7 @@ impl TcpBackendHandler for SqlBackendHandler { Ok((refresh_token, duration)) } - async fn check_token(&self, token: &str, user: &str) -> Result { - let refresh_token_hash = { - let mut s = DefaultHasher::new(); - token.hash(&mut s); - s.finish() - }; + async fn check_token(&self, refresh_token_hash: u64, user: &str) -> Result { let query = Query::select() .expr(SimpleExpr::Value(1.into())) .from(JwtRefreshStorage::Table) @@ -101,12 +94,7 @@ impl TcpBackendHandler for SqlBackendHandler { sqlx::query(&query).execute(&self.sql_pool).await?; Ok(result?) } - async fn delete_refresh_token(&self, token: &str) -> DomainResult<()> { - let refresh_token_hash = { - let mut s = DefaultHasher::new(); - token.hash(&mut s); - s.finish() - }; + async fn delete_refresh_token(&self, refresh_token_hash: u64) -> DomainResult<()> { let query = Query::delete() .from_table(JwtRefreshStorage::Table) .and_where(Expr::col(JwtRefreshStorage::RefreshTokenHash).eq(refresh_token_hash)) diff --git a/src/infra/tcp_backend_handler.rs b/src/infra/tcp_backend_handler.rs index 7351528..5dba894 100644 --- a/src/infra/tcp_backend_handler.rs +++ b/src/infra/tcp_backend_handler.rs @@ -8,9 +8,9 @@ pub type DomainResult = crate::domain::error::Result; pub trait TcpBackendHandler { async fn get_jwt_blacklist(&self) -> anyhow::Result>; async fn create_refresh_token(&self, user: &str) -> DomainResult<(String, chrono::Duration)>; - async fn check_token(&self, token: &str, user: &str) -> DomainResult; + async fn check_token(&self, refresh_token_hash: u64, user: &str) -> DomainResult; async fn blacklist_jwts(&self, user: &str) -> DomainResult>; - async fn delete_refresh_token(&self, token: &str) -> DomainResult<()>; + async fn delete_refresh_token(&self, refresh_token_hash: u64) -> DomainResult<()>; } #[cfg(test)] @@ -32,8 +32,8 @@ mockall::mock! { impl TcpBackendHandler for TestTcpBackendHandler { async fn get_jwt_blacklist(&self) -> anyhow::Result>; async fn create_refresh_token(&self, user: &str) -> DomainResult<(String, chrono::Duration)>; - async fn check_token(&self, token: &str, user: &str) -> DomainResult; + async fn check_token(&self, refresh_token_hash: u64, user: &str) -> DomainResult; async fn blacklist_jwts(&self, user: &str) -> DomainResult>; - async fn delete_refresh_token(&self, token: &str) -> DomainResult<()>; + async fn delete_refresh_token(&self, refresh_token_hash: u64) -> DomainResult<()>; } }