From 10aa258576a7f5c24fcac243414bf5252e32ff35 Mon Sep 17 00:00:00 2001 From: AINDUSTRIES Date: Sat, 28 Sep 2024 00:07:01 +0200 Subject: [PATCH] backend update (login modified and new logout) --- src/main.rs | 59 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index bc0b46e..c6e9376 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,24 @@ +use argon2::{ + password_hash::{ + rand_core::OsRng, + PasswordHash, PasswordHasher, PasswordVerifier, SaltString, + }, + Argon2, +}; use bytes::Buf; use bytes::Bytes; use chrono::{DateTime, Days, Utc}; +#[cfg(target_os = "linux")] +use daemonize::Daemonize; use futures; use http_body_util::{BodyExt, Full}; use hyper::body::{Body, Incoming}; +use hyper::header::{LOCATION, SET_COOKIE}; use hyper::server::conn::http1; use hyper::service::service_fn; use hyper::{Error, Method, Request, Response, StatusCode}; use hyper_util::rt::{TokioIo, TokioTimer}; +use rand::distributions::{Alphanumeric, DistString}; use serde::{Deserialize, Serialize}; use serde_json::{from_reader, Value}; use sqlx::sqlite::SqlitePool; @@ -20,16 +31,6 @@ use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::SystemTime; use tokio::net::TcpListener; -use rand::distributions::{DistString, Alphanumeric}; -use argon2::{ - password_hash::{ - rand_core::OsRng, - PasswordHash, PasswordHasher, PasswordVerifier, SaltString - }, - Argon2 -}; -#[cfg(target_os = "linux")] -use daemonize::Daemonize; #[derive(Serialize, Deserialize)] struct Player { id: i64, @@ -51,13 +52,13 @@ struct User { username: String, saltyhash: String, permissions: i64, - token: String + token: String, } #[derive(Serialize, Deserialize)] struct Login { username: String, - password: String + password: String, } #[derive(Serialize, Deserialize)] struct Settings { @@ -74,10 +75,12 @@ async fn service(req: Request, db: Arc>) -> Result, db: Arc>) -> Result>, Error> { let path = req.uri().path(); - if path.starts_with("/static/") { + if path.starts_with("/static") { get_file(path).await - } else if path.starts_with("/data/") { + } else if path.starts_with("/data") { get_data(path, &req, db).await + } else if path.starts_with("/logout") { + logout().await } else { get_page(path).await } @@ -201,13 +204,13 @@ async fn post(req: Request, db: Arc>) -> Result { post_vote(req, db).await - }, + } "/login" => { login(req, db).await - }, + } "/register" => { register(req, db).await - }, + } _ => { not_found().await } @@ -243,7 +246,7 @@ async fn post_vote(req: Request, db: Arc>) -> Result async fn login(req: Request, db: Arc>) -> Result>, Error> { let body = req.into_body().collect().await; let data: Result = from_reader(body?.aggregate().reader()); - if data.is_err(){ + if data.is_err() { return Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap()); } let data = data.unwrap(); @@ -261,13 +264,18 @@ async fn login(req: Request, db: Arc>) -> Result { let date: DateTime = DateTime::from(SystemTime::now()); let date = date.checked_add_days(Days::new(7)).unwrap(); - Ok(Response::builder().header("Set-Cookie", format!("token={}; Expires={}; Secure; HttpOnly; SameSite=Strict", user.token, date.to_rfc2822())).body(Full::new(Bytes::from("Ok"))).unwrap()) - }, + // With server side rendering, redirect here to "/" + Ok(Response::builder() + .header(SET_COOKIE, + format!("token={}; Expires={}; Secure; HttpOnly; SameSite=Strict", user.token, date.to_rfc2822())) + .body(Full::new(Bytes::from("Ok"))) + .unwrap()) + } Err(_) => { Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap()) } } - }, + } Ok(None) => { Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap()) } @@ -305,6 +313,15 @@ async fn register(req: Request, db: Arc>) -> Result< } } +async fn logout() -> Result>, Error> { + let date: DateTime = DateTime::from(SystemTime::now()); + Ok(Response::builder() + .status(StatusCode::SEE_OTHER) + .header(LOCATION, "/") + .header(SET_COOKIE, format!("token=''; Expires={}; Secure; HttpOnly; SameSite=Strict", date.to_rfc2822())) + .body(Full::new(Bytes::from(""))).unwrap()) +} + fn check_username(username: &String) -> bool { if username.len() > 21 { return false;