this repo has no description
1use axum::{ 2 Json, 3 http::StatusCode, 4 response::{IntoResponse, Response}, 5}; 6use serde::Serialize; 7 8#[derive(Debug)] 9pub enum OAuthError { 10 InvalidRequest(String), 11 InvalidClient(String), 12 InvalidGrant(String), 13 UnauthorizedClient(String), 14 UnsupportedGrantType(String), 15 InvalidScope(String), 16 AccessDenied(String), 17 ServerError(String), 18 UseDpopNonce(String), 19 InvalidDpopProof(String), 20 ExpiredToken(String), 21 InvalidToken(String), 22 RateLimited, 23} 24 25#[derive(Serialize)] 26struct OAuthErrorResponse { 27 error: String, 28 error_description: Option<String>, 29} 30 31impl IntoResponse for OAuthError { 32 fn into_response(self) -> Response { 33 let (status, error, description) = match self { 34 OAuthError::InvalidRequest(msg) => { 35 (StatusCode::BAD_REQUEST, "invalid_request", Some(msg)) 36 } 37 OAuthError::InvalidClient(msg) => { 38 (StatusCode::UNAUTHORIZED, "invalid_client", Some(msg)) 39 } 40 OAuthError::InvalidGrant(msg) => (StatusCode::BAD_REQUEST, "invalid_grant", Some(msg)), 41 OAuthError::UnauthorizedClient(msg) => { 42 (StatusCode::UNAUTHORIZED, "unauthorized_client", Some(msg)) 43 } 44 OAuthError::UnsupportedGrantType(msg) => { 45 (StatusCode::BAD_REQUEST, "unsupported_grant_type", Some(msg)) 46 } 47 OAuthError::InvalidScope(msg) => (StatusCode::BAD_REQUEST, "invalid_scope", Some(msg)), 48 OAuthError::AccessDenied(msg) => (StatusCode::FORBIDDEN, "access_denied", Some(msg)), 49 OAuthError::ServerError(msg) => { 50 (StatusCode::INTERNAL_SERVER_ERROR, "server_error", Some(msg)) 51 } 52 OAuthError::UseDpopNonce(nonce) => { 53 return ( 54 StatusCode::BAD_REQUEST, 55 [("DPoP-Nonce", nonce)], 56 Json(OAuthErrorResponse { 57 error: "use_dpop_nonce".to_string(), 58 error_description: Some("A DPoP nonce is required".to_string()), 59 }), 60 ) 61 .into_response(); 62 } 63 OAuthError::InvalidDpopProof(msg) => { 64 (StatusCode::UNAUTHORIZED, "invalid_dpop_proof", Some(msg)) 65 } 66 OAuthError::ExpiredToken(msg) => (StatusCode::UNAUTHORIZED, "invalid_token", Some(msg)), 67 OAuthError::InvalidToken(msg) => (StatusCode::UNAUTHORIZED, "invalid_token", Some(msg)), 68 OAuthError::RateLimited => ( 69 StatusCode::TOO_MANY_REQUESTS, 70 "rate_limited", 71 Some("Too many requests. Please try again later.".to_string()), 72 ), 73 }; 74 ( 75 status, 76 Json(OAuthErrorResponse { 77 error: error.to_string(), 78 error_description: description, 79 }), 80 ) 81 .into_response() 82 } 83} 84 85impl From<sqlx::Error> for OAuthError { 86 fn from(err: sqlx::Error) -> Self { 87 tracing::error!("Database error in OAuth flow: {}", err); 88 OAuthError::ServerError("An internal error occurred".to_string()) 89 } 90} 91 92impl From<anyhow::Error> for OAuthError { 93 fn from(err: anyhow::Error) -> Self { 94 tracing::error!("Internal error in OAuth flow: {}", err); 95 OAuthError::ServerError("An internal error occurred".to_string()) 96 } 97}