audit log for endpoint

This commit is contained in:
Brandon Thomas committed 2026-04-14 03:40:51 -04:00
1 parent c65775f7fe
commit ebca7c865b
2 files changed
+40 -7

No files matched your search

@@ -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);
}
}
@@ -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<ModerationSendAlertRequest>,
server_state: web::Data<Arc<ServerState>>,
) -> Result<Json<ModerationSendAlertResponse>, CommonWebError> {
) -> Result<Json<ModerationSendAlertResponse>, 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,
}))