summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Fischer <yvesf-git@xapek.org>2018-11-26 21:01:09 +0100
committerYves Fischer <yvesf-git@xapek.org>2018-11-26 21:01:09 +0100
commit16055300c760c636399f555ce30c07deff2a6820 (patch)
tree9b93f656f413ec02810c4deab38cdf8cec2f34ab
parent4a966e386d2a095c3028c758f2bc872fcb3c1e48 (diff)
downloadnginx-auth-totp-16055300c760c636399f555ce30c07deff2a6820.tar.gz
nginx-auth-totp-16055300c760c636399f555ce30c07deff2a6820.zip
Redo response builder usage
- Set correct content-type header - Refactor views to use one base-view
-rw-r--r--src/request_handler/handler_login.rs17
-rw-r--r--src/request_handler/mod.rs39
-rw-r--r--src/request_handler/views.rs179
3 files changed, 116 insertions, 119 deletions
diff --git a/src/request_handler/handler_login.rs b/src/request_handler/handler_login.rs
index bfa7016..aa93e96 100644
--- a/src/request_handler/handler_login.rs
+++ b/src/request_handler/handler_login.rs
@@ -14,9 +14,9 @@ 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())
+ Response::builder().set_defaults().body(views::login_is_logged_in()).unwrap()
} else {
- make_response(StatusCode::OK, views::login_login_form(path_rest))
+ Response::builder().set_defaults().body(views::login_login_form(path_rest)).unwrap()
}
}
@@ -51,10 +51,9 @@ pub(in super) fn POST<'a>(header_infos: &HeaderExtract, state: &ApplicationState
let redirect = redirect.unwrap_or(Default::default());
if header_infos.totp_secrets.is_empty() {
- return error_handler_internal("no secrets configured".to_string())
+ 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())
@@ -62,10 +61,14 @@ pub(in super) fn POST<'a>(header_infos: &HeaderExtract, state: &ApplicationState
.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()
+ Response::builder()
+ .set_defaults()
+ .header(SET_COOKIE, cookie.to_string())
+ .body(views::login_auth_success(&redirect)).unwrap()
} else {
- ret.body(views::login_auth_fail()).unwrap()
+ Response::builder()
+ .set_defaults()
+ .body(views::login_auth_fail()).unwrap()
}
} \ No newline at end of file
diff --git a/src/request_handler/mod.rs b/src/request_handler/mod.rs
index 2e92821..72e9142 100644
--- a/src/request_handler/mod.rs
+++ b/src/request_handler/mod.rs
@@ -12,6 +12,7 @@ use std::cell::RefCell;
use time;
use http::{Request, Response, StatusCode, Method};
+use http::response::Builder;
use tokio::prelude::*;
use horrorshow;
use cookie::{Cookie, CookieBuilder};
@@ -55,12 +56,24 @@ pub struct RequestHandler {
routing_table: router::RoutingTable<Route>,
}
-pub(in request_handler) fn make_response(code: StatusCode, body: String) -> Response<String> {
- Response::builder().status(code).body(body).unwrap()
+pub trait ResponseBuilderExtra {
+ fn set_defaults(&mut self) -> &mut Self;
+}
+
+impl ResponseBuilderExtra for Builder {
+ fn set_defaults(&mut self) -> &mut Self {
+ self
+ .status(StatusCode::OK)
+ .header(::http::header::CONTENT_TYPE, "text/html; charset=utf-8")
+ .header("X-Frame-Options", "DENY")
+ }
}
pub(in request_handler) fn error_handler_internal(body: String) -> Response<String> {
- Response::builder().status(StatusCode::INTERNAL_SERVER_ERROR).body(body).unwrap()
+ Response::builder()
+ .set_defaults()
+ .status(StatusCode::INTERNAL_SERVER_ERROR)
+ .body(body).unwrap()
}
impl HttpHandler<super::ApplicationState> for RequestHandler {
@@ -71,8 +84,8 @@ impl HttpHandler<super::ApplicationState> for RequestHandler {
Ok((Route::Logout, rest)) => logout(state, &req, rest),
Ok((Route::Check, rest)) => check(state, &req, rest),
Err(error) => match error {
- router::NoMatchingRoute =>
- make_response(StatusCode::NOT_FOUND, "Resource not found".to_string()),
+ router::NoMatchingRoute => Response::builder().set_defaults()
+ .status(StatusCode::NOT_FOUND).body("Resource not found".to_string()).unwrap(),
}
}
}
@@ -111,7 +124,8 @@ fn info<'a>(request_handler: &RequestHandler, state: &super::ApplicationState,
} else {
views::info(path_rest)
};
- Response::builder().body(view).unwrap()
+ Response::builder().set_defaults()
+ .body(view).unwrap()
}
fn login<'a>(state: &super::ApplicationState, req: &Request<Bytes>, path_rest: &'a str,
@@ -127,15 +141,15 @@ fn login<'a>(state: &super::ApplicationState, req: &Request<Bytes>, path_rest: &
}
}
+// unimplemented
fn logout<'a>(state: &super::ApplicationState, req: &Request<Bytes>, path_rest: &'a str,
) -> Response<String> {
let header_infos = match parse_header_infos(req) {
Ok(infos) => infos,
Err(message) => return error_handler_internal(message),
};
-
- let body = format!("Rest: {}", path_rest);
- Response::builder().body(body.to_string()).unwrap()
+ Response::builder().set_defaults()
+ .body(format!("Rest: {}", path_rest)).unwrap()
}
@@ -145,9 +159,12 @@ fn check<'a>(state: &super::ApplicationState, req: &Request<Bytes>, path_rest: &
Err(message) => return error_handler_internal(message),
};
if is_logged_in(&header_infos.cookies, &state.cookie_store) {
- make_response(StatusCode::OK, "".to_string())
+ Response::builder().set_defaults()
+ .body(Default::default()).unwrap()
} else {
- make_response(StatusCode::UNAUTHORIZED, "Cookie expired".to_string())
+ Response::builder().set_defaults()
+ .status(StatusCode::UNAUTHORIZED)
+ .body("Cookie expired".to_string()).unwrap()
}
}
diff --git a/src/request_handler/views.rs b/src/request_handler/views.rs
index ee020eb..1a239a4 100644
--- a/src/request_handler/views.rs
+++ b/src/request_handler/views.rs
@@ -1,138 +1,115 @@
-use horrorshow::Template;
+use std::boxed::Box;
+use horrorshow::{Render, RenderBox, Template};
-pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String)>) -> String {
+
+fn render_base_template(title: &'static str, page_body: Box<RenderBox>) -> String {
(html! {
: horrorshow::helper::doctype::HTML;
html {
head {
- title: "Hello world!";
+ title: title;
+ meta(name="viewport", content="width=device-width, initial-scale=1.5");
}
body {
- h1(id = "heading") {
- : "Hello! This is <html />";
- : "And path rest is: ";
- : path_rest;
- : "... ok :)";
- }
- h2: "Valid cookies are:";
- table(border="1") {
- thead {
- th: "Cookie value";
- th: "Valid until";
- }
- tbody {
- @ for (name, valid_until) in cookies {
- tr {
- td: name;
- td: valid_until;
- }
- }
- }
- }
+ : page_body;
}
}
}).into_string().unwrap()
}
-pub(in super) fn info<'a>(path_rest: &'a str) -> String {
- (html! {
- : horrorshow::helper::doctype::HTML;
- html {
- head {
- title: "Hello world!";
+pub(in super) fn info_debug<'a>(path_rest: &'a str, cookies: Vec<(String, String)>) -> String {
+ let path = path_rest.to_string();
+ render_base_template("Info (debug)", box_html! {
+ h1(id = "heading") {
+ : "Hello! This is <html />";
+ : "And path rest is: ";
+ : path;
+ : "... ok :)";
+ }
+ h2: "Valid cookies are:";
+ table(border="1") {
+ thead {
+ th: "Cookie value";
+ th: "Valid until";
}
- body {
- h1(id = "heading") {
- : "Hello! This is <html />";
- : "And path rest is: ";
- : path_rest;
- : "... ok :)";
+ tbody {
+ @ for (name, valid_until) in cookies {
+ tr {
+ td: name;
+ td: valid_until;
+ }
}
}
}
- }).into_string().unwrap()
+ })
+}
+
+pub(in super) fn info<'a>(path_rest: &'a str) -> String {
+ let path = path_rest.to_string();
+ render_base_template("Info", box_html! {
+ h1(id = "heading") {
+ : "Hello! This is <html />";
+ : "And path rest is: ";
+ : path;
+ : "... ok :)";
+ }
+ })
}
pub(in super) fn login_is_logged_in() -> String {
- (html! {
- : horrorshow::helper::doctype::HTML;
- html {
- head {
- title: "TOTP Login";
- }
- body {
- h1(id = "heading") {
- : "Currently logged in"
- }
- }
+ render_base_template("Logged in", box_html! {
+ h1(id = "heading") {
+ : "Currently logged in"
}
- }).into_string().unwrap()
+ })
}
pub(in super) fn login_login_form<'a>(redirect: &'a str) -> String {
- (html! {
- : horrorshow::helper::doctype::HTML;
- html {
- head {
- title: "TOTP Login";
- }
- body {
- h1(id = "heading") {
- : "Login"
- }
- form(method="POST") {
- label(for="token") {
+ let redirect = redirect.to_string();
+ render_base_template("TOTP Login", box_html! {
+ h1(id = "heading") {
+ : "Login"
+ }
+ form(method="POST") {
+ div {
+ label(for="token") {
: "Enter TOTP token"
- }
- input(name="token",id="token",type="text");
- input(name="redirect", type="hidden", value=redirect);
- input(name="send",type="submit",value="Submit");
}
}
+ div {
+ input(name="token",id="token",type="number",autocomplete="off",required="");
+ input(name="redirect", type="hidden", value=redirect);
+ }
+ div {
+ input(name="send",type="submit",value="Submit");
+ }
}
- }).into_string().unwrap()
+ })
}
pub(in super) fn login_auth_success(redirect: &String) -> String {
- (html! {
- : horrorshow::helper::doctype::HTML;
- html {
- head {
- title: "TOTP Successful";
- meta(http-equiv="refresh", content=format!("3; URL={}", redirect))
- }
- body {
- h1(id = "heading") {
- : "Login succesful"
- }
- a(href=redirect) {
- : "Try again... redirecting to ";
- }
- span {
- : format!("{}", redirect)
- }
- }
+ let redirect = redirect.clone();
+ render_base_template("Login successful", box_html! {
+ h1(id = "heading") {
+ : "Login succesful"
}
- }).into_string().unwrap()
+ a(href=&redirect) {
+ : "redirecting to ";
+ }
+ span {
+ : format!("{}", redirect)
+ }
+ })
}
pub(in super) fn login_auth_fail() -> String {
- (html! {
- : horrorshow::helper::doctype::HTML;
- html {
- head {
- title: "TOTP Login failed";
- meta(http-equiv="refresh", content="1")
- }
- body {
- h1(id = "heading") {
- : "Login failed"
- }
- a(href="login") {
- : "Try again... "
- }
- }
+ render_base_template("Login failed", box_html! {
+ h1(id = "heading") {
+ : "Login failed"
}
- }).into_string().unwrap()
+ a(href="login") {
+ : "Try again... "
+ }
+ })
} \ No newline at end of file