summaryrefslogtreecommitdiff
path: root/src/server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.rs')
-rw-r--r--src/server.rs49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/server.rs b/src/server.rs
index c0e9028..4e5b6f3 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -16,19 +16,26 @@ use router::Router;
use staticfile::Static;
use systemd::journal;
use systemd::unit;
-use persistent::Write;
+use persistent::{Read, Write};
use rusqlite::Connection;
use db;
use auth;
+use url;
#[derive(Debug)]
pub struct Context {
pub base_url: String,
- pub conn: Connection,
}
impl iron::typemap::Key for Context {
type Value = Context;
}
+#[derive(Debug)]
+pub struct State {
+ pub conn: Connection,
+}
+impl iron::typemap::Key for State {
+ type Value = State;
+}
#[derive(Default, Debug, Clone)]
struct Login {
@@ -47,6 +54,22 @@ impl iron_sessionstorage::Value for Login {
}
}
+// Construct an absolute url from base_url if provided, or the request url
+// otherwise.
+fn url_for(r: &mut Request, path: &str) -> Url {
+ let context = r.get::<Read<Context>>().unwrap();
+ match context.base_url.as_ref() {
+ "" => {
+ let mut url: url::Url = r.url.clone().into();
+ url.set_path(path);
+ Url::from_generic_url(url).unwrap()
+ },
+ base_url => {
+ Url::parse(&format!("{}{}", base_url, path)).unwrap()
+ }
+ }
+}
+
fn overview(r: &mut Request) -> IronResult<Response> {
let mut _value = try!(r.session().get::<Login>());
@@ -139,16 +162,16 @@ fn authenticate(r: &mut Request) -> IronResult<Response> {
};
let hash = {
- let mutex = r.get::<Write<Context>>().unwrap();
- let context = mutex.lock().unwrap();
- db::lookup_user(&context.conn, &user).unwrap()
+ let mutex = r.get::<Write<State>>().unwrap();
+ let state = mutex.lock().unwrap();
+ db::lookup_user(&state.conn, &user).unwrap()
};
if let Some(true) = hash.map(|h| auth::validate(&password, &h)) {
let login = Login { user: user.to_string() }; // TODO Make a validated login type
info!("User logged in: {:?}", login);
r.session().set(login)?;
- let url = url_for!(r, "root");
+ let url = url_for(r, "");
Ok(Response::with((status::Found, Redirect(url))))
} else {
login(r)
@@ -157,14 +180,17 @@ fn authenticate(r: &mut Request) -> IronResult<Response> {
fn logout(r: &mut Request) -> IronResult<Response> {
r.session().set::<Login>(Default::default());
- let url = url_for!(r, "root");
+ let url = url_for(r, "");
Ok(Response::with((status::Found, Redirect(url))))
}
fn make_renderer(r: &mut Request) -> IronResult<render::Renderer> {
let user = get_logged_in_user(r)?.map(|u| u.user);
- let base_url = format!("{}", url_for!(r, "root"));
- Ok(render::Renderer { base_url: base_url, user: user })
+ let context = r.get::<Read<Context>>().unwrap();
+ Ok(render::Renderer {
+ base_url: context.base_url.to_string(),
+ user: user
+ })
}
fn static_file(r: &mut Request) -> IronResult<Response> {
@@ -180,7 +206,7 @@ fn static_file(r: &mut Request) -> IronResult<Response> {
})
}
-pub fn serve(context: Context, port: u16) -> HttpResult<Listening> {
+pub fn serve(context: Context, state: State, port: u16) -> HttpResult<Listening> {
// TODO: Use a real secret.
let secret = b"secret2".to_vec();
let router = router!(
@@ -194,7 +220,8 @@ pub fn serve(context: Context, port: u16) -> HttpResult<Listening> {
);
let mut chain = Chain::new(router);
chain.link_around(SessionStorage::new(SignedCookieBackend::new(secret)));
- chain.link(Write::<Context>::both(context));
+ chain.link(Read::<Context>::both(context));
+ chain.link(Write::<State>::both(state));
let bind_address = format!("{}:{}", "::", port);
Iron::new(chain).http(bind_address.as_str())
}