actix_jwt_auth_middleware/
errors.rs1use actix_web::body::BoxBody;
2use actix_web::http::StatusCode;
3use actix_web::Error as ActixWebError;
4use actix_web::HttpResponse;
5use actix_web::ResponseError;
6use jwt_compact::CreationError;
7use jwt_compact::ParseError;
8use jwt_compact::ValidationError;
9
10pub type AuthResult<T> = Result<T, AuthError>;
11
12#[derive(Debug)]
20pub enum AuthError {
21 NoToken,
22 NoTokenSigner,
23 RefreshAuthorizerCall(ActixWebError),
24 RefreshAuthorizerDenied(ActixWebError),
25 TokenCreation(CreationError),
26 TokenParse(ParseError),
27 TokenValidation(ValidationError),
28}
29
30impl PartialEq for AuthError {
31 fn eq(&self, other: &Self) -> bool {
32 match (self, other) {
33 (Self::TokenCreation(_), Self::TokenCreation(_))
34 | (Self::TokenValidation(_), Self::TokenValidation(_))
35 | (Self::TokenParse(_), Self::TokenParse(_))
36 | (Self::RefreshAuthorizerCall(_), Self::RefreshAuthorizerCall(_)) => true,
37 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
38 }
39 }
40}
41
42impl From<CreationError> for AuthError {
43 fn from(val: CreationError) -> Self {
44 AuthError::TokenCreation(val)
45 }
46}
47
48impl From<ParseError> for AuthError {
49 fn from(val: ParseError) -> Self {
50 AuthError::TokenParse(val)
51 }
52}
53
54impl From<ValidationError> for AuthError {
55 fn from(val: ValidationError) -> Self {
56 AuthError::TokenValidation(val)
57 }
58}
59
60impl std::fmt::Display for AuthError {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 const NO_TOKEN_MESSAGE: &str = "An error occurred, no cookie containing a jwt was found in the request. Please first authenticate with this application.";
63
64 #[cfg(not(debug_assertions))]
65 match self {
66 AuthError::NoToken => f.write_str(NO_TOKEN_MESSAGE),
67 AuthError::RefreshAuthorizerDenied(err) => f.write_str(&err.to_string()),
68 AuthError::TokenParse(_) | AuthError::TokenValidation(_) => {
69 f.write_str("An error occurred, the provided jwt could not be processed.")
70 }
71 AuthError::RefreshAuthorizerCall(_)
72 | AuthError::NoTokenSigner
73 | AuthError::TokenCreation(_) => {
74 f.write_str("An internal error occurred. Please try again later.")
75 }
76 }
77 #[cfg(debug_assertions)]
78 match self {
79 AuthError::NoToken => f.write_str(NO_TOKEN_MESSAGE),
80 AuthError::NoTokenSigner => f.write_str(
81 "An error occurred because no CookieSigner was configured on the Authority struct.",
82 ),
83 AuthError::TokenCreation(err) => f.write_fmt(format_args!(
84 "An error occurred creating the jwt.\n\t Error: \"{err}\""
85 )),
86 AuthError::TokenValidation(err) => f.write_fmt(format_args!(
87 "An error occurred validating the jwt.\n\t Error: \"{err}\""
88 )),
89 AuthError::TokenParse(err) => f.write_fmt(format_args!(
90 "An error occurred parsing the jwt.\n\t Error: \"{err}\""
91 )),
92 AuthError::RefreshAuthorizerDenied(err) | AuthError::RefreshAuthorizerCall(err) => {
93 f.write_str(&err.to_string())
94 }
95 }
96 }
97}
98
99impl ResponseError for AuthError {
100 fn status_code(&self) -> StatusCode {
101 match self {
102 AuthError::TokenCreation(_) | AuthError::NoTokenSigner => {
103 StatusCode::INTERNAL_SERVER_ERROR
104 }
105 AuthError::TokenParse(_) => StatusCode::BAD_REQUEST,
106 AuthError::NoToken | AuthError::TokenValidation(_) => StatusCode::UNAUTHORIZED,
107 AuthError::RefreshAuthorizerCall(err) | AuthError::RefreshAuthorizerDenied(err) => {
108 err.as_response_error().status_code()
109 }
110 }
111 }
112 fn error_response(&self) -> HttpResponse<BoxBody> {
113 match self {
114 AuthError::RefreshAuthorizerDenied(err) | AuthError::RefreshAuthorizerCall(err) => {
115 err.error_response()
116 }
117 _ => HttpResponse::build(self.status_code()).body(self.to_string()),
118 }
119 }
120}