From 0b64c88fc6b8c1bd39588964336101c07be9cdd2 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Thu, 14 Apr 2022 17:13:07 +0200 Subject: [PATCH] Normalize error responses --- src/controllers/openid_controller.rs | 58 ++++++++++++++++------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/controllers/openid_controller.rs b/src/controllers/openid_controller.rs index 9a252b8..cfbbeb1 100644 --- a/src/controllers/openid_controller.rs +++ b/src/controllers/openid_controller.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use actix::Addr; use actix_identity::Identity; use actix_web::{HttpRequest, HttpResponse, Responder, web}; @@ -152,6 +154,21 @@ pub async fn authorize(user: CurrentUser, id: Identity, query: web::Query(query: &D, error: &str, description: &str) -> HttpResponse { + log::warn!("request failed: {} - {} => '{:#?}'", error, description, query); + HttpResponse::BadRequest() + .json(ErrorResponse { + error: error.to_string(), + error_description: description.to_string(), + }) +} + #[derive(Debug, serde::Deserialize)] pub struct TokenAuthorizationCodeQuery { redirect_uri: String, @@ -207,8 +224,11 @@ pub async fn token(req: HttpRequest, (None, None, Some(v)) => { let token = match v.to_str().unwrap_or_default().strip_prefix("Basic ") { None => { - log::warn!("Token request failed: Authorization header does not start with 'Basic '! => got '{:#?}'", v); - return Ok(HttpResponse::Unauthorized().body("Authorization header does not start with 'Basic '")); + return Ok(error_response( + &query, + "invalid_request", + &format!("Authorization header does not start with 'Basic ', got '{:#?}'", v), + )); } Some(v) => v }; @@ -216,8 +236,8 @@ pub async fn token(req: HttpRequest, let decode = String::from_utf8_lossy(&match base64::decode(token) { Ok(d) => d, Err(e) => { - log::warn!("Failed to decode authorization header! {:?}", e); - return Ok(HttpResponse::InternalServerError().body("Failed to decode authorization header!")); + log::error!("Failed to decode authorization header: {:?}", e); + return Ok(error_response(&query, "invalid_request", "Failed to decode authorization header!")); } }).to_string(); @@ -228,8 +248,7 @@ pub async fn token(req: HttpRequest, } _ => { - log::warn!("Token request failed: Unknown client authentication method! {:#?}", query.0); - return Ok(HttpResponse::BadRequest().body("Authentication method unknown!")); + return Ok(error_response(&query, "invalid_request", "Authentication method unknown!")); } }; @@ -238,8 +257,7 @@ pub async fn token(req: HttpRequest, .ok_or_else(|| ErrorUnauthorized("Client not found"))?; if !client.secret.eq(&client_secret) { - log::warn!("Token request failed: client secret is invalid! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Client secret is invalid!")); + return Ok(error_response(&query, "invalid_request", "Client secret is invalid!")); } let token_response = match (query.grant_type.as_str(), @@ -251,30 +269,25 @@ pub async fn token(req: HttpRequest, .await.unwrap() { None => { - log::warn!("Token request failed: Session not found! {:#?}", query.0); - return Ok(HttpResponse::NotFound().body("Session not found!")); + return Ok(error_response(&query, "invalid_request", "Session not found!")); } Some(s) => s, }; if session.client != client.id { - log::warn!("Token request failed: Client mismatch! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Client mismatch!")); + return Ok(error_response(&query, "invalid_request", "Client mismatch!")); } if session.redirect_uri != q.redirect_uri { - log::warn!("Token request failed: Invalid redirect URI! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Invalid redirect URI!")); + return Ok(error_response(&query, "invalid_request", "Invalid redirect URI!")); } if session.authorization_code_expire_at < time() { - log::warn!("Token request failed: Authorization code expired! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Authorization code expired!")); + return Ok(error_response(&query, "invalid_request", "Authorization code expired!")); } if session.authorization_code_used { - log::warn!("Token request failed: Authorization already used! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Authorization already used!")); + return Ok(error_response(&query, "invalid_request", "Authorization already used!")); } // Mark session as used @@ -308,15 +321,13 @@ pub async fn token(req: HttpRequest, .await.unwrap() { None => { - log::warn!("Token refresh failed: Session not found! {:#?}", query.0); - return Ok(HttpResponse::NotFound().body("Session not found!")); + return Ok(error_response(&query, "invalid_request", "Session not found!")); } Some(s) => s, }; if session.client != client.id { - log::warn!("Token request failed: Client mismatch! {:#?}", query.0); - return Ok(HttpResponse::Unauthorized().body("Client mismatch!")); + return Ok(error_response(&query, "invalid_request", "Client mismatch!")); } session.refresh_token = rand_str(OPEN_ID_REFRESH_TOKEN_LEN); @@ -338,8 +349,7 @@ pub async fn token(req: HttpRequest, } _ => { - log::warn!("Token request failed: Grant type unsupported or incomplete! {:#?}", query.0); - return Ok(HttpResponse::BadRequest().body("Grant type unsupported!")); + return Ok(error_response(&query, "invalid_request", "Grant type unsupported!")); } };