actix_web_middleware_keycloak_auth/
errors.rs1use actix_web::body::BoxBody;
7use actix_web::http::StatusCode;
8use actix_web::{HttpResponse, ResponseError};
9
10use super::Role;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum AuthError {
15 NoAuthorizationHeader,
17 InvalidAuthorizationHeader,
19 InvalidJwt(String),
21 DecodeError(String),
23 RoleParsingError(String),
25 MissingRoles(Vec<Role>),
27}
28
29impl ResponseError for AuthError {
30 fn status_code(&self) -> StatusCode {
31 match self {
32 Self::MissingRoles(_) => StatusCode::FORBIDDEN,
33 Self::InvalidAuthorizationHeader => StatusCode::BAD_REQUEST,
34 _ => StatusCode::UNAUTHORIZED,
35 }
36 }
37
38 fn error_response(&self) -> HttpResponse {
39 HttpResponse::new(self.status_code()).set_body(BoxBody::new(self.to_string()))
40 }
41}
42
43impl std::fmt::Display for AuthError {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 match self {
46 Self::NoAuthorizationHeader => f.write_str("No bearer token was provided"),
47 Self::InvalidAuthorizationHeader => {
48 f.write_str("Authorization header value is invalid (cannot convert it into string)")
49 }
50 Self::InvalidJwt(e) => write!(f, "Invalid JWT token ({})", e),
51 Self::DecodeError(e) => write!(f, "Error while decoding JWT token ({})", e),
52 Self::RoleParsingError(e) => write!(
53 f,
54 "Error while parsing Keycloak roles from JWT token ({})",
55 e
56 ),
57 Self::MissingRoles(roles) => {
58 write!(
59 f,
60 "JWT token is missing roles: {}",
61 &roles
62 .iter()
63 .map(|r| r.to_string())
64 .collect::<Vec<String>>()
65 .join(", ")
66 )
67 }
68 }
69 }
70}
71
72impl AuthError {
73 pub fn to_response(&self, detailed_responses: bool) -> HttpResponse {
75 if detailed_responses {
76 self.error_response()
77 } else {
78 HttpResponse::build(self.status_code()).body(self.status_code().to_string())
79 }
80 }
81}
82
83#[derive(Debug)]
85pub enum ClaimError {
86 NotFound(String),
88 ParseError(String, serde_json::Error),
90}
91
92impl std::fmt::Display for ClaimError {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 match self {
95 Self::NotFound(key) => write!(f, "Claim '{}' was not found", key),
96 Self::ParseError(key, err) => write!(f, "Parsing claim '{}' failed: {}", key, err),
97 }
98 }
99}