From d004a7047b7fc8a68d6c03baca4581ba8d2b0d4d Mon Sep 17 00:00:00 2001 From: GrO2Bl Date: Wed, 12 Jun 2024 20:24:43 +0330 Subject: [PATCH] Add an admin inclusive request guard #1156 --- plume-models/src/admin.rs | 19 ++++++++++++++++++- src/routes/instance.rs | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/plume-models/src/admin.rs b/plume-models/src/admin.rs index a4fa0455..37a34584 100644 --- a/plume-models/src/admin.rs +++ b/plume-models/src/admin.rs @@ -5,7 +5,7 @@ use rocket::{ Outcome, }; -/// Wrapper around User to use as a request guard on pages reserved to admins. +/// Wrapper around User to use as a request guard on pages exclusively reserved to admins. pub struct Admin(pub User); impl<'a, 'r> FromRequest<'a, 'r> for Admin { @@ -21,6 +21,23 @@ impl<'a, 'r> FromRequest<'a, 'r> for Admin { } } +/// Same as `Admin` but it forwards to next guard if the user is not an admin. +/// It's useful when there are multiple implementations of routes for admin and moderator. +pub struct InclusiveAdmin(pub User); + +impl<'a, 'r> FromRequest<'a, 'r> for InclusiveAdmin { + type Error = (); + + fn from_request(request: &'a Request<'r>) -> request::Outcome { + let user = request.guard::()?; + if user.is_admin() { + Outcome::Success(InclusiveAdmin(user)) + } else { + Outcome::Forward(()) + } + } +} + /// Same as `Admin` but for moderators. pub struct Moderator(pub User); diff --git a/src/routes/instance.rs b/src/routes/instance.rs index 9de9fee0..e05e069c 100644 --- a/src/routes/instance.rs +++ b/src/routes/instance.rs @@ -51,7 +51,7 @@ pub fn index(conn: DbConn, rockets: PlumeRocket) -> Result { } #[get("/admin")] -pub fn admin(_admin: Admin, conn: DbConn, rockets: PlumeRocket) -> Result { +pub fn admin(_admin: InclusiveAdmin, conn: DbConn, rockets: PlumeRocket) -> Result { let local_inst = Instance::get_local()?; Ok(render!(instance::admin( &(&conn, &rockets).to_context(),