From 3a5fb7bcd08d6d85a6f41cdf05c6f184a4fca22e Mon Sep 17 00:00:00 2001 From: SadlyNotSappho Date: Fri, 22 Mar 2024 12:10:51 -0700 Subject: [PATCH] i am going insane --- src/main.rs | 102 ++++++++++++++++++++++++------------------- src/tables.rs | 24 +++++++++- web/uploadimage.html | 2 + 3 files changed, 81 insertions(+), 47 deletions(-) diff --git a/src/main.rs b/src/main.rs index 40fc3f0..0f7900d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ use rocket::fs::TempFile; use rocket::http::CookieJar; use rocket::serde::{json::Json, Deserialize}; -use fossil::tables::{Db, Image, Post, User}; +use fossil::tables::{Db, Image, LoginStatus, Post, User}; #[get("/login")] fn login_page() -> RawHtml { @@ -374,65 +374,75 @@ async fn get_image( } #[post("/upload", format = "image/png", data = "")] -async fn upload(mut file: TempFile<'_>, cookies: &CookieJar<'_>, mut db: Connection) -> String { +async fn upload( + mut file: TempFile<'_>, + cookies: &CookieJar<'_>, + mut db: Connection, +) -> status::Custom { let uuid = Uuid::new_v4().to_string(); - match file.copy_to(format!("/srv/tmpimages/{uuid}.png")).await { - Ok(_) => { - // validate that it is, in fact, an image - match Reader::open(format!("/srv/tmpimages/{uuid}.png")) { - Ok(_) => { - match cookies.get_private("token") { - Some(t) => { - match User::get_by_token(&mut db, t).await { - Some(user) => { - if user.make_posts == true || user.admin == true { - // upload to db - match Image::create(&mut db, &uuid, user).await { + + // login & perms check + match User::login_status(&mut db, cookies).await { + LoginStatus::LoggedIn(user) => { + match user.make_posts || user.admin { + // image validation check + true => { + match file.copy_to(format!("/srv/tmpimages/{uuid}.png")).await { + Ok(_) => { + // validate that it is, in fact, an image + match Reader::open(format!("/srv/tmpimages/{uuid}.png")) { + Ok(_) => { + match file.copy_to(format!("/srv/images/{uuid}.png")).await { + Ok(_) => match Image::create(&mut db, &uuid, user).await { Ok(_) => { - // move image - match file - .copy_to(format!("/srv/images/{uuid}.png")) - .await - { - Ok(_) => { - match fs::remove_file(format!( - "/srv/tmpimages/{uuid}.png" - )) { - Ok(_) => uuid, - Err(why) => { - eprintln!("{why:?}"); - "couldn't delete old file" - .to_string() - } - } - } + match fs::remove_file(format!( + "/srv/tmpimages/{uuid}.png" + )) { + Ok(_) => status::Custom(Status::Created, uuid), Err(why) => { - eprintln!("{why:?}"); - "couldn't save file to final destination" - .to_string() + eprintln!("couldn't clear image from tmpimages: {why:?}"); + status::Custom(Status::Ok, uuid) } } } - Err(_) => "Couldn't save to DB".to_string(), - } - } else { - "Invalid perms".to_string() + Err(why) => { + eprintln!("{why:?}"); + status::Custom( + Status::InternalServerError, + "Couldn't save to DB".to_string(), + ) + } + }, + Err(_) => status::Custom( + Status::InternalServerError, + "Couldn't copy file to final location".to_string(), + ), } } - None => "Invalid login token".to_string(), + Err(_) => status::Custom( + Status::Forbidden, + "File isn't an image".to_string(), + ), } } - None => "Not logged in".to_string(), + Err(_) => status::Custom( + Status::InternalServerError, + "Couldn't save temporary file".to_string(), + ), } } - Err(why) => { - // isn't an image, or something else went wrong - eprintln!("{why:?}"); - "error".to_string() - } + false => status::Custom( + Status::Unauthorized, + "You don't have the right permissions for that".to_string(), + ), } } - Err(why) => why.to_string(), + LoginStatus::InvalidToken => { + status::Custom(Status::Unauthorized, "Invalid login token".to_string()) + } + LoginStatus::NotLoggedIn => { + status::Custom(Status::Unauthorized, "Not logged in".to_string()) + } } } diff --git a/src/tables.rs b/src/tables.rs index 4eaf8d9..82f649b 100644 --- a/src/tables.rs +++ b/src/tables.rs @@ -1,7 +1,7 @@ use base64::{engine::general_purpose, Engine}; use rand::{RngCore, SeedableRng}; use regex::Regex; -use rocket::http::Cookie; +use rocket::http::{Cookie, CookieJar}; use rocket_db_pools::sqlx::Executor; use rocket_db_pools::Connection; use rocket_db_pools::{ @@ -67,6 +67,12 @@ pub struct User { pub comment: bool, } +pub enum LoginStatus { + InvalidToken, + NotLoggedIn, + LoggedIn(User) +} + impl User { pub async fn create(db: &mut Connection, username: &String, password: &String) -> Result { match Regex::new(r"[^A-Za-z0-9_]") { @@ -217,6 +223,22 @@ impl User { } } } + + pub async fn login_status(db: &mut Connection, cookies: &CookieJar<'_>) -> LoginStatus { + match cookies.get_private("token") { + Some(t) => { + match User::get_by_token(db, t).await { + Some(user) => { + LoginStatus::LoggedIn(user) + }, + None => { + LoginStatus::InvalidToken + } + } + }, + None => LoginStatus::NotLoggedIn + } + } } pub struct Image { diff --git a/web/uploadimage.html b/web/uploadimage.html index 46637e4..619928c 100644 --- a/web/uploadimage.html +++ b/web/uploadimage.html @@ -32,6 +32,8 @@ }, body: input.files[0] }) + + // TODO: if status is 200, not 201, alert the user to tell the admins to clear tmpimages alert(await token.text()); });