kanidmd_core/https/
errors.rsuse axum::http::header::ACCESS_CONTROL_ALLOW_ORIGIN;
use axum::http::{HeaderValue, StatusCode};
use axum::response::{IntoResponse, Response};
use utoipa::ToSchema;
use kanidm_proto::internal::OperationError;
#[derive(Debug, ToSchema)]
pub enum WebError {
OperationError(OperationError),
InternalServerError(String),
}
impl From<OperationError> for WebError {
fn from(inner: OperationError) -> Self {
WebError::OperationError(inner)
}
}
impl WebError {
pub(crate) fn response_with_access_control_origin_header(self) -> Response {
let mut res = self.into_response();
res.headers_mut().insert(
ACCESS_CONTROL_ALLOW_ORIGIN,
#[allow(clippy::expect_used)]
HeaderValue::from_str("*").expect("Header generation failed, this is weird."),
);
res
}
}
impl IntoResponse for WebError {
fn into_response(self) -> Response {
match self {
WebError::InternalServerError(inner) => {
(StatusCode::INTERNAL_SERVER_ERROR, inner).into_response()
}
WebError::OperationError(inner) => {
let (code, headers) = match &inner {
OperationError::NotAuthenticated | OperationError::SessionExpired => {
(
StatusCode::UNAUTHORIZED,
Some([("WWW-Authenticate", "Bearer"); 1]),
)
}
OperationError::SystemProtectedObject | OperationError::AccessDenied => {
(StatusCode::FORBIDDEN, None)
}
OperationError::NoMatchingEntries => (StatusCode::NOT_FOUND, None),
OperationError::PasswordQuality(_)
| OperationError::EmptyRequest
| OperationError::InvalidAttribute(_)
| OperationError::InvalidAttributeName(_)
| OperationError::SchemaViolation(_)
| OperationError::CU0003WebauthnUserNotVerified
| OperationError::VL0001ValueSshPublicKeyString => {
(StatusCode::BAD_REQUEST, None)
}
_ => (StatusCode::INTERNAL_SERVER_ERROR, None),
};
let body = serde_json::to_string(&inner).unwrap_or(inner.to_string());
match headers {
Some(headers) => (code, headers, body).into_response(),
None => (code, body).into_response(),
}
}
}
}
}