tld-registration/src/session.rs

84 lines
2.3 KiB
Rust

use std::convert::TryFrom;
use std::future::{ready, Ready};
use std::time::{Duration, SystemTime};
use actix_web::dev::Payload;
use actix_web::http::header::LOCATION;
use actix_web::http::Uri;
use actix_web::{FromRequest, HttpRequest, HttpResponse};
use lettre::Address;
use rand::{thread_rng, Fill};
pub struct Session(actix_session::Session);
impl FromRequest for Session {
type Config = <actix_session::Session as FromRequest>::Config;
type Error = <actix_session::Session as FromRequest>::Error;
type Future = Ready<Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
ready(
actix_session::Session::from_request(req, payload)
.into_inner()
.map(Self),
)
}
}
impl Session {
pub fn init(&self, email: &Address) {
self.0.clear();
self.0
.insert("email", email)
.expect("email serialization to work");
let mut buf: [u8; 32] = [0; 32];
buf.try_fill(&mut thread_rng()).expect("rng to fill buf");
self.0
.insert(
"expires",
SystemTime::now() + Duration::from_secs(60 * 60 * 24),
)
.expect("setting expiration to work");
}
pub fn purge(&self) {
self.0.purge();
}
pub fn validate_or_redirect(&self, redirect_to: &Uri) -> Result<(), HttpResponse> {
if self.expired() {
self.0.clear();
self.set_redirect_url(redirect_to);
Err(HttpResponse::SeeOther()
.insert_header((LOCATION, "/login"))
.finish())
} else {
Ok(())
}
}
pub fn expired(&self) -> bool {
self.0
.get("expires")
.ok()
.flatten()
.map_or(true, |expires: SystemTime| expires < SystemTime::now())
}
pub fn get_redirect_url(&self) -> Option<Uri> {
self.0
.remove("redirect_to")
.and_then(|v| Uri::try_from(&v).ok())
}
pub fn set_redirect_url(&self, url: &Uri) {
self.0
.insert("redirect_to", url.to_string())
.expect("setting a str to work");
}
pub fn email(&self) -> Option<Address> {
self.0.get("email").ok().flatten()
}
}