use tide::{ http::mime, sessions::{CookieStore, SessionMiddleware}, Next, Redirect, Request, Response, Result, StatusCode, }; use std::{env, future::Future, io::ErrorKind, pin::Pin}; use tera::Context; use crate::{routes, State}; pub fn session() -> SessionMiddleware { SessionMiddleware::new( CookieStore::new(), env::var("TIDE_SECRET") .expect( "Please provide a TIDE_SECRET value of at \ least 32 bytes in order to run this example", ) .as_bytes(), ) } pub fn require_auth<'a>( req: Request, next: Next<'a, State>, ) -> Pin + 'a + Send>> { Box::pin(async { let logged_in: bool = req.session().get("logged_in").unwrap_or(false); if logged_in { Ok(next.run(req).await) } else { let login_path = &req.state().login_path; Ok(Redirect::new(login_path).into()) } }) } pub fn require_guest<'a>( req: Request, next: Next<'a, State>, ) -> Pin + 'a + Send>> { Box::pin(async { let logged_in: bool = req.session().get("logged_in").unwrap_or(false); if logged_in { Ok(Redirect::new("/").into()) } else { Ok(next.run(req).await) } }) } pub async fn errors(mut res: Response) -> Result { let mut context = Context::new(); match res.downcast_error::() { Some(e) => { context.insert("error", &e.to_string()); let status = if let ErrorKind::NotFound = e.kind() { StatusCode::NotFound } else { StatusCode::InternalServerError }; let body: String = routes::render_template("error.html", &context)?; res.set_body(body); res.set_status(status); res.set_content_type(mime::HTML); } None => match res.status() { StatusCode::NotFound => { context.insert("error", "Page not found"); res.set_body(routes::render_template("error.html", &context)?); res.set_content_type(mime::HTML); } _ => {} }, }; Ok(res) }