/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ use crate::{database::Database, ui::error::MyResult}; use anyhow::{anyhow, Context}; use jellycommon::user::UserPermission; use jellylogic::session::AdminSession; use rocket::{form::Form, get, post, FromForm, FromFormField, State}; #[get("/admin/users")] pub fn r_admin_users( _session: AdminSession, database: &State, ) -> MyResult> { user_management(database, None) } fn user_management<'a>( database: &Database, flash: Option>, ) -> MyResult> { // TODO this doesnt scale, pagination! let users = database.list_users()?; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); Ok(LayoutPage { title: "User management".to_string(), content: markup::new! { h1 { "User Management" } @FlashDisplay { flash: flash.clone() } h2 { "All Users" } ul { @for u in &users { li { a[href=uri!(r_admin_user(&u.name))] { @format!("{:?}", u.display_name) " (" @u.name ")" } } }} }, ..Default::default() }) } #[get("/admin/user/")] pub fn r_admin_user<'a>( _session: AdminSession, database: &State, name: &'a str, ) -> MyResult> { manage_single_user(database, None, name.to_string()) } fn manage_single_user<'a>( database: &Database, flash: Option>, name: String, ) -> MyResult> { let user = database .get_user(&name)? .ok_or(anyhow!("user does not exist"))?; let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); Ok(LayoutPage { title: "User management".to_string(), content: markup::new! {}, ..Default::default() }) } #[derive(FromForm)] pub struct UserPermissionForm { permission: String, action: GrantState, } #[derive(FromFormField)] pub enum GrantState { Grant, Revoke, Unset, } #[post("/admin/user//update_permission", data = "
")] pub fn r_admin_user_permission( session: AdminSession, database: &State, form: Form, name: &str, ) -> MyResult> { drop(session); let perm = serde_json::from_str::(&form.permission) .context("parsing provided permission")?; database.update_user(&form.name, |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)), } Ok(()) })?; manage_single_user( database, Some(Ok("Permissions update".into())), form.name.clone(), ) } #[post("/admin//remove")] pub fn r_admin_remove_user( session: AdminSession, database: &State, name: &str, ) -> MyResult> { drop(session); if !database.delete_user(&name)? { Err(anyhow!("user did not exist"))?; } user_management(database, Some(Ok("User removed".into()))) }