diff options
Diffstat (limited to 'server/src/routes/ui/admin')
-rw-r--r-- | server/src/routes/ui/admin/mod.rs | 45 | ||||
-rw-r--r-- | server/src/routes/ui/admin/user.rs | 70 |
2 files changed, 73 insertions, 42 deletions
diff --git a/server/src/routes/ui/admin/mod.rs b/server/src/routes/ui/admin/mod.rs index b976192..60ed416 100644 --- a/server/src/routes/ui/admin/mod.rs +++ b/server/src/routes/ui/admin/mod.rs @@ -8,7 +8,7 @@ pub mod user; use super::account::session::AdminSession; use crate::{ - database::Database, + database::DataAcid, routes::ui::{ admin::log::rocket_uri_macro_r_admin_log, error::MyResult, @@ -17,7 +17,11 @@ use crate::{ uri, }; use anyhow::anyhow; -use jellybase::{federation::Federation, CONF}; +use jellybase::{ + database::{ReadableTable, TableExt, T_INVITE}, + federation::Federation, + CONF, +}; use jellyimport::import; use rand::Rng; use rocket::{form::Form, get, post, FromForm, State}; @@ -27,16 +31,28 @@ use user::rocket_uri_macro_r_admin_users; #[get("/admin/dashboard")] pub fn r_admin_dashboard( _session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, ) -> MyResult<DynLayoutPage<'static>> { admin_dashboard(database, None) } pub fn admin_dashboard<'a>( - database: &Database, + database: &DataAcid, flash: Option<MyResult<String>>, ) -> MyResult<DynLayoutPage<'a>> { - let invites = database.invite.iter().collect::<Result<Vec<_>, _>>()?; + let invites = { + let txn = database.begin_read()?; + let table = txn.open_table(T_INVITE)?; + let i = table + .iter()? + .map(|a| { + let (x, _) = a.unwrap(); + x.value().to_owned() + }) + .collect::<Vec<_>>(); + drop(table); + i + }; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); Ok(LayoutPage { @@ -64,8 +80,8 @@ pub fn admin_dashboard<'a>( ul { @for t in &invites { li { form[method="POST", action=uri!(r_admin_remove_invite())] { - span { @t.0 } - input[type="text", name="invite", value=&t.0, hidden]; + span { @t } + input[type="text", name="invite", value=&t, hidden]; input[type="submit", value="Invalidate"]; } } @@ -78,10 +94,10 @@ pub fn admin_dashboard<'a>( #[post("/admin/generate_invite")] pub fn r_admin_invite( _session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, ) -> MyResult<DynLayoutPage<'static>> { let i = format!("{}", rand::thread_rng().gen::<u128>()); - database.invite.insert(&i, &())?; + T_INVITE.insert(&database, &*i, ())?; admin_dashboard(database, Some(Ok(format!("Invite: {}", i)))) } @@ -94,13 +110,12 @@ pub struct DeleteInvite { #[post("/admin/remove_invite", data = "<form>")] pub fn r_admin_remove_invite( session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, form: Form<DeleteInvite>, ) -> MyResult<DynLayoutPage<'static>> { drop(session); - database - .invite - .remove(&form.invite)? + T_INVITE + .remove(&database, form.invite.as_str())? .ok_or(anyhow!("invite did not exist"))?; admin_dashboard(database, Some(Ok("Invite invalidated".into()))) @@ -109,7 +124,7 @@ pub fn r_admin_remove_invite( #[post("/admin/import")] pub async fn r_admin_import( session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, federation: &State<Federation>, ) -> MyResult<DynLayoutPage<'static>> { drop(session); @@ -127,7 +142,7 @@ pub async fn r_admin_import( #[post("/admin/delete_cache")] pub async fn r_admin_delete_cache( session: AdminSession, - database: &State<Database>, + database: &State<DataAcid>, ) -> MyResult<DynLayoutPage<'static>> { drop(session); let t = Instant::now(); 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()))) } |