From 9eb8501fae4b4024e1b2d052b213351deeae8b81 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sun, 8 Apr 2018 22:56:29 +0200 Subject: [PATCH] feat(handlers): Use cookie session backend to store author info --- src/errors.rs | 14 ++++++++++++-- src/handlers.rs | 26 +++++++++++++++++--------- src/main.rs | 8 ++++++-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index d07d19cd3..cf75f0e29 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -9,6 +9,7 @@ use actix_web::http::StatusCode; // Modules with foreign errors: use actix; +use actix_web; use diesel; use r2d2; use reqwest; @@ -30,11 +31,14 @@ pub enum ConverseError { #[fail(display = "a template rendering error occured: {}", reason)] Template { reason: String }, + #[fail(display = "error occured during request handling: {}", error)] + ActixWeb { error: actix_web::Error }, + // This variant is used as a catch-all for wrapping // actix-web-compatible response errors, such as the errors it // throws itself. #[fail(display = "Actix response error: {}", error)] - ActixWeb { error: Box }, + Actix { error: Box }, } // Establish conversion links to foreign errors: @@ -61,7 +65,13 @@ impl From for ConverseError { impl From for ConverseError { fn from(error: actix::MailboxError) -> ConverseError { - ConverseError::ActixWeb { error: Box::new(error) } + ConverseError::Actix { error: Box::new(error) } + } +} + +impl From for ConverseError { + fn from(error: actix_web::Error) -> ConverseError { + ConverseError::ActixWeb { error } } } diff --git a/src/handlers.rs b/src/handlers.rs index ebae7f390..0531bb174 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -5,14 +5,15 @@ //! the tera templates stored in the `/templates` directory in the //! project root. -use tera; -use actix_web::*; -use models::*; -use db::*; use actix::prelude::{Addr, Syn}; -use futures::Future; +use actix_web::*; +use actix_web::middleware::RequestSession; +use db::*; use errors::{Result, ConverseError}; +use futures::Future; +use models::*; use oidc::*; +use tera; type ConverseResponse = Box>; @@ -119,11 +120,18 @@ pub fn login(state: State) -> ConverseResponse { .responder() } -pub fn callback(state: State, data: Form) -> ConverseResponse { +pub fn callback(state: State, + data: Form, + mut req: HttpRequest) -> ConverseResponse { state.oidc.send(RetrieveToken(data.0)) .from_err() - .and_then(|author| { - Ok(HttpResponse::from(format!("{:?}", author))) - }) + .and_then(move |result| { + let author = result?; + info!("Setting cookie for {} after callback", author.name); + req.session().set("author_name", author.name)?; + req.session().set("author_email", author.email)?; + Ok(HttpResponse::SeeOther() + .header("Location", "/") + .finish())}) .responder() } diff --git a/src/main.rs b/src/main.rs index 570a1b39f..2e2664a2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,7 @@ pub mod schema; use actix::prelude::*; use actix_web::*; +use actix_web::middleware::{Logger, SessionStorage, CookieSessionBackend}; use actix_web::http::Method; use db::*; use diesel::pg::PgConnection; @@ -80,6 +81,7 @@ fn main() { info!("Initialising HTTP server ..."); let bind_host = config_default("CONVERSE_BIND_HOST", "127.0.0.1:4567"); + let key: &[u8] = &[0; 32]; // TODO: generate! server::new(move || { let template_path = concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*"); @@ -91,13 +93,15 @@ fn main() { }; App::with_state(state) - .middleware(middleware::Logger::default()) + .middleware(Logger::default()) + // TODO: Configure session backend with more secure settings. + .middleware(SessionStorage::new(CookieSessionBackend::new(key))) .resource("/", |r| r.method(Method::GET).with(forum_index)) .resource("/thread/submit", |r| r.method(Method::POST).with2(submit_thread)) .resource("/thread/reply", |r| r.method(Method::POST).with2(reply_thread)) .resource("/thread/{id}", |r| r.method(Method::GET).with2(forum_thread)) .resource("/oidc/login", |r| r.method(Method::GET).with(login)) - .resource("/oidc/callback", |r| r.method(Method::POST).with2(callback))}) + .resource("/oidc/callback", |r| r.method(Method::POST).with3(callback))}) .bind(&bind_host).expect(&format!("Could not bind on '{}'", bind_host)) .start();