feat(handlers): Use cookie session backend to store author info

This commit is contained in:
Vincent Ambo 2018-04-08 22:56:29 +02:00
parent e761b2d295
commit 9eb8501fae
3 changed files with 35 additions and 13 deletions

View file

@ -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<ResponseError> },
Actix { error: Box<ResponseError> },
}
// Establish conversion links to foreign errors:
@ -61,7 +65,13 @@ impl From<tera::Error> for ConverseError {
impl From<actix::MailboxError> for ConverseError {
fn from(error: actix::MailboxError) -> ConverseError {
ConverseError::ActixWeb { error: Box::new(error) }
ConverseError::Actix { error: Box::new(error) }
}
}
impl From<actix_web::Error> for ConverseError {
fn from(error: actix_web::Error) -> ConverseError {
ConverseError::ActixWeb { error }
}
}

View file

@ -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<Future<Item=HttpResponse, Error=ConverseError>>;
@ -119,11 +120,18 @@ pub fn login(state: State<AppState>) -> ConverseResponse {
.responder()
}
pub fn callback(state: State<AppState>, data: Form<CodeResponse>) -> ConverseResponse {
pub fn callback(state: State<AppState>,
data: Form<CodeResponse>,
mut req: HttpRequest<AppState>) -> 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()
}

View file

@ -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();