feat(handlers): Add RequireLogin middleware

Adds a middleware that automatically redirects users to the login page
if they don't have an active session (i.e. 'author' set).
This commit is contained in:
Vincent Ambo 2018-04-09 09:10:48 +02:00
parent d91dec28f8
commit ef5e8ec8bd
2 changed files with 27 additions and 4 deletions

View file

@ -6,8 +6,9 @@
//! project root. //! project root.
use actix::prelude::{Addr, Syn}; use actix::prelude::{Addr, Syn};
use actix_web;
use actix_web::*; use actix_web::*;
use actix_web::middleware::RequestSession; use actix_web::middleware::{Started, Middleware, RequestSession};
use db::*; use db::*;
use errors::{Result, ConverseError}; use errors::{Result, ConverseError};
use futures::Future; use futures::Future;
@ -120,6 +121,8 @@ pub fn login(state: State<AppState>) -> ConverseResponse {
.responder() .responder()
} }
const AUTHOR: &'static str = "author";
pub fn callback(state: State<AppState>, pub fn callback(state: State<AppState>,
data: Form<CodeResponse>, data: Form<CodeResponse>,
mut req: HttpRequest<AppState>) -> ConverseResponse { mut req: HttpRequest<AppState>) -> ConverseResponse {
@ -128,10 +131,30 @@ pub fn callback(state: State<AppState>,
.and_then(move |result| { .and_then(move |result| {
let author = result?; let author = result?;
info!("Setting cookie for {} after callback", author.name); info!("Setting cookie for {} after callback", author.name);
req.session().set("author_name", author.name)?; req.session().set(AUTHOR, author)?;
req.session().set("author_email", author.email)?;
Ok(HttpResponse::SeeOther() Ok(HttpResponse::SeeOther()
.header("Location", "/") .header("Location", "/")
.finish())}) .finish())})
.responder() .responder()
} }
/// Middleware used to enforce logins unceremonially.
pub struct RequireLogin;
impl <S> Middleware<S> for RequireLogin {
fn start(&self, req: &mut HttpRequest<S>) -> actix_web::Result<Started> {
let has_author = req.session().get::<Author>(AUTHOR)?.is_some();
let is_oidc_req = req.path().starts_with("/oidc");
if !is_oidc_req && !has_author {
Ok(Started::Response(
HttpResponse::SeeOther()
.header("Location", "/oidc/login")
.finish()
))
} else {
Ok(Started::Done)
}
}
}

View file

@ -42,7 +42,7 @@ pub struct CodeResponse {
/// This struct represents the data extracted from the ID token and /// This struct represents the data extracted from the ID token and
/// stored in the user's session. /// stored in the user's session.
#[derive(Debug)] #[derive(Debug, Serialize, Deserialize)]
pub struct Author { pub struct Author {
pub name: String, pub name: String,
pub email: String, pub email: String,