1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use std::collections::HashMap;
use actix_web::dev::HttpResponseBuilder;
use actix_web::http::{header, StatusCode};
use actix_web::{error, HttpResponse};
use once_cell::sync::Lazy;
use crate::authentication::error::error_type::AuthenticationError;
static AUTH_ERROR_STATUS_CODE_MAPPING: Lazy<HashMap<AuthenticationError, u16>> = Lazy::new(|| {
let mut error_codes: HashMap<AuthenticationError, u16> = HashMap::new();
add_env_error_code(AuthenticationError::InvalidAuthentication, &mut error_codes);
add_env_error_code(AuthenticationError::InvalidToken, &mut error_codes);
add_env_error_code(
AuthenticationError::InvalidAuthorizationHeader,
&mut error_codes,
);
add_env_error_code(AuthenticationError::UsernameNotFound, &mut error_codes);
add_env_error_code(
AuthenticationError::AuthorizationHeaderNotSet,
&mut error_codes,
);
error_codes
});
static AUTH_ERROR_MESSAGE_MAPPING: Lazy<HashMap<AuthenticationError, String>> = Lazy::new(|| {
let mut error_messages: HashMap<AuthenticationError, String> = HashMap::new();
add_env_error_message(
AuthenticationError::InvalidAuthentication,
"invalid authentication".to_string(),
&mut error_messages,
);
add_env_error_message(
AuthenticationError::InvalidToken,
"access denied".to_string(),
&mut error_messages,
);
add_env_error_message(
AuthenticationError::InvalidAuthorizationHeader,
"invalid authorization header".to_string(),
&mut error_messages,
);
add_env_error_message(
AuthenticationError::UsernameNotFound,
"access denied".to_string(),
&mut error_messages,
);
add_env_error_message(
AuthenticationError::AuthorizationHeaderNotSet,
"authorization header not set".to_string(),
&mut error_messages,
);
error_messages
});
static AUTH_ERROR_CONTENT_TYPE: Lazy<String> =
Lazy::new(|| match std::env::var("AUTH_ERROR_CONTENT_TYPE") {
Ok(content_type) => content_type,
_ => "text/html; charset=utf-8".to_string(),
});
fn add_env_error_code(
error: AuthenticationError,
error_codes: &mut HashMap<AuthenticationError, u16>,
) {
match std::env::var(format!("{}_code", error)) {
Ok(code) => error_codes.insert(
error,
code.parse::<u16>().expect("Invalid status code mapping"),
),
_ => error_codes.insert(error, 401),
};
}
fn add_env_error_message(
error: AuthenticationError,
default_message: String,
error_messages: &mut HashMap<AuthenticationError, String>,
) {
match std::env::var(format!("{}_message", error)) {
Ok(message) => error_messages.insert(error, message),
_ => error_messages.insert(error, default_message),
};
}
pub fn overwrite_auth_error_status_code(error: AuthenticationError, status_code: u16) {
assert!((100..=1000).contains(&status_code), "Invalid status code");
std::env::set_var(format!("{}_code", error), status_code.to_string());
}
pub fn overwrite_auth_error_message(error: AuthenticationError, message: String) {
std::env::set_var(format!("{}_message", error), message);
}
pub fn set_auth_error_content_type(content_type: String) {
std::env::set_var("AUTH_ERROR_CONTENT_TYPE", content_type);
}
impl error::ResponseError for AuthenticationError {
fn status_code(&self) -> StatusCode {
match *self {
AuthenticationError::InvalidAuthentication => {
dynamic_status_code(&AuthenticationError::InvalidAuthentication)
}
AuthenticationError::AuthorizationHeaderNotSet => {
dynamic_status_code(&AuthenticationError::AuthorizationHeaderNotSet)
}
AuthenticationError::InvalidAuthorizationHeader => {
dynamic_status_code(&AuthenticationError::InvalidAuthorizationHeader)
}
AuthenticationError::UsernameNotFound => {
dynamic_status_code(&AuthenticationError::UsernameNotFound)
}
AuthenticationError::InvalidToken => {
dynamic_status_code(&AuthenticationError::InvalidToken)
}
}
}
fn error_response(&self) -> HttpResponse {
HttpResponseBuilder::new(self.status_code())
.set_header(header::CONTENT_TYPE, AUTH_ERROR_CONTENT_TYPE.to_string())
.body(dynamic_error_message(self))
}
}
fn dynamic_status_code(error: &AuthenticationError) -> StatusCode {
StatusCode::from_u16(
*AUTH_ERROR_STATUS_CODE_MAPPING
.get(error)
.expect("Status code mapping missing"),
)
.expect("Invalid status code mapping found")
}
fn dynamic_error_message(error: &AuthenticationError) -> String {
AUTH_ERROR_MESSAGE_MAPPING
.get(error)
.expect("Error message mapping missing")
.clone()
}