add username limits (no special characters, max and min size) and start working on image support for blog posts (because yes, this is a template, but i also want to get all the basic things for a blog working

This commit is contained in:
SadlyNotSappho 2024-02-16 14:47:31 -08:00
parent 17f46ce71d
commit 860399e4fc
5 changed files with 114 additions and 40 deletions

11
Cargo.lock generated
View File

@ -520,6 +520,7 @@ dependencies = [
"base64", "base64",
"rand", "rand",
"rand_hc", "rand_hc",
"regex",
"rocket", "rocket",
"rocket_db_pools", "rocket_db_pools",
"sha256", "sha256",
@ -1384,13 +1385,13 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.2" version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
"regex-automata 0.4.3", "regex-automata 0.4.5",
"regex-syntax 0.8.2", "regex-syntax 0.8.2",
] ]
@ -1405,9 +1406,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.3" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",

View File

@ -9,6 +9,7 @@ edition = "2021"
base64 = "0.21.7" base64 = "0.21.7"
rand = "0.8.5" rand = "0.8.5"
rand_hc = "0.3.2" rand_hc = "0.3.2"
regex = "1.10.3"
rocket = {version="0.5.0",features=["secrets","json"]} rocket = {version="0.5.0",features=["secrets","json"]}
rocket_db_pools = {version="0.1.0",features=["sqlx_postgres"]} rocket_db_pools = {version="0.1.0",features=["sqlx_postgres"]}
sha256 = "1.5.0" sha256 = "1.5.0"

View File

@ -1 +1,11 @@
pub mod tables; pub mod tables;
pub struct Status<T> {
pub status: StatusTypes,
pub data: T
}
pub enum StatusTypes {
Success,
Faliure
}

View File

