diff options
Diffstat (limited to 'server/src/routes/ui/admin')
| -rw-r--r-- | server/src/routes/ui/admin/mod.rs | 34 | ||||
| -rw-r--r-- | server/src/routes/ui/admin/user.rs | 98 | 
2 files changed, 102 insertions, 30 deletions
| diff --git a/server/src/routes/ui/admin/mod.rs b/server/src/routes/ui/admin/mod.rs index c6a89ca..0d1ee0a 100644 --- a/server/src/routes/ui/admin/mod.rs +++ b/server/src/routes/ui/admin/mod.rs @@ -4,6 +4,7 @@      Copyright (C) 2023 metamuffin <metamuffin.org>  */  pub mod log; +pub mod user;  use super::account::session::AdminSession;  use crate::{ @@ -22,6 +23,7 @@ use jellybase::CONF;  use rand::Rng;  use rocket::{form::Form, get, post, FromForm, State};  use std::time::Instant; +use user::rocket_uri_macro_r_admin_users;  #[get("/admin/dashboard")]  pub fn r_admin_dashboard( @@ -35,8 +37,6 @@ pub fn admin_dashboard<'a>(      database: &Database,      flash: Option<MyResult<String>>,  ) -> MyResult<DynLayoutPage<'a>> { -    // TODO this doesnt scale, pagination! -    let users = database.user.iter().collect::<Result<Vec<_>, _>>()?;      let invites = database.invite.iter().collect::<Result<Vec<_>, _>>()?;      let flash = flash.map(|f| f.map_err(|e| format!("{e:?}"))); @@ -56,6 +56,8 @@ pub fn admin_dashboard<'a>(              form[method="POST", action=uri!(r_admin_delete_cache())] {                  input[type="submit", value="Delete Cache"];              } +            h2 { "Users" } +            p { a[href=uri!(r_admin_users())] "Manage Users" }              h2 { "Invitations" }              form[method="POST", action=uri!(r_admin_invite())] {                  input[type="submit", value="Generate new invite code"]; @@ -69,14 +71,6 @@ pub fn admin_dashboard<'a>(                      }                  }              }} -            h2 { "Users" } -            ul { @for (_, u) in &users { -                li { form[method="POST", action=uri!(r_admin_remove_user())] { -                    span { @format!("{:?}", u.display_name) " (" @u.name ")" } -                    input[type="text", name="name", value=&u.name, hidden]; -                    input[type="submit", value="Remove(!)"]; -                }} -            }}          },          ..Default::default()      }) @@ -94,26 +88,6 @@ pub fn r_admin_invite(  }  #[derive(FromForm)] -pub struct DeleteUser { -    name: String, -} - -#[post("/admin/remove_user", data = "<form>")] -pub fn r_admin_remove_user( -    session: AdminSession, -    database: &State<Database>, -    form: Form<DeleteUser>, -) -> MyResult<DynLayoutPage<'static>> { -    drop(session); -    database -        .user -        .remove(&form.name)? -        .ok_or(anyhow!("user did not exist"))?; - -    admin_dashboard(database, Some(Ok("User removed".into()))) -} - -#[derive(FromForm)]  pub struct DeleteInvite {      invite: String,  } diff --git a/server/src/routes/ui/admin/user.rs b/server/src/routes/ui/admin/user.rs new file mode 100644 index 0000000..9868343 --- /dev/null +++ b/server/src/routes/ui/admin/user.rs @@ -0,0 +1,98 @@ +use crate::{ +    database::Database, +    routes::ui::{ +        account::session::AdminSession, +        error::MyResult, +        layout::{DynLayoutPage, FlashDisplay, LayoutPage}, +    }, +    uri, +}; +use anyhow::anyhow; +use rocket::{form::Form, get, post, FromForm, State}; + +#[get("/admin/users")] +pub fn r_admin_users( +    _session: AdminSession, +    database: &State<Database>, +) -> MyResult<DynLayoutPage<'static>> { +    user_management(database, None) +} + +fn user_management<'a>( +    database: &Database, +    flash: Option<MyResult<String>>, +) -> MyResult<DynLayoutPage<'a>> { +    // TODO this doesnt scale, pagination! +    let users = database.user.iter().collect::<Result<Vec<_>, _>>()?; +    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/<name>")] +pub fn r_admin_user<'a>( +    _session: AdminSession, +    database: &State<Database>, +    name: &'a str, +) -> MyResult<DynLayoutPage<'a>> { +    manage_single_user(database, None, name) +} + +fn manage_single_user<'a>( +    database: &Database, +    flash: Option<MyResult<String>>, +    name: &'a str, +) -> MyResult<DynLayoutPage<'a>> { +    // TODO this doesnt scale, pagination! +    let user = database +        .user +        .get(&name.to_string())? +        .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! { +            h1 { "Manage User" } +            @FlashDisplay { flash: flash.clone() } +            h2 { @format!("{:?}", user.display_name) " (" @user.name ")" } +            form[method="POST", action=uri!(r_admin_remove_user())] { +                input[type="text", name="name", value=&user.name, hidden]; +                input[type="submit", value="Remove(!)"]; +            } +        }, +        ..Default::default() +    }) +} + +#[derive(FromForm)] +pub struct DeleteUser { +    name: String, +} + +#[post("/admin/remove_user", data = "<form>")] +pub fn r_admin_remove_user( +    session: AdminSession, +    database: &State<Database>, +    form: Form<DeleteUser>, +) -> MyResult<DynLayoutPage<'static>> { +    drop(session); +    database +        .user +        .remove(&form.name)? +        .ok_or(anyhow!("user did not exist"))?; +    user_management(database, Some(Ok("User removed".into()))) +} | 
