backend update (login modified and new logout)
This commit is contained in:
57
src/main.rs
57
src/main.rs
@@ -1,13 +1,24 @@
|
|||||||
|
use argon2::{
|
||||||
|
password_hash::{
|
||||||
|
rand_core::OsRng,
|
||||||
|
PasswordHash, PasswordHasher, PasswordVerifier, SaltString,
|
||||||
|
},
|
||||||
|
Argon2,
|
||||||
|
};
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::{DateTime, Days, Utc};
|
use chrono::{DateTime, Days, Utc};
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use daemonize::Daemonize;
|
||||||
use futures;
|
use futures;
|
||||||
use http_body_util::{BodyExt, Full};
|
use http_body_util::{BodyExt, Full};
|
||||||
use hyper::body::{Body, Incoming};
|
use hyper::body::{Body, Incoming};
|
||||||
|
use hyper::header::{LOCATION, SET_COOKIE};
|
||||||
use hyper::server::conn::http1;
|
use hyper::server::conn::http1;
|
||||||
use hyper::service::service_fn;
|
use hyper::service::service_fn;
|
||||||
use hyper::{Error, Method, Request, Response, StatusCode};
|
use hyper::{Error, Method, Request, Response, StatusCode};
|
||||||
use hyper_util::rt::{TokioIo, TokioTimer};
|
use hyper_util::rt::{TokioIo, TokioTimer};
|
||||||
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{from_reader, Value};
|
use serde_json::{from_reader, Value};
|
||||||
use sqlx::sqlite::SqlitePool;
|
use sqlx::sqlite::SqlitePool;
|
||||||
@@ -20,16 +31,6 @@ use std::str::FromStr;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use tokio::net::TcpListener;
|
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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Player {
|
struct Player {
|
||||||
id: i64,
|
id: i64,
|
||||||
@@ -51,13 +52,13 @@ struct User {
|
|||||||
username: String,
|
username: String,
|
||||||
saltyhash: String,
|
saltyhash: String,
|
||||||
permissions: i64,
|
permissions: i64,
|
||||||
token: String
|
token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Login {
|
struct Login {
|
||||||
username: String,
|
username: String,
|
||||||
password: String
|
password: String,
|
||||||
}
|
}
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
@@ -74,10 +75,12 @@ async fn service(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<R
|
|||||||
|
|
||||||
async fn get(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Response<Full<Bytes>>, Error> {
|
async fn get(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Response<Full<Bytes>>, Error> {
|
||||||
let path = req.uri().path();
|
let path = req.uri().path();
|
||||||
if path.starts_with("/static/") {
|
if path.starts_with("/static") {
|
||||||
get_file(path).await
|
get_file(path).await
|
||||||
} else if path.starts_with("/data/") {
|
} else if path.starts_with("/data") {
|
||||||
get_data(path, &req, db).await
|
get_data(path, &req, db).await
|
||||||
|
} else if path.starts_with("/logout") {
|
||||||
|
logout().await
|
||||||
} else {
|
} else {
|
||||||
get_page(path).await
|
get_page(path).await
|
||||||
}
|
}
|
||||||
@@ -201,13 +204,13 @@ async fn post(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Resp
|
|||||||
match path {
|
match path {
|
||||||
"/vote" => {
|
"/vote" => {
|
||||||
post_vote(req, db).await
|
post_vote(req, db).await
|
||||||
},
|
}
|
||||||
"/login" => {
|
"/login" => {
|
||||||
login(req, db).await
|
login(req, db).await
|
||||||
},
|
}
|
||||||
"/register" => {
|
"/register" => {
|
||||||
register(req, db).await
|
register(req, db).await
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
not_found().await
|
not_found().await
|
||||||
}
|
}
|
||||||
@@ -261,13 +264,18 @@ async fn login(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<Res
|
|||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let date: DateTime<Utc> = DateTime::from(SystemTime::now());
|
let date: DateTime<Utc> = DateTime::from(SystemTime::now());
|
||||||
let date = date.checked_add_days(Days::new(7)).unwrap();
|
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(_) => {
|
Err(_) => {
|
||||||
Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap())
|
Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap())
|
Ok(Response::builder().status(StatusCode::BAD_REQUEST).body(Full::new(Bytes::from("Bad Request"))).unwrap())
|
||||||
}
|
}
|
||||||
@@ -305,6 +313,15 @@ async fn register(req: Request<Incoming>, db: Arc<Mutex<SqlitePool>>) -> Result<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn logout() -> Result<Response<Full<Bytes>>, Error> {
|
||||||
|
let date: DateTime<Utc> = 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 {
|
fn check_username(username: &String) -> bool {
|
||||||
if username.len() > 21 {
|
if username.len() > 21 {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user