From 2c86325e3c23fdddfb0a84e479437c8bc057a7eb Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Fri, 31 Jan 2020 20:30:03 -0500 Subject: Add user request guard --- src/server.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'src/server.rs') diff --git a/src/server.rs b/src/server.rs index 4f98337..40e6b87 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,13 +1,14 @@ -use diesel::pg::PgConnection; use rocket::http::Cookies; use rocket::http::Cookie; use rocket::config::Config; use rocket::config::Environment; use rocket::config::Value; use rocket::http::Status; +use rocket::request; use rocket::request::Form; use rocket::request::FromForm; -use rocket::response; +use rocket::request::FromRequest; +use rocket::request::Request; use rocket::response::Redirect; use rocket::State; use rocket_contrib::templates::Template; @@ -24,11 +25,48 @@ pub struct Params { #[database("db")] pub struct Db(diesel::PgConnection); +#[derive(Debug)] +pub struct LoggedInUser { + pub username: String, +} + +impl<'a, 'r> FromRequest<'a, 'r> for LoggedInUser { + type Error = Error; + + fn from_request(request: &'a Request<'r>) + -> request::Outcome { + let conn = request.guard::() + .map_failure(|(s, ())| (s, Error::InternalError))?; + + let user = (|| { + let username = request.cookies() + .get_private("user") + .map(|cookie| cookie.value().to_string()) + .ok_or(Error::NotFound)?; + if db::user_exists(&conn, &username)? { + Ok(LoggedInUser{username: username}) + } else { + Err(Error::NotFound) + } + })(); + + use request::Outcome; + match user { + Ok(user) => Outcome::Success(user), + Err(Error::NotFound) => Outcome::Forward(()), + Err(e) => Outcome::Failure((Status::InternalServerError, e)), + } + } +} + #[get("/")] -fn index() -> Template { +fn index(user: Option) -> Template { let mut context = HashMap::new(); - context.insert("parent", "layout"); - context.insert("message", "Hello, World"); + context.insert("parent", "layout".to_string()); + context.insert("message", "Hello, World".to_string()); + for user in user { + context.insert("user", user.username); + } Template::render("index", context) } @@ -48,12 +86,10 @@ struct LoginData { password: String, } -// Request guard for logged in user: https://api.rocket.rs/v0.4/rocket/request/trait.FromRequest.html - #[post("/login", data = "")] fn login_submit(conn: Db, data: Form, mut cookies: Cookies) -> Result { match db::authenticate(&*conn, &data.username, &data.password) { - Ok(user) => { + Ok(_user) => { cookies.add_private(Cookie::new("user", data.username.clone())); Ok(Redirect::to(uri!(index).to_string())) }, @@ -87,14 +123,17 @@ fn link_strava(config: State) -> Redirect { )) } -pub fn start(db_url: &str, params: Params) { +pub fn start(conn: diesel::PgConnection, db_url: &str, params: Params) { let mut database_config = HashMap::new(); let mut databases = HashMap::new(); database_config.insert("url", Value::from(db_url)); databases.insert("db", Value::from(database_config)); + let persistent_config = db::get_config(&conn).expect("loading config"); + let config = Config::build(Environment::Development) .extra("databases", databases) + .secret_key(persistent_config.rocket_secret_key) .finalize() .unwrap(); -- cgit v1.2.3