Normalize error responses
This commit is contained in:
parent
078a913f6a
commit
0b64c88fc6
@ -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<Author
|
||||
))).finish()
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct ErrorResponse {
|
||||
error: String,
|
||||
error_description: String,
|
||||
}
|
||||
|
||||
pub fn error_response<D: Debug>(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!"));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user