diff options
Diffstat (limited to 'server/src/routes/ui/admin/user.rs')
-rw-r--r-- | server/src/routes/ui/admin/user.rs | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/server/src/routes/ui/admin/user.rs b/server/src/routes/ui/admin/user.rs index 5c2c737..7d619c0 100644 --- a/server/src/routes/ui/admin/user.rs +++ b/server/src/routes/ui/admin/user.rs @@ -4,7 +4,7 @@ Copyright (C) 2023 metamuffin <metamuffin.org> */ use crate::{ - database::Database, + database::DataAcid, routes::ui::{ account::session::AdminSession, error::MyResult, @@ -13,23 +13,36 @@ use crate::{ uri, }; use anyhow::{anyhow, Context}; +use jellybase::database::{ReadableTable, Ser, TableExt, T_USER}; use jellycommon::user::{PermissionSet, UserPermission}; use rocket::{form::Form, get, post, FromForm, FromFormField, State}; #[get("/admin/users")] pub fn r_admin_users( _session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, ) -> MyResult<DynLayoutPage<'static>> { user_management(database, None) } fn user_management<'a>( - database: &Database, + database: &DataAcid, flash: Option<MyResult<String>>, ) -> MyResult<DynLayoutPage<'a>> { // TODO this doesnt scale, pagination! - let users = database.user.iter().collect::<Result<Vec<_>, _>>()?; + let users = { + let txn = database.begin_read()?; + let table = txn.open_table(T_USER)?; + let i = table + .iter()? + .map(|a| { + let (x, y) = a.unwrap(); + (x.value().to_owned(), y.value().0) + }) + .collect::<Vec<_>>(); + drop(table); + i + }; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); Ok(LayoutPage { @@ -51,20 +64,19 @@ fn user_management<'a>( #[get("/admin/user/<name>")] pub fn r_admin_user<'a>( _session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, name: &'a str, ) -> MyResult<DynLayoutPage<'a>> { manage_single_user(database, None, name.to_string()) } fn manage_single_user<'a>( - database: &Database, + database: &DataAcid, flash: Option<MyResult<String>>, name: String, ) -> MyResult<DynLayoutPage<'a>> { - let user = database - .user - .get(&name)? + let user = T_USER + .get(&database, &*name)? .ok_or(anyhow!("user does not exist"))?; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); @@ -140,26 +152,31 @@ pub enum GrantState { #[post("/admin/update_user_permission", data = "<form>")] pub fn r_admin_user_permission( session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, form: Form<UserPermissionForm>, ) -> MyResult<DynLayoutPage<'static>> { drop(session); let perm = serde_json::from_str::<UserPermission>(&form.permission) .context("parsing provided permission")?; - database - .user - .update_and_fetch(&form.name, |user| { - user.map(|mut user| { - match form.action { - GrantState::Grant => drop(user.permissions.0.insert(perm.clone(), true)), - GrantState::Revoke => drop(user.permissions.0.insert(perm.clone(), false)), - GrantState::Unset => drop(user.permissions.0.remove(&perm)), - } - user - }) - })? - .ok_or(anyhow!("user did not exist"))?; + let txn = database.begin_write()?; + let mut users = txn.open_table(T_USER)?; + + let mut user = users + .get(&*form.name)? + .ok_or(anyhow!("user missing"))? + .value() + .0; + + match form.action { + GrantState::Grant => drop(user.permissions.0.insert(perm.clone(), true)), + GrantState::Revoke => drop(user.permissions.0.insert(perm.clone(), false)), + GrantState::Unset => drop(user.permissions.0.remove(&perm)), + } + + users.insert(&*form.name, Ser(user))?; + drop(users); + txn.commit()?; manage_single_user( database, @@ -171,13 +188,12 @@ pub fn r_admin_user_permission( #[post("/admin/remove_user", data = "<form>")] pub fn r_admin_remove_user( session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, form: Form<DeleteUser>, ) -> MyResult<DynLayoutPage<'static>> { drop(session); - database - .user - .remove(&form.name)? + T_USER + .remove(&database, form.name.as_str())? .ok_or(anyhow!("user did not exist"))?; user_management(database, Some(Ok("User removed".into()))) } |