p1: added notion of accounts in DB

This commit is contained in:
Artemis 2025-01-24 17:07:00 +01:00
parent e987b45306
commit 8215975757
9 changed files with 105 additions and 3 deletions

40
Cargo.lock generated
View file

@ -372,6 +372,12 @@ dependencies = [
"typenum",
]
[[package]]
name = "ct-codecs"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b916ba8ce9e4182696896f015e8a5ae6081b305f74690baa8465e35f5a142ea4"
[[package]]
name = "der"
version = "0.7.9"
@ -460,6 +466,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"orion",
"rand",
"regex",
"rocket",
@ -467,6 +474,7 @@ dependencies = [
"rocket_dyn_templates",
"serde_json",
"sqlx",
"uuid",
]
[[package]]
@ -532,6 +540,12 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fiat-crypto"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "figment"
version = "0.10.19"
@ -1488,6 +1502,19 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "orion"
version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ab5415cf60cd271259e576f2ddee7a5f9fed42659035224c01af766943fad3"
dependencies = [
"ct-codecs",
"fiat-crypto",
"getrandom",
"subtle",
"zeroize",
]
[[package]]
name = "overload"
version = "0.1.1"
@ -2304,6 +2331,7 @@ dependencies = [
"tokio-stream",
"tracing",
"url",
"uuid",
"webpki-roots",
]
@ -2386,6 +2414,7 @@ dependencies = [
"stringprep",
"thiserror 1.0.69",
"tracing",
"uuid",
"whoami",
]
@ -2425,6 +2454,7 @@ dependencies = [
"stringprep",
"thiserror 1.0.69",
"tracing",
"uuid",
"whoami",
]
@ -2450,6 +2480,7 @@ dependencies = [
"tracing",
"url",
"urlencoding",
"uuid",
]
[[package]]
@ -2989,6 +3020,15 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"serde",
]
[[package]]
name = "valuable"
version = "0.1.0"

View file

@ -12,9 +12,12 @@ sqlx = { version = "0.7", default-features = false, features = [
"macros",
"chrono",
"migrate",
"uuid",
] }
chrono = { version = "0.4", features = ["serde"] }
regex = "1.11"
rand = "0.8"
serde_json = "1.0"
anyhow = "1.0"
orion = "0.17"
uuid = { version = "1.11", features = ["serde"] }

24
migrations/2_users.sql Normal file
View file

@ -0,0 +1,24 @@
create extension "uuid-ossp";
create table users (
id uuid not null primary key default gen_random_uuid(),
created_at timestamptz not null default current_timestamp,
updated_at timestamptz,
username varchar(256) not null,
password varchar(512) not null,
enabled boolean not null default true
);
insert into users (id, username, password)
values ('00000000-0000-0000-0000-000000000000', 'legacy', '');
alter table doll_profiles
add column bound_to_id uuid not null
default '00000000-0000-0000-0000-000000000000'
references users (id)
on delete cascade;
alter table doll_profiles
alter column bound_to_id drop default;

1
src/auth/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod pw;

27
src/auth/pw.rs Normal file
View file

@ -0,0 +1,27 @@
use orion::{errors::UnknownCryptoError, pwhash};
// see guidelines on determining those values: https://doc.libsodium.org/password_hashing/default_phf#guidelines-for-choosing-the-parameters
// 3 password hash iterations
const ITERATIONS: u32 = 3;
// 64MB RAM allocated to a password hash
const MEMORY: u32 = 1 << 16;
// TODO: make those configurable through the .toml file
pub fn hash(input: &str) -> Result<String, UnknownCryptoError> {
let password = pwhash::Password::from_slice(input.as_bytes())?;
Ok(pwhash::hash_password(&password, ITERATIONS, MEMORY)?
.unprotected_as_encoded()
.to_string())
}
pub fn verify(input: &str, against: &str) -> Result<bool, UnknownCryptoError> {
if input.len() == 0 {
// disabled accounts
return Ok(false);
}
let password = pwhash::Password::from_slice(input.as_bytes())?;
let hash = pwhash::PasswordHash::from_encoded(against)?;
Ok(pwhash::hash_password_verify(&hash, &password).is_ok())
}

View file

@ -48,8 +48,8 @@ pub async fn create(mut db: DollTagsDb, doll: CreateDollProfile<'_>) -> sqlx::Re
sqlx::query!(
r#"
insert into doll_profiles
(id, microchip_id, name, pronoun_subject, pronoun_object, pronoun_possessive, handler_name, handler_link, kind, breed, behaviour, description, chassis_type, chassis_id, chassis_color)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
(id, microchip_id, name, pronoun_subject, pronoun_object, pronoun_possessive, handler_name, handler_link, kind, breed, behaviour, description, chassis_type, chassis_id, chassis_color, bound_to_id)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
"#,
doll.id,
doll.microchip_id,
@ -66,6 +66,7 @@ pub async fn create(mut db: DollTagsDb, doll: CreateDollProfile<'_>) -> sqlx::Re
doll.chassis_type,
doll.chassis_id,
doll.chassis_color,
doll.bound_to_id,
).execute(&mut **db).await?;
Ok(())

View file

@ -1,7 +1,7 @@
use ::chrono::Utc;
use rocket::serde::Serialize;
use rocket_db_pools::{Connection, Database};
use sqlx::types::chrono;
use sqlx::types::{chrono, Uuid};
#[derive(Database)]
#[database("dolltags")]
@ -17,6 +17,8 @@ pub struct DollProfile {
pub created_at: chrono::DateTime<Utc>,
pub updated_at: Option<chrono::DateTime<Utc>>,
pub bound_to_id: Uuid,
pub name: String,
pub pronoun_subject: String,
pub pronoun_object: String,
@ -48,6 +50,7 @@ impl DollProfile {
pub struct CreateDollProfile<'a> {
pub id: i32,
pub microchip_id: Option<&'a str>,
pub bound_to_id: &'a Uuid,
pub name: &'a str,
pub pronoun_subject: &'a str,

View file

@ -12,6 +12,7 @@ use rocket_dyn_templates::Template;
use routes::{error_handlers, form, public};
use serde_json::{to_value, Value};
pub mod auth;
pub mod db;
pub mod ids;
pub mod routes;

View file

@ -3,6 +3,7 @@ use rocket::{
response::Redirect,
};
use rocket_dyn_templates::{context, Template};
use uuid::uuid;
use crate::{
db::{
@ -148,6 +149,7 @@ pub async fn handle_register(
chassis_type: normalize_opt(tag.chassis_type),
chassis_id: normalize_opt(tag.chassis_id),
chassis_color: normalize_opt(tag.chassis_color),
bound_to_id: &uuid!("00000000-0000-0000-0000-000000000000"), // TODO: remove once accounts exist
},
)
.await?;