Skip to main content

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}