diff options
Diffstat (limited to 'src/server.rs')
-rw-r--r-- | src/server.rs | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/src/server.rs b/src/server.rs index 2ab4f75..3a03ea0 100644 --- a/src/server.rs +++ b/src/server.rs @@ -15,11 +15,15 @@ use router::Router; use staticfile::Static; use systemd::journal; use systemd::unit; -use persistent::Read; - -#[derive(Clone, Default, Debug)] -struct Context { - base_url: String +use persistent::Write; +use rusqlite::Connection; +use db; +use auth; + +#[derive(Debug)] +pub struct Context { + pub base_url: String, + pub conn: Connection } impl iron::typemap::Key for Context { type Value = Context; @@ -120,13 +124,14 @@ fn get_logged_in_user(r: &mut Request) -> IronResult<Option<Login>> { fn login(r: &mut Request) -> IronResult<Response> { let renderer = make_renderer(r)?; + let is_retry = r.method == iron::method::Method::Post; Ok(Response::with((status::Ok, Header(ContentType::html()), - renderer.login_page()))) + renderer.login_page(is_retry)))) } -fn login_submit(r: &mut Request) -> IronResult<Response> { - let login = { +fn authenticate(r: &mut Request) -> IronResult<Response> { + let (user, password) = { let map = r.get_ref::<Params>().unwrap(); let user = match map.get("username") { Some(&Value::String(ref v)) => v, @@ -136,14 +141,25 @@ fn login_submit(r: &mut Request) -> IronResult<Response> { Some(&Value::String(ref v)) => v, _ => panic!("no password in params: {:?}", map) }; - Login { user: user.clone() } + (user.to_string(), password.to_string()) }; - info!("User logged in: {:?}", login); - r.session().set(login)?; - let url = Url::parse("http://localhost:8080/").unwrap(); - Ok(Response::with((status::Found, - Redirect(url)))) + let hash = { + let mutex = r.get::<Write<Context>>().unwrap(); + let context = mutex.lock().unwrap(); + db::lookup_user(&context.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::parse("http://localhost:8080/").unwrap(); + Ok(Response::with((status::Found, + Redirect(url)))) + } else { + login(r) + } } fn logout(r: &mut Request) -> IronResult<Response> { @@ -160,24 +176,21 @@ fn make_renderer(r: &mut Request) -> IronResult<render::Renderer> { }) } -pub fn serve(port: u16) -> HttpResult<Listening> { +pub fn serve(context: Context, port: u16) -> HttpResult<Listening> { // TODO: Use a real secret. let secret = b"secret2".to_vec(); let router = router!( root: get "/" => overview, login: get "/login" => login, - login_submit: post "/login" => login_submit, + authenticate: post "/login" => authenticate, logout: get "/logout" => logout, details: get "/status/:unit" => unit_status, journal: get "/journal/:unit" => journal, css: get "/static/main.css" => Static::new(""), ); let mut chain = Chain::new(router); - let context = Context { - base_url: String::from("http://localhost:8080/"), - }; chain.link_around(SessionStorage::new(SignedCookieBackend::new(secret))); - chain.link(Read::<Context>::both(context)); + chain.link(Write::<Context>::both(context)); let bind_address = format!("{}:{}", "::", port); Iron::new(chain).http(bind_address.as_str()) } |