kanidmd_core/https/
errors.rs
1use axum::http::header::ACCESS_CONTROL_ALLOW_ORIGIN;
5use axum::http::{HeaderValue, StatusCode};
6use axum::response::{IntoResponse, Response};
7use utoipa::ToSchema;
8
9use kanidm_proto::internal::OperationError;
10
11#[derive(Debug, ToSchema)]
13pub enum WebError {
14 OperationError(OperationError),
16 InternalServerError(String),
17}
18
19impl From<OperationError> for WebError {
20 fn from(inner: OperationError) -> Self {
21 WebError::OperationError(inner)
22 }
23}
24
25impl WebError {
26 pub(crate) fn response_with_access_control_origin_header(self) -> Response {
27 let mut res = self.into_response();
28 res.headers_mut().insert(
29 ACCESS_CONTROL_ALLOW_ORIGIN,
30 #[allow(clippy::expect_used)]
31 HeaderValue::from_str("*").expect("Header generation failed, this is weird."),
32 );
33 res
34 }
35}
36
37impl IntoResponse for WebError {
38 fn into_response(self) -> Response {
39 match self {
40 WebError::InternalServerError(inner) => {
41 (StatusCode::INTERNAL_SERVER_ERROR, inner).into_response()
42 }
43 WebError::OperationError(inner) => {
44 let (code, headers) = match &inner {
45 OperationError::NotAuthenticated | OperationError::SessionExpired => {
46 (
48 StatusCode::UNAUTHORIZED,
49 Some([("WWW-Authenticate", "Bearer"); 1]),
50 )
51 }
52 OperationError::SystemProtectedObject | OperationError::AccessDenied => {
53 (StatusCode::FORBIDDEN, None)
54 }
55 OperationError::NoMatchingEntries => (StatusCode::NOT_FOUND, None),
56 OperationError::PasswordQuality(_)
57 | OperationError::EmptyRequest
58 | OperationError::InvalidAttribute(_)
59 | OperationError::InvalidAttributeName(_)
60 | OperationError::SchemaViolation(_)
61 | OperationError::CU0003WebauthnUserNotVerified
62 | OperationError::VL0001ValueSshPublicKeyString => {
63 (StatusCode::BAD_REQUEST, None)
64 }
65 _ => (StatusCode::INTERNAL_SERVER_ERROR, None),
66 };
67 let body = serde_json::to_string(&inner).unwrap_or(inner.to_string());
68
69 match headers {
70 Some(headers) => (code, headers, body).into_response(),
71 None => (code, body).into_response(),
72 }
73 }
74 }
75 }
76}