axum_authentik_auth/error.rs
1use apiresponse::{ApiResponse, Response};
2use axum::response::{IntoResponse, Response as AxumResponse};
3
4/// Error type for authentik authentication failures.
5///
6/// Derives [`Response`] from the `apiresponse` crate, which provides
7/// structured error codes, module-prefixed messages, and HTTP status codes.
8/// Error responses are always JSON via [`ApiResponse`].
9///
10/// All variants implement [`IntoResponse`], so they can be returned directly
11/// from handler functions as `Result<T, AuthentikError>`.
12///
13/// # Error codes
14///
15/// | Variant | Code | HTTP Status |
16/// |------------------|------|-------------|
17/// | `Unauthenticated`| 1000 | 401 |
18/// | `Forbidden` | 1001 | 403 |
19#[derive(Debug, thiserror::Error, Response)]
20#[response(module = "authentik")]
21pub enum AuthentikError {
22 /// The user is not authenticated (missing or invalid auth headers).
23 #[error("missing authentication headers")]
24 #[response(code = 1000, status = 401)]
25 Unauthenticated,
26
27 /// The user is authenticated but does not have the required permissions.
28 #[error("user does not have required group: {required_group}")]
29 #[response(code = 1001, status = 403)]
30 Forbidden {
31 /// The group that the user was required to belong to.
32 required_group: String,
33 },
34}
35
36impl IntoResponse for AuthentikError {
37 fn into_response(self) -> AxumResponse {
38 // ApiResponse produces JSON: { "code": 1000, "message": "[authentik] ...", "data": null }
39 // HTTP status code is set automatically from self.http_status_code().
40 let result: Result<(), Self> = Err(self);
41 ApiResponse::from(result).into_response()
42 }
43}