haste_server/auth_n/oidc/
error.rs1use axum::response::{IntoResponse, Redirect};
5
6#[derive(serde::Serialize, Debug)]
7pub enum OIDCErrorCode {
8 #[serde(rename = "invalid_request")]
13 InvalidRequest,
14 #[serde(rename = "unauthorized_client")]
19 UnauthorizedClient,
20 #[serde(rename = "unsupported_response_type")]
25 UnsupportedResponseType,
26 #[serde(rename = "invalid_scope")]
30 InvalidScope,
31 #[serde(rename = "server_error")]
39 ServerError,
40 #[serde(rename = "temporarily_unavailable")]
48 TemporarilyUnavailable,
49 #[serde(rename = "invalid_client")]
62 InvalidClient,
63 #[serde(rename = "invalid_grant")]
71 InvalidGrant,
72
73 #[serde(rename = "access_denied")]
74 AccessDenied,
75}
76
77impl From<&OIDCErrorCode> for &str {
78 fn from(code: &OIDCErrorCode) -> Self {
79 match code {
80 OIDCErrorCode::InvalidRequest => "invalid_request",
81 OIDCErrorCode::UnauthorizedClient => "unauthorized_client",
82 OIDCErrorCode::UnsupportedResponseType => "unsupported_response_type",
83 OIDCErrorCode::InvalidScope => "invalid_scope",
84 OIDCErrorCode::ServerError => "server_error",
85 OIDCErrorCode::TemporarilyUnavailable => "temporarily_unavailable",
86 OIDCErrorCode::InvalidClient => "invalid_client",
87 OIDCErrorCode::InvalidGrant => "invalid_grant",
88 OIDCErrorCode::AccessDenied => "access_denied",
89 }
90 }
91}
92
93#[allow(dead_code)]
94#[derive(serde::Serialize, Debug)]
95pub struct OIDCError {
96 pub code: OIDCErrorCode,
97 pub description: Option<String>,
98 #[serde(skip_serializing)]
99 pub redirect_uri: Option<String>,
100}
101
102impl OIDCError {
103 pub fn new(
104 code: OIDCErrorCode,
105 description: Option<String>,
106 redirect_uri: Option<String>,
107 ) -> Self {
108 OIDCError {
109 code,
110 description,
111 redirect_uri,
112 }
113 }
114}
115
116impl IntoResponse for OIDCError {
117 fn into_response(self) -> axum::response::Response {
118 let error_code: &str = (&self.code).into();
119
120 if let Some(error_uri) = self.redirect_uri {
121 let mut redirect_uri = error_uri + "?error=" + error_code;
122
123 if let Some(description) = self.description {
124 redirect_uri = redirect_uri + "&error_description=" + &description;
125 }
126
127 Redirect::to(&redirect_uri).into_response()
128 } else {
129 let json_body = serde_json::to_string(&self).unwrap_or_default();
130
131 match self.code {
132 OIDCErrorCode::InvalidRequest
133 | OIDCErrorCode::InvalidGrant
134 | OIDCErrorCode::InvalidClient
135 | OIDCErrorCode::InvalidScope => {
136 (axum::http::StatusCode::BAD_REQUEST, json_body).into_response()
137 }
138 OIDCErrorCode::UnauthorizedClient => {
139 (axum::http::StatusCode::UNAUTHORIZED, json_body).into_response()
140 }
141 OIDCErrorCode::UnsupportedResponseType => {
142 (axum::http::StatusCode::UNPROCESSABLE_ENTITY, json_body).into_response()
143 }
144 OIDCErrorCode::ServerError => {
145 (axum::http::StatusCode::INTERNAL_SERVER_ERROR, json_body).into_response()
146 }
147 OIDCErrorCode::TemporarilyUnavailable => {
148 (axum::http::StatusCode::SERVICE_UNAVAILABLE, json_body).into_response()
149 }
150 OIDCErrorCode::AccessDenied => {
151 (axum::http::StatusCode::FORBIDDEN, json_body).into_response()
152 }
153 }
154 }
155 }
156}