use crate::routes::pages; use rocket::{ catch, form::{Form, FromForm}, http::{Cookie, CookieJar, Status}, post, request::{FromRequest, Outcome, Request}, response::Redirect, uri, State, }; use rocket_contrib::templates::Template; pub struct MasterPassword(String); impl From for MasterPassword { fn from(pass: String) -> Self { Self(pass) } } const AUTH_COOKIE_KEY: &str = "authorized"; const AUTH_COOKIE_VAL: &str = "true"; #[derive(Debug)] pub struct Authorized; #[derive(Debug)] pub struct Unauthorized; #[rocket::async_trait] impl<'a> FromRequest<'a> for Authorized { type Error = Unauthorized; async fn from_request(request: &'a Request<'_>) -> Outcome { let cookies = request.cookies(); match cookies.get_private(AUTH_COOKIE_KEY) { Some(cookie) if cookie.value() == AUTH_COOKIE_VAL => Outcome::Success(Authorized), _ => Outcome::Failure((Status::Unauthorized, Unauthorized)), } } } #[catch(401)] pub fn login_page(_req: &Request) -> Template { Template::render("login", &()) } #[derive(FromForm)] pub struct Login { password: String, } #[post("/login", data = "")] pub fn login( cookies: &CookieJar, login: Form, master_pass: State, ) -> Redirect { if login.password == master_pass.0 { cookies.add_private(Cookie::new(AUTH_COOKIE_KEY, AUTH_COOKIE_VAL)); } Redirect::to(uri!(pages::index)) }