diff --git a/crates/schema/public/enums/src/by_table/staff_audit_logs/staff_audit_action.rs b/crates/schema/public/enums/src/by_table/staff_audit_logs/staff_audit_action.rs index d718416b5a..f86252345c 100644 --- a/crates/schema/public/enums/src/by_table/staff_audit_logs/staff_audit_action.rs +++ b/crates/schema/public/enums/src/by_table/staff_audit_logs/staff_audit_action.rs @@ -32,6 +32,10 @@ pub enum StaffAuditAction { /// Staff added banked balance to a wallet. #[serde(rename = "add_wallet_banked_balance")] AddWalletBankedBalance, + + /// Staff sent a manual alert via the pager system. + #[serde(rename = "send_alert")] + SendAlert, } impl_enum_display_and_debug_using_to_str!(StaffAuditAction); @@ -46,6 +50,7 @@ impl StaffAuditAction { Self::BanUser => "ban_user", Self::UnbanUser => "unban_user", Self::AddWalletBankedBalance => "add_wallet_banked_balance", + Self::SendAlert => "send_alert", } } @@ -56,6 +61,7 @@ impl StaffAuditAction { "ban_user" => Ok(Self::BanUser), "unban_user" => Ok(Self::UnbanUser), "add_wallet_banked_balance" => Ok(Self::AddWalletBankedBalance), + "send_alert" => Ok(Self::SendAlert), _ => Err(format!("invalid StaffAuditAction value: {:?}", value)), } } @@ -67,6 +73,7 @@ impl StaffAuditAction { Self::BanUser, Self::UnbanUser, Self::AddWalletBankedBalance, + Self::SendAlert, ]) } } @@ -86,6 +93,7 @@ mod tests { assert_serialization(StaffAuditAction::BanUser, "ban_user"); assert_serialization(StaffAuditAction::UnbanUser, "unban_user"); assert_serialization(StaffAuditAction::AddWalletBankedBalance, "add_wallet_banked_balance"); + assert_serialization(StaffAuditAction::SendAlert, "send_alert"); } #[test] @@ -95,6 +103,7 @@ mod tests { assert_eq!(StaffAuditAction::BanUser.to_str(), "ban_user"); assert_eq!(StaffAuditAction::UnbanUser.to_str(), "unban_user"); assert_eq!(StaffAuditAction::AddWalletBankedBalance.to_str(), "add_wallet_banked_balance"); + assert_eq!(StaffAuditAction::SendAlert.to_str(), "send_alert"); } #[test] @@ -104,12 +113,13 @@ mod tests { assert_eq!(StaffAuditAction::from_str("ban_user").unwrap(), StaffAuditAction::BanUser); assert_eq!(StaffAuditAction::from_str("unban_user").unwrap(), StaffAuditAction::UnbanUser); assert_eq!(StaffAuditAction::from_str("add_wallet_banked_balance").unwrap(), StaffAuditAction::AddWalletBankedBalance); + assert_eq!(StaffAuditAction::from_str("send_alert").unwrap(), StaffAuditAction::SendAlert); assert!(StaffAuditAction::from_str("invalid").is_err()); } #[test] fn all_variants() { - const EXPECTED_COUNT: usize = 5; + const EXPECTED_COUNT: usize = 6; assert_eq!(StaffAuditAction::all_variants().len(), EXPECTED_COUNT); } } diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/alerts/moderation_send_alert_handler.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/alerts/moderation_send_alert_handler.rs index 214caefbc9..315bee8bfe 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/alerts/moderation_send_alert_handler.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/moderation/alerts/moderation_send_alert_handler.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use std::sync::Arc; use actix_web::web::Json; @@ -5,11 +6,14 @@ use actix_web::{web, HttpRequest}; use log::warn; use artcraft_api_defs::moderation::alerts::moderation_send_alert::{ModerationSendAlertRequest, ModerationSendAlertResponse, ModerationSendAlertUrgency}; -use pager::client::pager::Pager; -use pager::notification::notification_details::NotificationDetails; +use enums::by_table::staff_audit_logs::staff_audit_action::StaffAuditAction; +use http_server_common::request::get_request_ip::get_request_ip; +use mysql_queries::queries::staff_audit_logs::insert_staff_audit_log::{ + insert_staff_audit_log, InsertStaffAuditLogArgs, +}; use pager::notification::notification_details_builder::NotificationDetailsBuilder; use pager::notification::notification_urgency::NotificationUrgency; -use crate::http_server::common_responses::common_web_error::CommonWebError; +use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError; use crate::http_server::web_utils::user_session::require_moderator::{require_moderator, UseDatabase}; use crate::state::server_state::ServerState; @@ -29,11 +33,16 @@ pub async fn moderation_send_alert_handler( http_request: HttpRequest, request: Json, server_state: web::Data>, -) -> Result, CommonWebError> { +) -> Result, AdvancedCommonWebError> { let user_session = require_moderator(&http_request, &server_state, UseDatabase::GrabNewConnection) .await - .map_err(|_| CommonWebError::NotAuthorized)?; + .map_err(|err| { + warn!("Moderator check failed: {:?}", err); + AdvancedCommonWebError::NotAuthorized + })?; + + let ip_address = get_request_ip(&http_request); let title = request.title.clone() .unwrap_or_else(|| "Moderation Alert".to_string()); @@ -68,9 +77,23 @@ pub async fn moderation_send_alert_handler( .enqueue_page(notification) .map_err(|err| { warn!("moderation_send_alert error: {:?}", err); - CommonWebError::ServerError + AdvancedCommonWebError::server_error_with_message("Failed to enqueue alert") })?; + // Insert staff audit log. + let _audit_token = insert_staff_audit_log(InsertStaffAuditLogArgs { + audit_action: StaffAuditAction::SendAlert, + maybe_entity_type: None, + maybe_entity_token: None, + staff_user_token: &user_session.user_token, + actor_ip_address: &ip_address, + mysql_executor: &server_state.mysql_pool, + phantom: PhantomData, + }).await.map_err(|err| { + warn!("Failed to insert staff audit log: {:?}", err); + AdvancedCommonWebError::from_error(err) + })?; + Ok(Json(ModerationSendAlertResponse { success: true, }))