diff options
author | metamuffin <metamuffin@disroot.org> | 2024-01-20 00:50:20 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-01-20 00:50:20 +0100 |
commit | 46c251655db7bb3d9aa814b1a5dde85336b0b9b1 (patch) | |
tree | ab0696f2c92e8854ce6aa0737877cc15184bd8b6 /server/src/routes/ui/account | |
parent | 1c37d32a0985ff7390313833345b9299f9f0b196 (diff) | |
download | jellything-46c251655db7bb3d9aa814b1a5dde85336b0b9b1.tar jellything-46c251655db7bb3d9aa814b1a5dde85336b0b9b1.tar.bz2 jellything-46c251655db7bb3d9aa814b1a5dde85336b0b9b1.tar.zst |
replace sled with redb
Diffstat (limited to 'server/src/routes/ui/account')
-rw-r--r-- | server/src/routes/ui/account/mod.rs | 71 | ||||
-rw-r--r-- | server/src/routes/ui/account/session/guard.rs | 18 | ||||
-rw-r--r-- | server/src/routes/ui/account/settings.rs | 53 |
3 files changed, 88 insertions, 54 deletions
diff --git a/server/src/routes/ui/account/mod.rs b/server/src/routes/ui/account/mod.rs index cd8695f..8af92a0 100644 --- a/server/src/routes/ui/account/mod.rs +++ b/server/src/routes/ui/account/mod.rs @@ -8,7 +8,7 @@ pub mod settings; use super::{error::MyError, layout::LayoutPage}; use crate::{ - database::Database, + database::DataAcid, routes::ui::{ account::session::Session, error::MyResult, home::rocket_uri_macro_r_home, layout::DynLayoutPage, @@ -18,7 +18,10 @@ use crate::{ use anyhow::anyhow; use argon2::{password_hash::Salt, Argon2, PasswordHasher}; use chrono::Duration; -use jellybase::CONF; +use jellybase::{ + database::{Ser, TableExt, T_INVITE, T_USER}, + CONF, +}; use jellycommon::user::{PermissionSet, Theme, User, UserPermission}; use rocket::{ form::{Contextual, Form}, @@ -121,7 +124,7 @@ pub fn r_account_logout() -> DynLayoutPage<'static> { #[post("/account/register", data = "<form>")] pub fn r_account_register_post<'a>( - database: &'a State<Database>, + database: &'a State<DataAcid>, _sess: Option<Session>, form: Form<Contextual<'a, RegisterForm>>, ) -> MyResult<DynLayoutPage<'a>> { @@ -131,15 +134,17 @@ pub fn r_account_register_post<'a>( None => return Err(format_form_error(form)), }; - if database.invite.remove(&form.invitation).unwrap().is_none() { - return Err(MyError(anyhow!("invitation invalid"))); + let txn = database.begin_write()?; + let mut invites = txn.open_table(T_INVITE)?; + let mut users = txn.open_table(T_USER)?; + + if invites.remove(&*form.invitation)?.is_none() { + Err(anyhow!("invitation invalid"))?; } - match database - .user - .compare_and_swap( - &form.username, - None, - Some(&User { + let prev_user = users + .insert( + &*form.username, + Ser(User { display_name: form.username.clone(), name: form.username.clone(), password: hash_password(&form.username, &form.password), @@ -147,27 +152,32 @@ pub fn r_account_register_post<'a>( theme: Theme::Dark, permissions: PermissionSet::default(), }), - ) - .unwrap() - { - Ok(_) => Ok(LayoutPage { - title: "Registration successful".to_string(), - content: markup::new! { - h1 { @if logged_in { - "Registration successful, you may switch account now." - } else { - "Registration successful, you may log in now." - }} - }, - ..Default::default() - }), - Err(_) => Err(MyError(anyhow!("username is taken"))), + )? + .map(|x| x.value().0); + if prev_user.is_some() { + Err(anyhow!("username taken"))?; } + + drop(users); + drop(invites); + txn.commit()?; + + Ok(LayoutPage { + title: "Registration successful".to_string(), + content: markup::new! { + h1 { @if logged_in { + "Registration successful, you may switch account now." + } else { + "Registration successful, you may log in now." + }} + }, + ..Default::default() + }) } #[post("/account/login", data = "<form>")] pub fn r_account_login_post( - database: &State<Database>, + database: &State<DataAcid>, jar: &CookieJar, form: Form<Contextual<LoginForm>>, ) -> MyResult<Redirect> { @@ -194,7 +204,7 @@ pub fn r_account_logout_post(jar: &CookieJar) -> MyResult<Redirect> { } pub fn login_logic( - database: &Database, + database: &DataAcid, username: &str, password: &str, expire: Option<i64>, @@ -203,9 +213,8 @@ pub fn login_logic( // hashing the password regardless if the accounts exists to prevent timing attacks let password = hash_password(username, password); - let mut user = database - .user - .get(&username.to_string())? + let mut user = T_USER + .get(database, username)? .ok_or(anyhow!("invalid password"))?; if user.password != password { diff --git a/server/src/routes/ui/account/session/guard.rs b/server/src/routes/ui/account/session/guard.rs index ae1ebd3..b2fd408 100644 --- a/server/src/routes/ui/account/session/guard.rs +++ b/server/src/routes/ui/account/session/guard.rs @@ -4,8 +4,9 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use super::{AdminSession, Session}; -use crate::{database::Database, routes::ui::error::MyError}; +use crate::{database::DataAcid, routes::ui::error::MyError}; use anyhow::anyhow; +use jellybase::database::{ReadableTable, T_USER}; use log::warn; use rocket::{ async_trait, @@ -35,8 +36,19 @@ impl Session { username = "admin".to_string(); } - let db = req.guard::<&State<Database>>().await.unwrap(); - let user = db.user.get(&username)?.ok_or(anyhow!("user not found"))?; + let db = req.guard::<&State<DataAcid>>().await.unwrap(); + + let user = { + let txn = db.inner.begin_read()?; + let table = txn.open_table(T_USER)?; + let user = table + .get(&*username)? + .ok_or(anyhow!("user not found"))? + .value() + .0; + drop(table); + user + }; Ok(Session { user }) } diff --git a/server/src/routes/ui/account/settings.rs b/server/src/routes/ui/account/settings.rs index f14478b..ecc0723 100644 --- a/server/src/routes/ui/account/settings.rs +++ b/server/src/routes/ui/account/settings.rs @@ -5,7 +5,7 @@ */ use super::{format_form_error, hash_password}; use crate::{ - database::Database, + database::DataAcid, routes::ui::{ account::{rocket_uri_macro_r_account_login, session::Session}, error::MyResult, @@ -13,7 +13,11 @@ use crate::{ }, uri, }; -use jellybase::permission::PermissionSetExt; +use anyhow::anyhow; +use jellybase::{ + database::{ReadableTable, Ser, T_USER}, + permission::PermissionSetExt, +}; use jellycommon::user::{Theme, UserPermission}; use markup::{Render, RenderAttributeValue}; use rocket::{ @@ -97,7 +101,7 @@ pub fn r_account_settings(session: Session) -> DynLayoutPage<'static> { #[post("/account/settings", data = "<form>")] pub fn r_account_settings_post( session: Session, - database: &State<Database>, + database: &State<DataAcid>, form: Form<Contextual<SettingsForm>>, ) -> MyResult<DynLayoutPage<'static>> { session @@ -111,23 +115,32 @@ pub fn r_account_settings_post( }; let mut out = String::new(); - database.user.fetch_and_update(&session.user.name, |k| { - k.map(|mut k| { - if let Some(password) = &form.password { - k.password = hash_password(&session.user.name, password); - out += "Password updated\n"; - } - if let Some(display_name) = &form.display_name { - k.display_name = display_name.clone(); - out += "Display name updated\n"; - } - if let Some(theme) = form.theme { - k.theme = theme; - out += "Theme updated\n"; - } - k - }) - })?; + + let txn = database.begin_write()?; + let mut users = txn.open_table(T_USER)?; + + let mut user = users + .get(&*session.user.name)? + .ok_or(anyhow!("user missing"))? + .value() + .0; + + if let Some(password) = &form.password { + user.password = hash_password(&session.user.name, password); + out += "Password updated\n"; + } + if let Some(display_name) = &form.display_name { + user.display_name = display_name.clone(); + out += "Display name updated\n"; + } + if let Some(theme) = form.theme { + user.theme = theme; + out += "Theme updated\n"; + } + + users.insert(&*session.user.name, Ser(user))?; + drop(users); + txn.commit()?; Ok(settings_page( session, // using the old session here, results in outdated theme being displayed |