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
|
use std::io;
use std::borrow::Cow;
use tokio::prelude::*;
use http::{Request, Response, StatusCode, Method};
use http::header::{SET_COOKIE, COOKIE};
use url::form_urlencoded;
use ::ApplicationState;
use ::totp;
use super::*;
pub(in super) fn GET<'a>(header_infos: &HeaderExtract, state: &ApplicationState, path_rest: &'a str)
-> Response<String> {
if is_logged_in(&header_infos.cookies, &state.cookie_store) {
make_response(StatusCode::OK, views::login_is_logged_in())
} else {
make_response(StatusCode::OK, views::login_login_form(path_rest))
}
}
fn test_secrets(secrets: &Vec<&str>, token: &String) -> bool {
secrets.iter()
.any(|secret| {
match totp::verify(secret, token) {
Ok(true) => true,
Ok(false) => false,
Err(e) => {
error!("Error from totp::verify: {}", e);
false
}
}
})
}
pub(in super) fn POST<'a>(header_infos: &HeaderExtract, state: &ApplicationState, req: &Request<Bytes>)
-> Response<String> {
let mut token = None;
let mut redirect = None;
for (key, val) in form_urlencoded::parse(req.body()) {
if key == "token" {
token = Some(val.into_owned())
} else if key == "redirect" {
redirect = Some(val.into_owned())
}
}
if token.is_none() {
return error_handler_internal("missing argument 'token'".to_string());
}
let redirect = redirect.unwrap_or(Default::default());
if header_infos.totp_secrets.is_empty() {
return error_handler_internal("no secrets configured".to_string())
}
let mut ret = Response::builder();
if test_secrets(&header_infos.totp_secrets, &token.unwrap()) {
let cookie_value = state.cookie_store.create_authenticated_cookie();
let cookie = CookieBuilder::new(COOKIE_NAME, cookie_value.to_string())
.http_only(true)
.path("/")
.max_age(state.cookie_max_age)
.finish();
ret.header(SET_COOKIE, cookie.to_string());
warn!("Authenticated user with cookie {}", cookie);
ret.body(views::login_auth_success(&redirect)).unwrap()
} else {
ret.body(views::login_auth_fail()).unwrap()
}
}
|