extern crate iron_sessionstorage; use iron_sessionstorage::traits::*; use iron_sessionstorage::SessionStorage; use iron_sessionstorage::backends::SignedCookieBackend; use iron::status; use iron::modifiers::Header; use iron::headers::ContentType; use iron::{Iron, IronError, Request, IronResult, Response, Chain, Listening}; use iron::error::{HttpResult}; use router::Router; use systemd::unit; use systemd::journal; use render; use staticfile::Static; use regex::Regex; struct Login { user: String, } impl iron_sessionstorage::Value for Login { fn get_key() -> &'static str { "login" } fn into_raw(self) -> String { self.user } fn from_raw(v: String) -> Option { Some(Login{ user: v }) } } fn overview(r: &mut Request) -> IronResult { let mut _value = try!(r.session().get::()); let units = unit::get_units("*").unwrap(); let sections = ["service", "timer", "socket", "target", "slice", "mount", "path"]; let units_by_section = sections.iter().map(|&s| { (s.to_owned(), units.iter().filter(|&u| &u.type_ == s).collect::>()) }).collect::>(); // let res = Ok(Response::with((status::Ok, // Header(ContentType::html()), // render_message(&format!("Hello, {} ({})", // name, // session_value.0), // &units)))); // info!("Updating session value. Current value: {}", session_value.0); // session_value.0.push('a'); // try!(r.session().set(session_value)); Ok(Response::with((status::Ok, Header(ContentType::html()), render::system_status(&units_by_section)))) } fn journal(r: &mut Request) -> IronResult { let unit = iexpect!(r.extensions .get::() .unwrap() .find("unit"), status::BadRequest); let re = Regex::new(r"[-_\w\d]*").unwrap(); if !re.is_match(unit) { return Ok(Response::with( (status::BadRequest, format!("Unit ({}) does not match {}", unit, re)))); } Ok(Response::with((status::Ok, itry!(journal::get_log(unit, 100))))) } fn unit_status(r: &mut Request) -> IronResult { let unit_name = iexpect!(r.extensions .get::() .unwrap() .find("unit"), status::BadRequest); let re = Regex::new(r"[-_\w\d]*").unwrap(); if !re.is_match(unit_name) { return Ok(Response::with( (status::BadRequest, format!("Unit ({}) does not match {}", unit_name, re)))); } let ref unit = itry!(unit::get_units(unit_name))[0]; let log = itry!(journal::get_log(unit_name, 15)); Ok(Response::with((status::Ok, Header(ContentType::html()), render::unit_status(&unit, &log)))) } fn login(r: &mut Request) -> IronResult { Ok(Response::with((status::Ok, Header(ContentType::html()), render::login_page()))) } fn login_submit(r: &mut Request) -> IronResult { Ok(Response::with((status::Ok, Header(ContentType::plaintext()), "login"))) // TODO: Need this to get params: // https://github.com/iron/params } pub fn serve(port: u16) -> HttpResult { let secret = b"secret2".to_vec(); let router = router!( root: get "/" => overview, login: get "/login" => login, login_submit: post "/login" => login_submit, details: get "/status/:unit" => unit_status, journal: get "/journal/:unit" => journal, css: get "/static/main.css" => Static::new(""), ); let mut chain = Chain::new(router); chain.link_around(SessionStorage::new(SignedCookieBackend::new(secret))); let bind_address = format!("{}:{}", "::", port); Iron::new(chain).http(bind_address.as_str()) }