diff --git a/src/http_server/endpoints/moderation/ip_bans/list_ip_bans.rs b/src/http_server/endpoints/moderation/ip_bans/list_ip_bans.rs index d34a68d096..36aaef6854 100644 --- a/src/http_server/endpoints/moderation/ip_bans/list_ip_bans.rs +++ b/src/http_server/endpoints/moderation/ip_bans/list_ip_bans.rs @@ -25,11 +25,6 @@ use sqlx::error::Error::Database; use sqlx::mysql::MySqlDatabaseError; use std::sync::Arc; -#[derive(Deserialize)] -pub struct ListIpBansRequest { - delete: bool, -} - #[derive(Serialize)] pub struct ListIpBansResponse { pub success: bool, @@ -76,7 +71,6 @@ impl ResponseError for ListIpBansError { pub async fn list_ip_bans_handler( http_request: HttpRequest, - request: web::Json, server_state: web::Data> ) -> Result { diff --git a/src/http_server/endpoints/moderation/user_roles/list_mods.rs b/src/http_server/endpoints/moderation/user_roles/list_mods.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/http_server/endpoints/moderation/user_roles/list_roles.rs b/src/http_server/endpoints/moderation/user_roles/list_roles.rs index 46946eff9e..836f0b91bc 100644 --- a/src/http_server/endpoints/moderation/user_roles/list_roles.rs +++ b/src/http_server/endpoints/moderation/user_roles/list_roles.rs @@ -27,11 +27,6 @@ use sqlx::error::Error::Database; use sqlx::mysql::MySqlDatabaseError; use std::sync::Arc; -#[derive(Deserialize)] -pub struct ListUserRolesRequest { - delete: bool, -} - #[derive(Serialize)] pub struct ListUserRolesResponse { pub success: bool, @@ -67,7 +62,6 @@ impl ResponseError for ListUserRolesError { pub async fn list_user_roles_handler( http_request: HttpRequest, - request: web::Json, server_state: web::Data> ) -> Result { diff --git a/src/http_server/endpoints/moderation/user_roles/list_staff.rs b/src/http_server/endpoints/moderation/user_roles/list_staff.rs new file mode 100644 index 0000000000..3c21a63977 --- /dev/null +++ b/src/http_server/endpoints/moderation/user_roles/list_staff.rs @@ -0,0 +1,149 @@ +use actix_http::Error; +use actix_http::http::header; +use actix_web::cookie::Cookie; +use actix_web::dev::HttpResponseBuilder; +use actix_web::error::ResponseError; +use actix_web::http::StatusCode; +use actix_web::web::Path; +use actix_web::{Responder, web, HttpResponse, error, HttpRequest}; +use chrono::{DateTime, Utc}; +use crate::database_helpers::enums::{DownloadUrlType, CreatorSetVisibility, W2lTemplateType}; +use crate::http_server::web_utils::ip_address::get_request_ip; +use crate::http_server::web_utils::response_error_helpers::to_simple_json_error; +use crate::http_server::web_utils::response_success_helpers::simple_json_success; +use crate::server_state::ServerState; +use crate::util::random_prefix_crockford_token::random_prefix_crockford_token; +use crate::validations::check_for_slurs::contains_slurs; +use crate::validations::model_uploads::validate_model_title; +use crate::validations::passwords::validate_passwords; +use crate::validations::username::validate_username; +use derive_more::{Display, Error}; +use log::{info, warn, log}; +use regex::Regex; +use sqlx::error::DatabaseError; +use sqlx::error::Error::Database; +use sqlx::mysql::MySqlDatabaseError; +use std::sync::Arc; + + +#[derive(Serialize)] +pub struct ListStaffResponse { + pub success: bool, + pub staff: Vec, +} + +#[derive(Serialize)] +pub struct StaffRecordForList { + pub user_token: String, + pub username: String, + pub display_name: String, + pub user_role_slug: String, + pub user_role_name: String, +} + +#[derive(Debug, Display)] +pub enum ListStaffError { + BadInput(String), + ServerError, + Unauthorized, +} + +impl ResponseError for ListStaffError { + fn status_code(&self) -> StatusCode { + match *self { + ListStaffError::BadInput(_) => StatusCode::BAD_REQUEST, + ListStaffError::ServerError => StatusCode::INTERNAL_SERVER_ERROR, + ListStaffError::Unauthorized => StatusCode::UNAUTHORIZED, + } + } + + fn error_response(&self) -> HttpResponse { + let error_reason = match self { + ListStaffError::BadInput(reason) => reason.to_string(), + ListStaffError::ServerError => "server error".to_string(), + ListStaffError::Unauthorized => "unauthorized".to_string(), + }; + + to_simple_json_error(&error_reason, self.status_code()) + } +} + +pub async fn list_staff_handler( + http_request: HttpRequest, + server_state: web::Data> +) -> Result { + + let maybe_user_session = server_state + .session_checker + .maybe_get_user_session(&http_request, &server_state.mysql_pool) + .await + .map_err(|e| { + warn!("Session checker error: {:?}", e); + ListStaffError::ServerError + })?; + + let user_session = match maybe_user_session { + Some(session) => session, + None => { + warn!("not logged in"); + return Err(ListStaffError::Unauthorized); + } + }; + + // TODO: This is not the correct permission. + if !user_session.can_ban_users { + warn!("user is not allowed to delete bans: {}", user_session.user_token); + return Err(ListStaffError::Unauthorized); + } + + // NB: Lookup failure is Err(RowNotFound). + let maybe_results = sqlx::query_as!( + StaffRecordForList, + r#" +SELECT + users.token as user_token, + users.username, + users.display_name, + user_roles.slug as user_role_slug, + user_roles.name as user_role_name +FROM + users +JOIN user_roles + ON users.user_role_slug = user_roles.slug +WHERE + user_roles.slug != 'user' + "#, + ) + .fetch_all(&server_state.mysql_pool) + .await; + + let results : Vec = match maybe_results { + Ok(results) => { + info!("Results length: {}", results.len()); + results + }, + Err(err) => { + match err { + RowNotFound => { + Vec::new() + }, + _ => { + warn!("list staff db error: {:?}", err); + return Err(ListStaffError::ServerError); + } + } + } + }; + + let response = ListStaffResponse { + success: true, + staff: results, + }; + + let body = serde_json::to_string(&response) + .map_err(|e| ListStaffError::ServerError)?; + + Ok(HttpResponse::Ok() + .content_type("application/json") + .body(body)) +} diff --git a/src/http_server/endpoints/moderation/user_roles/mod.rs b/src/http_server/endpoints/moderation/user_roles/mod.rs index 9bb628e473..8e10abf233 100644 --- a/src/http_server/endpoints/moderation/user_roles/mod.rs +++ b/src/http_server/endpoints/moderation/user_roles/mod.rs @@ -1,3 +1,3 @@ -pub mod list_mods; +pub mod list_staff; pub mod list_roles; pub mod set_user_role; diff --git a/src/main.rs b/src/main.rs index 0f15de12f8..c3ea3e2c4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -81,6 +81,7 @@ use sqlx::MySqlPool; use sqlx::mysql::MySqlPoolOptions; use std::sync::Arc; use crate::http_server::endpoints::moderation::user_roles::list_roles::list_user_roles_handler; +use crate::http_server::endpoints::moderation::user_roles::list_staff::list_staff_handler; // TODO TODO TODO TODO // TODO TODO TODO TODO @@ -283,6 +284,11 @@ pub async fn serve(server_state: ServerState) -> AnyhowResult<()> // ==================== MODERATOR ==================== .service( web::scope("/moderation") + .service( + web::resource("/staff") + .route(web::get().to(list_staff_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) .service( web::scope("/ip_bans") .service(