From 11052951b74b9ad4b6a9412ae490086235f9154b Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 3 Jan 2021 13:40:40 +0100 Subject: Rewrite in Rust --- src/controller/utils.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/controller/utils.rs (limited to 'src/controller/utils.rs') diff --git a/src/controller/utils.rs b/src/controller/utils.rs new file mode 100644 index 0000000..225f8a4 --- /dev/null +++ b/src/controller/utils.rs @@ -0,0 +1,119 @@ +use hyper::header::{ + HeaderName, HeaderValue, CACHE_CONTROL, CONTENT_TYPE, LOCATION, SET_COOKIE, +}; +use hyper::{Body, Response, StatusCode}; +use std::collections::HashMap; +use tera::{Context, Tera}; +use tokio::fs::File; +use tokio_util::codec::{BytesCodec, FramedRead}; +use uuid::Uuid; + +use crate::controller::error; +use crate::model::config::Config; + +pub fn with_header( + response: Response, + name: HeaderName, + value: &str, +) -> Response { + with_headers(response, vec![(name, value)]) +} + +pub fn with_headers( + response: Response, + headers: Vec<(HeaderName, &str)>, +) -> Response { + let mut response = response; + let response_headers = response.headers_mut(); + for (name, value) in headers { + response_headers.insert(name, HeaderValue::from_str(value).unwrap()); + } + response +} + +pub fn with_login_cookie( + config: Config, + login_token: Uuid, + response: Response, +) -> Response { + let cookie = format!( + "TOKEN={}; SameSite=Strict; HttpOnly; Max-Age=86400{}", + login_token, + if config.secure_cookies { + "; Secure" + } else { + "" + } + ); + + with_header(response, SET_COOKIE, &cookie) +} + +pub fn with_logout_cookie( + config: Config, + response: Response, +) -> Response { + let cookie = format!( + "TOKEN=; SameSite=Strict; HttpOnly; Max-Age=0{}", + if config.secure_cookies { + "; Secure" + } else { + "" + } + ); + + with_header(response, SET_COOKIE, &cookie) +} + +pub fn template( + assets: &HashMap, + templates: &Tera, + path: &str, + context: Context, +) -> Response { + let mut context = context.clone(); + context.insert("assets", assets); + + let response = match templates.render(path, &context) { + Ok(template) => Response::new(template.into()), + Err(err) => Response::new( + error::template( + assets, + templates, + "Erreur serveur", + &format!( + "Erreur lors de la préparation de la page : {:?}", + err + ), + ) + .into(), + ), + }; + + with_headers( + response, + vec![(CONTENT_TYPE, "text/html"), (CACHE_CONTROL, "no-cache")], + ) +} + +pub fn redirect(uri: &str) -> Response { + let mut response = Response::default(); + *response.status_mut() = StatusCode::MOVED_PERMANENTLY; + with_headers(response, vec![(LOCATION, uri), (CACHE_CONTROL, "no-cache")]) +} + +pub fn not_found() -> Response { + let mut response = Response::default(); + *response.status_mut() = StatusCode::NOT_FOUND; + response +} + +pub async fn file(filename: &str) -> Response { + if let Ok(file) = File::open(filename).await { + let stream = FramedRead::new(file, BytesCodec::new()); + let body = Body::wrap_stream(stream); + with_header(Response::new(body), CACHE_CONTROL, "max-age=3153600000") + } else { + not_found() + } +} -- cgit v1.2.3