diff options
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/routes/mod.rs | 3 | ||||
-rw-r--r-- | server/src/routes/ui/admin/user.rs | 92 |
2 files changed, 88 insertions, 7 deletions
diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index cb7d90f..48fdf96 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -25,7 +25,7 @@ use ui::{ log::r_admin_log, r_admin_dashboard, r_admin_delete_cache, r_admin_import, r_admin_invite, r_admin_remove_invite, - user::{r_admin_remove_user, r_admin_user, r_admin_users}, + user::{r_admin_remove_user, r_admin_user, r_admin_user_permission, r_admin_users}, }, assets::r_item_assets, browser::r_all_items_filter, @@ -104,6 +104,7 @@ pub fn build_rocket(database: Database, federation: Federation) -> Rocket<Build> r_admin_user, r_admin_users, r_admin_remove_invite, + r_admin_user_permission, r_admin_import, r_admin_delete_cache, r_admin_log, diff --git a/server/src/routes/ui/admin/user.rs b/server/src/routes/ui/admin/user.rs index 9868343..e61ec45 100644 --- a/server/src/routes/ui/admin/user.rs +++ b/server/src/routes/ui/admin/user.rs @@ -7,8 +7,9 @@ use crate::{ }, uri, }; -use anyhow::anyhow; -use rocket::{form::Form, get, post, FromForm, State}; +use anyhow::{anyhow, Context}; +use jellycommon::user::{PermissionSet, UserPermission}; +use rocket::{form::Form, get, post, FromForm, FromFormField, State}; #[get("/admin/users")] pub fn r_admin_users( @@ -48,18 +49,17 @@ pub fn r_admin_user<'a>( database: &State<Database>, name: &'a str, ) -> MyResult<DynLayoutPage<'a>> { - manage_single_user(database, None, name) + manage_single_user(database, None, name.to_string()) } fn manage_single_user<'a>( database: &Database, flash: Option<MyResult<String>>, - name: &'a str, + name: String, ) -> MyResult<DynLayoutPage<'a>> { - // TODO this doesnt scale, pagination! let user = database .user - .get(&name.to_string())? + .get(&name)? .ok_or(anyhow!("user does not exist"))?; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); @@ -73,15 +73,95 @@ fn manage_single_user<'a>( input[type="text", name="name", value=&user.name, hidden]; input[type="submit", value="Remove(!)"]; } + + h3 { "Permissions" } + @PermissionDisplay { perms: &user.permissions } + + form[method="POST", action=uri!(r_admin_user_permission())] { + input[type="text", name="name", value=&user.name, hidden]; + fieldset.perms { + legend { "Permission" } + @for p in UserPermission::ALL_ENUMERABLE { + label { + input[type="radio", name="permission", value=serde_json::to_string(p).unwrap()]; + @format!("{p}") + } br; + } + } + fieldset.perms { + legend { "Permission" } + label { input[type="radio", name="action", value="unset"]; "Unset" } + label { input[type="radio", name="action", value="grant"]; "Grant" } + label { input[type="radio", name="action", value="revoke"]; "Revoke" } + } + input[type="submit", value="Update"]; + } + }, ..Default::default() }) } +markup::define! { + PermissionDisplay<'a>(perms: &'a PermissionSet) { + ul { @for (perm,grant) in &perms.0 { + @if *grant { + li[class="perm-grant"] { @format!("Allow {}", perm) } + } else { + li[class="perm-revoke"] { @format!("Deny {}", perm) } + } + }} + } +} + #[derive(FromForm)] pub struct DeleteUser { name: String, } +#[derive(FromForm)] +pub struct UserPermissionForm { + name: String, + permission: String, + action: GrantState, +} + +#[derive(FromFormField)] +pub enum GrantState { + Grant, + Revoke, + Unset, +} + +#[post("/admin/update_user_permission", data = "<form>")] +pub fn r_admin_user_permission( + session: AdminSession, + database: &State<Database>, + 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"))?; + + manage_single_user( + database, + Some(Ok("Permissions update".into())), + form.name.clone(), + ) +} #[post("/admin/remove_user", data = "<form>")] pub fn r_admin_remove_user( |