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