From d933dadf62807759cdf7f899a695f76c49e6f8c5 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 15 May 2021 09:10:39 +0200 Subject: [PATCH] Can update admin roles --- .../admin/admin_roles_controller.rs | 25 ++++++++++++++++++- src/data/base_request_handler.rs | 12 ++++++++- src/helpers/admin_roles_helper.rs | 19 ++++++++++++-- src/helpers/database.rs | 12 ++++++++- src/routes.rs | 3 ++- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/controllers/admin/admin_roles_controller.rs b/src/controllers/admin/admin_roles_controller.rs index 5a1d0c3..a8c427f 100644 --- a/src/controllers/admin/admin_roles_controller.rs +++ b/src/controllers/admin/admin_roles_controller.rs @@ -3,15 +3,38 @@ //! @author Pierre Hubert use crate::api_data::admin::admin_role_api::AdminRoleDetailsAPI; -use crate::constants::admin::ADMIN_ROLES_LIST; +use crate::constants::admin::{ADMIN_ROLES_LIST, AdminRole}; use crate::data::base_request_handler::BaseRequestHandler; use crate::data::http_request_handler::HttpRequestHandler; +use crate::helpers::admin_roles_helper; use crate::routes::RequestResult; +/// Get the list of roles embedded in the code pub fn get_list(r: &mut HttpRequestHandler) -> RequestResult { let res = ADMIN_ROLES_LIST.iter() .map(AdminRoleDetailsAPI::new) .collect::>(); r.set_response(res) +} + +/// Toggle the status of a role for an admin +pub fn toggle(r: &mut HttpRequestHandler) -> RequestResult { + r.check_admin_has_role(AdminRole::MANAGE_ADMINS)?; + + let admin_id = r.post_admin_id("adminID")?; + let enable = r.post_bool("enable")?; + let role_str = r.post_string("role")?; + let role = r.some_or_bad_request( + AdminRole::from_id(&role_str), + "Specified role does not exists!", + )?; + + if !enable { + admin_roles_helper::remove_role(admin_id, role)?; + } else if !admin_roles_helper::has_role(admin_id, role)? { + admin_roles_helper::add_role(admin_id, role)?; + } + + r.ok() } \ No newline at end of file diff --git a/src/data/base_request_handler.rs b/src/data/base_request_handler.rs index c2c68c9..e84cc25 100644 --- a/src/data/base_request_handler.rs +++ b/src/data/base_request_handler.rs @@ -12,6 +12,7 @@ use image::{GenericImageView, ImageFormat}; use serde::Serialize; use crate::api_data::http_error::HttpError; +use crate::constants::admin::AdminRole; use crate::constants::PASSWORD_MIN_LENGTH; use crate::data::admin::AdminID; use crate::data::comment::Comment; @@ -24,7 +25,7 @@ use crate::data::group_id::GroupID; use crate::data::post::{Post, PostAccessLevel}; use crate::data::user::UserID; use crate::data::user_token::UserAccessToken; -use crate::helpers::{account_helper, admin_account_helper, comments_helper, conversations_helper, custom_emojies_helper, friends_helper, groups_helper, posts_helper, user_helper, virtual_directory_helper}; +use crate::helpers::{account_helper, admin_account_helper, admin_roles_helper, comments_helper, conversations_helper, custom_emojies_helper, friends_helper, groups_helper, posts_helper, user_helper, virtual_directory_helper}; use crate::helpers::virtual_directory_helper::VirtualDirType; use crate::routes::RequestResult; use crate::utils::mp3_utils::is_valid_mp3; @@ -606,6 +607,15 @@ pub trait BaseRequestHandler { Ok(admin_id) } + /// Check if an admin has a given role or not + fn check_admin_has_role(&mut self, role: AdminRole) -> Res { + if !admin_roles_helper::has_role(self.admin_id()?, role)? { + self.forbidden("You have not the permission to do this!".to_string())?; + } + + Ok(()) + } + /// Get a list of users ID included in the request fn post_users_id(&mut self, name: &str) -> ResultBoxError> { let users = self.post_numbers_list(name, 1)? diff --git a/src/helpers/admin_roles_helper.rs b/src/helpers/admin_roles_helper.rs index 03e7ff6..296171b 100644 --- a/src/helpers/admin_roles_helper.rs +++ b/src/helpers/admin_roles_helper.rs @@ -12,11 +12,11 @@ use crate::utils::date_utils::time; /// Get the list of roles of a given administrator pub fn get_roles(id: AdminID) -> Res> { database::QueryInfo::new(ADMIN_ROLES_TABLE) - .cond_admin_id("id", id) + .cond_admin_id("admin_id", id) .exec(db_to_role) } -/// Add a new role to a user +/// Add a new role to an admin pub fn add_role(id: AdminID, role: AdminRole) -> Res { database::InsertQuery::new(ADMIN_ROLES_TABLE) .add_admin_id("admin_id", id) @@ -25,6 +25,21 @@ pub fn add_role(id: AdminID, role: AdminRole) -> Res { .insert_drop_result() } +/// Remove a role to an admin +pub fn remove_role(id: AdminID, role: AdminRole) -> Res { + database::DeleteQuery::new(ADMIN_ROLES_TABLE) + .cond_admin_id("admin_id", id) + .cond_str("role_id", role.to_id()) + .exec() +} +/// Check out whether an admin has a role or not +pub fn has_role(id: AdminID, role: AdminRole) -> Res { + database::QueryInfo::new(ADMIN_ROLES_TABLE) + .cond_admin_id("admin_id", id) + .cond("role_id", role.to_id()) + .exec_count_has_at_least_one_result() +} + fn db_to_role(row: &database::RowResult) -> Res { let role_id = row.get_str("role_id")?; diff --git a/src/helpers/database.rs b/src/helpers/database.rs index 0188301..35d1668 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -11,7 +11,7 @@ use mysql::prelude::Queryable; use crate::data::admin::AdminID; use crate::data::config::{conf, DatabaseConfig}; use crate::data::conversation::ConvID; -use crate::data::error::{ExecError, ResultBoxError}; +use crate::data::error::{ExecError, Res, ResultBoxError}; use crate::data::group_id::GroupID; use crate::data::user::UserID; @@ -272,6 +272,11 @@ impl QueryInfo { pub fn exec_count(self) -> ResultBoxError { count(self) } + + /// Execute count query, checking that there is at least one result + pub fn exec_count_has_at_least_one_result(self) -> Res { + self.exec_count().map(|r| r > 0) + } } /// Struct used to read the result of a request @@ -841,6 +846,11 @@ impl DeleteQuery { self } + pub fn cond_admin_id(mut self, key: &str, value: AdminID) -> DeleteQuery { + self.conditions.insert(key.to_string(), Value::from(value.id())); + self + } + pub fn cond_group_id(mut self, key: &str, value: &GroupID) -> DeleteQuery { self.conditions.insert(key.to_string(), Value::from(value.id())); self diff --git a/src/routes.rs b/src/routes.rs index 7fb3fe1..24da3b6 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -364,6 +364,7 @@ pub fn get_routes() -> Vec { Route::limited_admin_post_without_login("/admin/keys/auth_with_key", Box::new(admin_keys_controller::auth_with_key), LimitPolicy::ANY(10)), // Admin roles controller - Route::admin_post("/admin/roles/list", Box::new(admin_roles_controller::get_list)) + Route::admin_post("/admin/roles/list", Box::new(admin_roles_controller::get_list)), + Route::admin_post("/admin/roles/toggle", Box::new(admin_roles_controller::toggle)), ] } \ No newline at end of file