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
extern crate rocket;
extern crate base64;
use rocket::{
Request,
Outcome,
outcome::IntoOutcome,
http::Status,
request::FromRequest
};
pub struct BasicAuthRaw {
pub username: String,
pub password: String,
}
impl<'a, 'r> FromRequest<'a, 'r> for BasicAuthRaw {
type Error = ();
fn from_request(request: &Request) -> Outcome<Self, (Status, <Self as FromRequest<'a, 'r>>::Error), ()> {
let auth_header = request.headers().get_one("Authorization");
if let Some(auth_header) = auth_header {
let split = auth_header.split_whitespace().collect::<Vec<_>>();
if split.len() != 2 {
return Outcome::Failure((Status::Unauthorized, ()));
}
let (basic, payload) = (split[0], split[1]);
if basic != "Basic" {
return Outcome::Failure((Status::Unauthorized, ()));
}
let decoded = base64::decode(payload)
.ok()
.into_outcome((Status::BadRequest, ()))?;
let decoded_str = String::from_utf8(decoded)
.ok()
.into_outcome((Status::BadRequest, ()))?;
let split = decoded_str.split(":").collect::<Vec<_>>();
if split.len() != 2 {
return Outcome::Failure((Status::BadRequest, ()));
}
let (username, password) = (split[0].to_string(), split[1].to_string());
Outcome::Success(BasicAuthRaw {
username,
password
})
} else {
Outcome::Failure((Status::Unauthorized, ()))
}
}
}