@ -1,3 +1,4 @@
use fossil::StatusTypes;
use rocket::fairing::AdHoc; use rocket::fairing::AdHoc;
use rocket::fs::FileServer; use rocket::fs::FileServer;
use rocket::http::Status; use rocket::http::Status;
@ -43,27 +44,34 @@ async fn createuser(
mut db: Connection<Db>, mut db: Connection<Db>,
info: Json<LoginInfo>, info: Json<LoginInfo>,
cookies: &CookieJar<'_>, cookies: &CookieJar<'_>,
) -> &'static str { ) -> String {
let token = cookies.get_private("token"); let token = cookies.get_private("token");
match token.is_some() { match token.is_some() {
true => "You're already logged in. Log out before trying to create a new account.", true => "You're already logged in. Log out before trying to create a new account.".to_string(),
false => { false => {
match User::get_by_username(&mut db, &info.username).await { match User::get_by_username(&mut db, &info.username).await {
Some(_) => "Username already taken. Please try again.", Some(_) => "Username already taken. Please try again.".to_string(),
None => { None => {
User::create(&mut db, &info.username, &info.password).await; let created = User::create(&mut db, &info.username, &info.password).await;
match User::get_by_username(&mut db, &info.username).await { match created.status {
Some(user) => match user.set_new_token(&mut db).await { StatusTypes::Success => {
Ok(t) => { match User::get_by_username(&mut db, &info.username).await {
cookies.add_private(("token", t)); Some(user) => match user.set_new_token(&mut db).await {
"Your account has been created and you've been automatically logged in." Ok(t) => {
}, cookies.add_private(("token", t));
Err(why) => { "Your account has been created and you've been automatically logged in.".to_string()
eprintln!("{why:?}"); },
"Couldn't log you in. Your account has been created, though." Err(why) => {
}, eprintln!("{why:?}");
"Couldn't log you in. Your account has been created, though.".to_string()
},
},
None => "Something went really wrong. I don't know what.".to_string()
}
}, },
None => "Something went really wrong. I don't know what." StatusTypes::Faliure => {
format!("Couldn't create user: {}", created.data)
}
} }
} }
} }
@ -278,7 +286,7 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
let mut conn: PoolConnection<Postgres> = db.acquire().await.unwrap(); let mut conn: PoolConnection<Postgres> = db.acquire().await.unwrap();
let _ = conn let _ = conn
.fetch_one(sqlx::query_as::<_, Post>( .execute(sqlx::query_as::<_, Post>(
"CREATE TABLE IF NOT EXISTS posts ( "CREATE TABLE IF NOT EXISTS posts (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL, title VARCHAR NOT NULL,
@ -288,7 +296,7 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
)) ))
.await; .await;
let _ = conn let _ = conn
.fetch_one(sqlx::query( .execute(sqlx::query(
"CREATE TABLE IF NOT EXISTS users ( "CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY, id SERIAL PRIMARY KEY,
username VARCHAR NOT NULL UNIQUE, username VARCHAR NOT NULL UNIQUE,
@ -298,7 +306,7 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
)) ))
.await; .await;
let _ = conn.fetch_one(sqlx::query( let _ = conn.execute(sqlx::query(
"ALTER TABLE users "ALTER TABLE users
ADD COLUMN IF NOT EXISTS admin BOOLEAN NOT NULL DEFAULT FALSE, ADD COLUMN IF NOT EXISTS admin BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS make_posts BOOLEAN NOT NULL DEFAULT FALSE, ADD COLUMN IF NOT EXISTS make_posts BOOLEAN NOT NULL DEFAULT FALSE,
@ -326,7 +334,18 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
.await .await
.expect("couldn't create admin user"); .expect("couldn't create admin user");
} }
} };
let _ = conn
.execute(sqlx::query(
"CREATE TABLE IF NOT EXISTS images (
id SERIAL PRIMARY KEY,
uuid VARCHAR NOT NULL UNIQUE,
owner_name TEXT NOT NULL,
image TEXT NOT NULL
)",
))
.await;
rocket rocket
} }

View File

@ -1,5 +1,6 @@
use base64::{engine::general_purpose, Engine}; use base64::{engine::general_purpose, Engine};
use rand::{RngCore, SeedableRng}; use rand::{RngCore, SeedableRng};
use regex::Regex;
use rocket::http::Cookie; use rocket::http::Cookie;
use rocket_db_pools::sqlx::Executor; use rocket_db_pools::sqlx::Executor;
use rocket_db_pools::Connection; use rocket_db_pools::Connection;
@ -9,6 +10,8 @@ use rocket_db_pools::{
}; };
use sqlx::FromRow; use sqlx::FromRow;
use crate::{Status, StatusTypes};
#[derive(Database)] #[derive(Database)]
#[database("fossil_postgres")] #[database("fossil_postgres")]
pub struct Db(PgPool); pub struct Db(PgPool);
@ -67,23 +70,56 @@ pub struct User {
} }
impl User { impl User {
pub async fn create(db: &mut Connection<Db>, username: &String, password: &String) { pub async fn create(db: &mut Connection<Db>, username: &String, password: &String) -> Status<String> {
match db match Regex::new(r"[^A-Za-z0-9_]") {
.execute( Ok(r) => {
sqlx::query( match r.captures(username) {
r#" Some(_) => Status {
INSERT INTO users (username, password) status: StatusTypes::Faliure,
VALUES ($1, $2); data:"The username contains invalid characters. Only letters, numbers, and underscores are allowed.".to_string()
"#, },
) None => {
.bind(username) if username.len().gt(&32) || username.len().lt(&3) { // i can Never
.bind(sha256::digest(password)), // remember which symbol is which. this works better for me.
) Status {
.await status: StatusTypes::Faliure,
{ data: "Please choose a username between 3 and 32 characters.".to_string()
Ok(_) => (), }
} else {
match db
.execute(
sqlx::query(
r#"
INSERT INTO users (username, password)
VALUES ($1, $2);
"#,
)
.bind(username)
.bind(sha256::digest(password)),
).await
{
Ok(_) => Status {
status: StatusTypes::Success,
data: "Created user.".to_string()
},
Err(why) => {
eprintln!("Couldn't create database entry: {why:?}");
Status {
status: StatusTypes::Faliure,
data: "Failed to create user.".to_string()
}
}
}
}
}
}
}
Err(why) => { Err(why) => {
eprintln!("Couldn't create database entry: {why:?}"); eprintln!("Couldn't compile name regex: {why:?}");
Status {
status: StatusTypes::Faliure,
data: "Couldn't compile name regex.".to_string()
}
} }
} }
} }
@ -195,3 +231,10 @@ impl User {
} }
} }
} }
pub struct Image {
pub id: i32,
pub uuid: String,
pub owner_name: String,
pub image: String,
}