kanidmd_core/https/views/
errors.rs
1use axum::http::StatusCode;
2use axum::response::{IntoResponse, Redirect, Response};
3use axum_htmx::{HxEvent, HxResponseTrigger, HxReswap, HxRetarget, SwapOption};
4use kanidmd_lib::idm::server::DomainInfoRead;
5use utoipa::ToSchema;
6use uuid::Uuid;
7
8use kanidm_proto::internal::OperationError;
9
10use crate::https::middleware::KOpId;
11use crate::https::views::{ErrorToastPartial, UnrecoverableErrorView};
12#[derive(Debug, ToSchema)]
23pub(crate) enum HtmxError {
24 OperationError(Uuid, OperationError, DomainInfoRead),
26}
27
28impl HtmxError {
29 pub(crate) fn new(kopid: &KOpId, operr: OperationError, domain_info: DomainInfoRead) -> Self {
30 HtmxError::OperationError(kopid.eventid, operr, domain_info)
31 }
32}
33
34impl IntoResponse for HtmxError {
35 fn into_response(self) -> Response {
36 match self {
37 HtmxError::OperationError(kopid, inner, domain_info) => {
38 let body = serde_json::to_string(&inner).unwrap_or(inner.to_string());
39 match &inner {
40 OperationError::NotAuthenticated
41 | OperationError::SessionExpired
42 | OperationError::InvalidSessionState => Redirect::to("/ui").into_response(),
43 OperationError::SystemProtectedObject | OperationError::AccessDenied => {
44 let trigger = HxResponseTrigger::after_swap([HxEvent::new(
45 "permissionDenied".to_string(),
46 )]);
47 (
48 trigger,
49 HxRetarget("main".to_string()),
50 HxReswap(SwapOption::BeforeEnd),
51 (
52 StatusCode::FORBIDDEN,
53 ErrorToastPartial {
54 err_code: inner,
55 operation_id: kopid,
56 },
57 )
58 .into_response(),
59 )
60 .into_response()
61 }
62 OperationError::NoMatchingEntries => {
63 (StatusCode::NOT_FOUND, body).into_response()
64 }
65 OperationError::PasswordQuality(_)
66 | OperationError::EmptyRequest
67 | OperationError::SchemaViolation(_)
68 | OperationError::CU0003WebauthnUserNotVerified => {
69 (StatusCode::BAD_REQUEST, body).into_response()
70 }
71 _ => (
72 StatusCode::INTERNAL_SERVER_ERROR,
73 HxRetarget("body".to_string()),
74 HxReswap(SwapOption::OuterHtml),
75 UnrecoverableErrorView {
76 err_code: inner,
77 operation_id: kopid,
78 domain_info,
79 },
80 )
81 .into_response(),
82 }
83 }
84 }
85 }
86}