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

View File

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

View File

@ -1 +1,11 @@
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::fs::FileServer;
use rocket::http::Status;
@ -43,27 +44,34 @@ async fn createuser(
mut db: Connection<Db>,
info: Json<LoginInfo>,
cookies: &CookieJar<'_>,
) -> &'static str {
) -> String {
let token = cookies.get_private("token");
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 => {
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 => {
User::create(&mut db, &info.username, &info.password).await;
match User::get_by_username(&mut db, &info.username).await {
Some(user) => match user.set_new_token(&mut db).await {
Ok(t) => {
cookies.add_private(("token", t));
"Your account has been created and you've been automatically logged in."
},
Err(why) => {
eprintln!("{why:?}");
"Couldn't log you in. Your account has been created, though."
},
let created = User::create(&mut db, &info.username, &info.password).await;
match created.status {
StatusTypes::Success => {
match User::get_by_username(&mut db, &info.username).await {
Some(user) => match user.set_new_token(&mut db).await {
Ok(t) => {
cookies.add_private(("token", t));
"Your account has been created and you've been automatically logged in.".to_string()
},
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 _ = conn
.fetch_one(sqlx::query_as::<_, Post>(
.execute(sqlx::query_as::<_, Post>(
"CREATE TABLE IF NOT EXISTS posts (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
@ -288,7 +296,7 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
))
.await;
let _ = conn
.fetch_one(sqlx::query(
.execute(sqlx::query(
"CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR NOT NULL UNIQUE,
@ -298,7 +306,7 @@ async fn migrate(rocket: Rocket<Build>) -> Rocket<Build> {
))
.await;
let _ = conn.fetch_one(sqlx::query(
let _ = conn.execute(sqlx::query(
"ALTER TABLE users
ADD COLUMN IF NOT EXISTS admin 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
.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
}

View File

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