mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 03:53:26 -08:00
[Server] Serve report list views through the database interface (#7844)
cmdReportList, cmdReportMyList and cmdReportDetails still prepared their SELECTs inline through Servatrice_DatabaseInterface and mapped the result columns to protocol records in the socket handler. Add getReportList, getReportsSubmittedBy, getReportForDetails and getReportComments to Server_DatabaseInterface with fail-closed defaults and a ReportLookupResult outcome, implement them with the previous statements, joins and null handling, and keep the detail authorization check and the tolerated comment-query failure in the handler in the same order. Response codes are unchanged.
This commit is contained in:
parent
fb836c6e0c
commit
2ba80cb61d
4 changed files with 349 additions and 232 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_chat_message.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_chat_message.pb.h"
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h"
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_private_chat_message.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_private_chat_message.pb.h"
|
||||||
|
#include "libcockatrice/protocol/pb/serverinfo_report.pb.h"
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_user.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_user.pb.h"
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_user_alt.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_user_alt.pb.h"
|
||||||
#include "libcockatrice/protocol/pb/serverinfo_user_session.pb.h"
|
#include "libcockatrice/protocol/pb/serverinfo_user_session.pb.h"
|
||||||
|
|
@ -391,6 +392,38 @@ public:
|
||||||
{
|
{
|
||||||
return ReplayWriteResult::Failed;
|
return ReplayWriteResult::Failed;
|
||||||
}
|
}
|
||||||
|
/** @brief Outcome of fetching one report row for the detail view. */
|
||||||
|
enum class ReportLookupResult
|
||||||
|
{
|
||||||
|
Ok,
|
||||||
|
NotFound,
|
||||||
|
Failed
|
||||||
|
};
|
||||||
|
/** @brief One page of reports with their joined moderator names, plus the total row count. */
|
||||||
|
virtual bool getReportList(bool /* unresolvedOnly */,
|
||||||
|
int /* offset */,
|
||||||
|
int /* limit */,
|
||||||
|
int & /* totalCount */,
|
||||||
|
QList<ServerInfo_Report> & /* reports */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/** @brief The newest reports the user filed, for their own list. */
|
||||||
|
virtual bool getReportsSubmittedBy(int /* reporterId */, QList<ServerInfo_Report> & /* reports */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/** @brief One report row for the detail view; also returns the reporter id for the access check. */
|
||||||
|
virtual ReportLookupResult
|
||||||
|
getReportForDetails(int /* reportId */, int & /* reporterId */, ServerInfo_Report & /* report */)
|
||||||
|
{
|
||||||
|
return ReportLookupResult::Failed;
|
||||||
|
}
|
||||||
|
/** @brief The comments of a report in creation order. */
|
||||||
|
virtual bool getReportComments(int /* reportId */, QList<ServerInfo_ReportComment> & /* comments */)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/** @brief One resolved or dismissed report whose reporter has not been told yet. */
|
/** @brief One resolved or dismissed report whose reporter has not been told yet. */
|
||||||
struct PendingReportNotification
|
struct PendingReportNotification
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3562,6 +3562,287 @@ bool Servatrice_DatabaseInterface::userEmailMatches(const QString &userName, con
|
||||||
return validateTableColumnStringData("{prefix}_users", "email", userName, email);
|
return validateTableColumnStringData("{prefix}_users", "email", userName, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// The user level the protocol expects for a report's reported user, resolved from the
|
||||||
|
// joined user row: the row is absent when the reported name no longer exists.
|
||||||
|
int reportUserLevel(bool userExists, int adminFlags)
|
||||||
|
{
|
||||||
|
int userLevel = ServerInfo_User::IsUser;
|
||||||
|
if (userExists) {
|
||||||
|
userLevel |= ServerInfo_User::IsRegistered;
|
||||||
|
if (adminFlags & 1) {
|
||||||
|
userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator;
|
||||||
|
} else if (adminFlags & 2) {
|
||||||
|
userLevel |= ServerInfo_User::IsModerator;
|
||||||
|
}
|
||||||
|
if (adminFlags & 4) {
|
||||||
|
userLevel |= ServerInfo_User::IsJudge;
|
||||||
|
}
|
||||||
|
if (adminFlags & 8) {
|
||||||
|
userLevel |= ServerInfo_User::IsDeveloper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userLevel;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::getReportList(bool unresolvedOnly,
|
||||||
|
int offset,
|
||||||
|
int limit,
|
||||||
|
int &totalCount,
|
||||||
|
QList<ServerInfo_Report> &reports)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString whereClause;
|
||||||
|
if (unresolvedOnly) {
|
||||||
|
whereClause = "WHERE r.status = 'open' OR r.status = 'assigned' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *countQuery = prepareQuery("SELECT COUNT(*) FROM {prefix}_reports r " + whereClause);
|
||||||
|
totalCount = 0;
|
||||||
|
if (execSqlQuery(countQuery) && countQuery->next()) {
|
||||||
|
totalCount = countQuery->value(0).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, "
|
||||||
|
"r.category, r.description, r.created_at, r.status, "
|
||||||
|
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, "
|
||||||
|
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
||||||
|
"AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin "
|
||||||
|
"FROM {prefix}_reports r "
|
||||||
|
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
||||||
|
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
||||||
|
"LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name ";
|
||||||
|
|
||||||
|
if (unresolvedOnly) {
|
||||||
|
queryStr += "WHERE r.status = 'open' OR r.status = 'assigned' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
queryStr += "ORDER BY r.created_at DESC LIMIT :limit OFFSET :offset";
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery(queryStr);
|
||||||
|
query->bindValue(":limit", limit);
|
||||||
|
query->bindValue(":offset", offset);
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query->next()) {
|
||||||
|
ServerInfo_Report info;
|
||||||
|
|
||||||
|
info.set_report_id(query->value(0).toInt());
|
||||||
|
info.set_reporter_name(query->value(1).toString().toStdString());
|
||||||
|
info.set_reported_user_name(query->value(2).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(3).isNull()) {
|
||||||
|
info.set_game_id(query->value(3).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
info.set_category(query->value(4).toString().toStdString());
|
||||||
|
info.set_description(query->value(5).toString().toStdString());
|
||||||
|
info.set_report_time(query->value(6).toDateTime().toSecsSinceEpoch());
|
||||||
|
info.set_status(query->value(7).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(8).isNull()) {
|
||||||
|
info.set_resolution_note(query->value(8).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(9).isNull()) {
|
||||||
|
info.set_assigned_mod_name(query->value(9).toString().toStdString());
|
||||||
|
}
|
||||||
|
if (!query->value(10).isNull()) {
|
||||||
|
info.set_resolved_by_name(query->value(10).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(11).isNull()) {
|
||||||
|
info.set_room_id(query->value(11).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(12).isNull()) {
|
||||||
|
info.set_replay_id(query->value(12).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
info.set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt()));
|
||||||
|
|
||||||
|
reports.append(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::getReportsSubmittedBy(int reporterId, QList<ServerInfo_Report> &reports)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, "
|
||||||
|
"r.category, r.description, r.created_at, r.status, "
|
||||||
|
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, "
|
||||||
|
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
||||||
|
"AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin "
|
||||||
|
"FROM {prefix}_reports r "
|
||||||
|
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
||||||
|
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
||||||
|
"LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name "
|
||||||
|
"WHERE r.reporter_id = :reporter_id "
|
||||||
|
"ORDER BY r.created_at DESC LIMIT 200";
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery(queryStr);
|
||||||
|
query->bindValue(":reporter_id", reporterId);
|
||||||
|
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query->next()) {
|
||||||
|
ServerInfo_Report info;
|
||||||
|
|
||||||
|
info.set_report_id(query->value(0).toInt());
|
||||||
|
info.set_reporter_name(query->value(1).toString().toStdString());
|
||||||
|
info.set_reported_user_name(query->value(2).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(3).isNull()) {
|
||||||
|
info.set_game_id(query->value(3).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
info.set_category(query->value(4).toString().toStdString());
|
||||||
|
info.set_description(query->value(5).toString().toStdString());
|
||||||
|
info.set_report_time(query->value(6).toDateTime().toSecsSinceEpoch());
|
||||||
|
info.set_status(query->value(7).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(8).isNull()) {
|
||||||
|
info.set_resolution_note(query->value(8).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(9).isNull()) {
|
||||||
|
info.set_assigned_mod_name(query->value(9).toString().toStdString());
|
||||||
|
}
|
||||||
|
if (!query->value(10).isNull()) {
|
||||||
|
info.set_resolved_by_name(query->value(10).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(11).isNull()) {
|
||||||
|
info.set_room_id(query->value(11).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(12).isNull()) {
|
||||||
|
info.set_replay_id(query->value(12).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
info.set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt()));
|
||||||
|
|
||||||
|
reports.append(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Server_DatabaseInterface::ReportLookupResult
|
||||||
|
Servatrice_DatabaseInterface::getReportForDetails(int reportId, int &reporterId, ServerInfo_Report &report)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return ReportLookupResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString queryStr =
|
||||||
|
"SELECT r.id, r.reporter_id, r.reporter_name, r.reported_user_name, r.game_id, "
|
||||||
|
"r.category, r.description, r.created_at, r.status, "
|
||||||
|
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.chat_log, r.room_id, "
|
||||||
|
"r.resolution_time, "
|
||||||
|
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
||||||
|
"AS replay_id "
|
||||||
|
"FROM {prefix}_reports r "
|
||||||
|
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
||||||
|
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
||||||
|
"WHERE r.id = :id";
|
||||||
|
QSqlQuery *query = prepareQuery(queryStr);
|
||||||
|
query->bindValue(":id", reportId);
|
||||||
|
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return ReportLookupResult::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->next()) {
|
||||||
|
return ReportLookupResult::NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
reporterId = query->value(1).toInt();
|
||||||
|
|
||||||
|
report.set_report_id(query->value(0).toInt());
|
||||||
|
report.set_reporter_name(query->value(2).toString().toStdString());
|
||||||
|
report.set_reported_user_name(query->value(3).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(4).isNull()) {
|
||||||
|
report.set_game_id(query->value(4).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
report.set_category(query->value(5).toString().toStdString());
|
||||||
|
report.set_description(query->value(6).toString().toStdString());
|
||||||
|
report.set_report_time(query->value(7).toDateTime().toSecsSinceEpoch());
|
||||||
|
report.set_status(query->value(8).toString().toStdString());
|
||||||
|
|
||||||
|
if (!query->value(9).isNull()) {
|
||||||
|
report.set_resolution_note(query->value(9).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(10).isNull()) {
|
||||||
|
report.set_assigned_mod_name(query->value(10).toString().toStdString());
|
||||||
|
}
|
||||||
|
if (!query->value(11).isNull()) {
|
||||||
|
report.set_resolved_by_name(query->value(11).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(12).isNull()) {
|
||||||
|
report.set_chat_log(query->value(12).toString().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(13).isNull()) {
|
||||||
|
report.set_room_id(query->value(13).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(14).isNull()) {
|
||||||
|
report.set_resolution_time(query->value(14).toDateTime().toSecsSinceEpoch());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query->value(15).isNull()) {
|
||||||
|
report.set_replay_id(query->value(15).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReportLookupResult::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Servatrice_DatabaseInterface::getReportComments(int reportId, QList<ServerInfo_ReportComment> &comments)
|
||||||
|
{
|
||||||
|
if (!checkSql()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery *query = prepareQuery("SELECT c.author_name, c.comment_text, c.created_at, c.is_moderator "
|
||||||
|
"FROM {prefix}_report_comments c "
|
||||||
|
"WHERE c.report_id = :report_id ORDER BY c.created_at ASC");
|
||||||
|
query->bindValue(":report_id", reportId);
|
||||||
|
|
||||||
|
if (!execSqlQuery(query)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query->next()) {
|
||||||
|
ServerInfo_ReportComment comment;
|
||||||
|
comment.set_author_name(query->value(0).toString().toStdString());
|
||||||
|
comment.set_comment_text(query->value(1).toString().toStdString());
|
||||||
|
comment.set_comment_time(query->value(2).toDateTime().toSecsSinceEpoch());
|
||||||
|
comment.set_is_moderator(query->value(3).toBool());
|
||||||
|
comments.append(comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int Servatrice_DatabaseInterface::countReportsSubmittedInLastDay(int reporterId)
|
int Servatrice_DatabaseInterface::countReportsSubmittedInLastDay(int reporterId)
|
||||||
{
|
{
|
||||||
if (!checkSql()) {
|
if (!checkSql()) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_chat_message.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_chat_message.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_moderator_login.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_private_chat_message.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_private_chat_message.pb.h>
|
||||||
|
#include <libcockatrice/protocol/pb/serverinfo_report.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_user_alt.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_user_alt.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_user_session.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_user_session.pb.h>
|
||||||
#include <libcockatrice/protocol/pb/serverinfo_warning.pb.h>
|
#include <libcockatrice/protocol/pb/serverinfo_warning.pb.h>
|
||||||
|
|
@ -291,6 +292,15 @@ public:
|
||||||
bool results) override;
|
bool results) override;
|
||||||
int countReportsSubmittedInLastDay(int reporterId) override;
|
int countReportsSubmittedInLastDay(int reporterId) override;
|
||||||
int getReportedUserId(const QString &userName) override;
|
int getReportedUserId(const QString &userName) override;
|
||||||
|
bool getReportList(bool unresolvedOnly,
|
||||||
|
int offset,
|
||||||
|
int limit,
|
||||||
|
int &totalCount,
|
||||||
|
QList<ServerInfo_Report> &reports) override;
|
||||||
|
bool getReportsSubmittedBy(int reporterId, QList<ServerInfo_Report> &reports) override;
|
||||||
|
Server_DatabaseInterface::ReportLookupResult
|
||||||
|
getReportForDetails(int reportId, int &reporterId, ServerInfo_Report &report) override;
|
||||||
|
bool getReportComments(int reportId, QList<ServerInfo_ReportComment> &comments) override;
|
||||||
bool addReport(int reporterId,
|
bool addReport(int reporterId,
|
||||||
const QString &reporterName,
|
const QString &reporterName,
|
||||||
int reportedUserId,
|
int reportedUserId,
|
||||||
|
|
|
||||||
|
|
@ -1819,33 +1819,10 @@ Response::ResponseCode AbstractServerSocketInterface::cmdBanFromServer(const Com
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
int reportUserLevel(bool userExists, int adminFlags)
|
|
||||||
{
|
|
||||||
int userLevel = ServerInfo_User::IsUser;
|
|
||||||
if (userExists) {
|
|
||||||
userLevel |= ServerInfo_User::IsRegistered;
|
|
||||||
if (adminFlags & 1) {
|
|
||||||
userLevel |= ServerInfo_User::IsAdmin | ServerInfo_User::IsModerator;
|
|
||||||
} else if (adminFlags & 2) {
|
|
||||||
userLevel |= ServerInfo_User::IsModerator;
|
|
||||||
}
|
|
||||||
if (adminFlags & 4) {
|
|
||||||
userLevel |= ServerInfo_User::IsJudge;
|
|
||||||
}
|
|
||||||
if (adminFlags & 8) {
|
|
||||||
userLevel |= ServerInfo_User::IsDeveloper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userLevel;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Command_ReportList &cmd,
|
Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Command_ReportList &cmd,
|
||||||
ResponseContainer &rc)
|
ResponseContainer &rc)
|
||||||
{
|
{
|
||||||
if (!sqlInterface->checkSql()) {
|
if (!databaseInterface->checkSql()) {
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1853,85 +1830,16 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportList(const Comman
|
||||||
const int offset = static_cast<int>(cmd.offset());
|
const int offset = static_cast<int>(cmd.offset());
|
||||||
const int limit = qMin(static_cast<int>(cmd.limit()), 1000);
|
const int limit = qMin(static_cast<int>(cmd.limit()), 1000);
|
||||||
|
|
||||||
// Columns: 0=id, 1=reporter_name, 2=reported_user_name, 3=game_id,
|
|
||||||
// 4=category, 5=description, 6=created_at, 7=status,
|
|
||||||
// 8=resolution_note, 9=assigned_mod_name, 10=resolved_by_name,
|
|
||||||
// 11=room_id, 12=replay_id,
|
|
||||||
// 13=reported_user_id, 14=reported_user_admin
|
|
||||||
QString whereClause;
|
|
||||||
if (unresolvedOnly) {
|
|
||||||
whereClause = "WHERE r.status = 'open' OR r.status = 'assigned' ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Total count query
|
|
||||||
QSqlQuery *countQuery = sqlInterface->prepareQuery("SELECT COUNT(*) FROM {prefix}_reports r " + whereClause);
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
if (sqlInterface->execSqlQuery(countQuery) && countQuery->next()) {
|
QList<ServerInfo_Report> reports;
|
||||||
totalCount = countQuery->value(0).toInt();
|
if (!databaseInterface->getReportList(unresolvedOnly, offset, limit, totalCount, reports)) {
|
||||||
}
|
|
||||||
|
|
||||||
QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, "
|
|
||||||
"r.category, r.description, r.created_at, r.status, "
|
|
||||||
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, "
|
|
||||||
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
|
||||||
"AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin "
|
|
||||||
"FROM {prefix}_reports r "
|
|
||||||
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
|
||||||
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
|
||||||
"LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name ";
|
|
||||||
|
|
||||||
if (unresolvedOnly) {
|
|
||||||
queryStr += "WHERE r.status = 'open' OR r.status = 'assigned' ";
|
|
||||||
}
|
|
||||||
|
|
||||||
queryStr += "ORDER BY r.created_at DESC LIMIT :limit OFFSET :offset";
|
|
||||||
|
|
||||||
QSqlQuery *query = sqlInterface->prepareQuery(queryStr);
|
|
||||||
query->bindValue(":limit", limit);
|
|
||||||
query->bindValue(":offset", offset);
|
|
||||||
if (!sqlInterface->execSqlQuery(query)) {
|
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response_ReportList *re = new Response_ReportList;
|
Response_ReportList *re = new Response_ReportList;
|
||||||
re->set_total_count(totalCount);
|
re->set_total_count(totalCount);
|
||||||
|
for (const ServerInfo_Report &report : reports) {
|
||||||
while (query->next()) {
|
*re->add_reports() = report;
|
||||||
ServerInfo_Report *info = re->add_reports();
|
|
||||||
|
|
||||||
info->set_report_id(query->value(0).toInt());
|
|
||||||
info->set_reporter_name(query->value(1).toString().toStdString());
|
|
||||||
info->set_reported_user_name(query->value(2).toString().toStdString());
|
|
||||||
|
|
||||||
if (!query->value(3).isNull()) {
|
|
||||||
info->set_game_id(query->value(3).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
info->set_category(query->value(4).toString().toStdString());
|
|
||||||
info->set_description(query->value(5).toString().toStdString());
|
|
||||||
info->set_report_time(query->value(6).toDateTime().toSecsSinceEpoch());
|
|
||||||
info->set_status(query->value(7).toString().toStdString());
|
|
||||||
|
|
||||||
if (!query->value(8).isNull()) {
|
|
||||||
info->set_resolution_note(query->value(8).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(9).isNull()) {
|
|
||||||
info->set_assigned_mod_name(query->value(9).toString().toStdString());
|
|
||||||
}
|
|
||||||
if (!query->value(10).isNull()) {
|
|
||||||
info->set_resolved_by_name(query->value(10).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(11).isNull()) {
|
|
||||||
info->set_room_id(query->value(11).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(12).isNull()) {
|
|
||||||
info->set_replay_id(query->value(12).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
info->set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
|
|
@ -2636,69 +2544,20 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportMyList(const Comm
|
||||||
return Response::RespFunctionNotAllowed;
|
return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sqlInterface->checkSql()) {
|
if (!databaseInterface->checkSql()) {
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPendingReportNotifications(rc);
|
sendPendingReportNotifications(rc);
|
||||||
|
|
||||||
QString queryStr = "SELECT r.id, r.reporter_name, r.reported_user_name, r.game_id, "
|
QList<ServerInfo_Report> reports;
|
||||||
"r.category, r.description, r.created_at, r.status, "
|
if (!databaseInterface->getReportsSubmittedBy(userInfo->id(), reports)) {
|
||||||
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.room_id, "
|
|
||||||
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
|
||||||
"AS replay_id, u2.id AS reported_user_id, u2.admin AS reported_user_admin "
|
|
||||||
"FROM {prefix}_reports r "
|
|
||||||
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
|
||||||
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
|
||||||
"LEFT JOIN {prefix}_users u2 ON u2.name = r.reported_user_name "
|
|
||||||
"WHERE r.reporter_id = :reporter_id "
|
|
||||||
"ORDER BY r.created_at DESC LIMIT 200";
|
|
||||||
|
|
||||||
QSqlQuery *query = sqlInterface->prepareQuery(queryStr);
|
|
||||||
query->bindValue(":reporter_id", userInfo->id());
|
|
||||||
|
|
||||||
if (!sqlInterface->execSqlQuery(query)) {
|
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response_ReportMyList *re = new Response_ReportMyList;
|
Response_ReportMyList *re = new Response_ReportMyList;
|
||||||
|
for (const ServerInfo_Report &report : reports) {
|
||||||
while (query->next()) {
|
*re->add_reports() = report;
|
||||||
ServerInfo_Report *info = re->add_reports();
|
|
||||||
|
|
||||||
info->set_report_id(query->value(0).toInt());
|
|
||||||
info->set_reporter_name(query->value(1).toString().toStdString());
|
|
||||||
info->set_reported_user_name(query->value(2).toString().toStdString());
|
|
||||||
|
|
||||||
if (!query->value(3).isNull()) {
|
|
||||||
info->set_game_id(query->value(3).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
info->set_category(query->value(4).toString().toStdString());
|
|
||||||
info->set_description(query->value(5).toString().toStdString());
|
|
||||||
info->set_report_time(query->value(6).toDateTime().toSecsSinceEpoch());
|
|
||||||
info->set_status(query->value(7).toString().toStdString());
|
|
||||||
|
|
||||||
if (!query->value(8).isNull()) {
|
|
||||||
info->set_resolution_note(query->value(8).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(9).isNull()) {
|
|
||||||
info->set_assigned_mod_name(query->value(9).toString().toStdString());
|
|
||||||
}
|
|
||||||
if (!query->value(10).isNull()) {
|
|
||||||
info->set_resolved_by_name(query->value(10).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(11).isNull()) {
|
|
||||||
info->set_room_id(query->value(11).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(12).isNull()) {
|
|
||||||
info->set_replay_id(query->value(12).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
info->set_reported_user_level(reportUserLevel(!query->value(13).isNull(), query->value(14).toInt()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
|
|
@ -2749,103 +2608,37 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportDetails(const Com
|
||||||
return Response::RespFunctionNotAllowed;
|
return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sqlInterface->checkSql()) {
|
if (!databaseInterface->checkSql()) {
|
||||||
return Response::RespInternalError;
|
return Response::RespInternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int reportId = cmd.report_id();
|
const int reportId = cmd.report_id();
|
||||||
|
|
||||||
// Columns: 0=id, 1=reporter_id, 2=reporter_name, 3=reported_user_name, 4=game_id,
|
int reporterId = -1;
|
||||||
// 5=category, 6=description, 7=created_at, 8=status,
|
ServerInfo_Report info;
|
||||||
// 9=resolution_note, 10=assigned_mod_name, 11=resolved_by_name,
|
switch (databaseInterface->getReportForDetails(reportId, reporterId, info)) {
|
||||||
// 12=chat_log, 13=room_id, 14=resolution_time, 15=replay_id
|
case Server_DatabaseInterface::ReportLookupResult::Failed:
|
||||||
QString queryStr =
|
return Response::RespInternalError;
|
||||||
"SELECT r.id, r.reporter_id, r.reporter_name, r.reported_user_name, r.game_id, "
|
case Server_DatabaseInterface::ReportLookupResult::NotFound:
|
||||||
"r.category, r.description, r.created_at, r.status, "
|
return Response::RespNameNotFound;
|
||||||
"r.resolution_note, u.name AS assigned_mod_name, ru.name AS resolved_by_name, r.chat_log, r.room_id, "
|
case Server_DatabaseInterface::ReportLookupResult::Ok:
|
||||||
"r.resolution_time, "
|
break;
|
||||||
"(SELECT id FROM {prefix}_replays WHERE id_game = r.game_id ORDER BY id DESC LIMIT 1) "
|
|
||||||
"AS replay_id "
|
|
||||||
"FROM {prefix}_reports r "
|
|
||||||
"LEFT JOIN {prefix}_users u ON r.assigned_to = u.id "
|
|
||||||
"LEFT JOIN {prefix}_users ru ON r.resolved_by = ru.id "
|
|
||||||
"WHERE r.id = :id";
|
|
||||||
QSqlQuery *query = sqlInterface->prepareQuery(queryStr);
|
|
||||||
query->bindValue(":id", reportId);
|
|
||||||
|
|
||||||
if (!sqlInterface->execSqlQuery(query)) {
|
|
||||||
return Response::RespInternalError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->next()) {
|
|
||||||
return Response::RespNameNotFound;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isMod = userInfo->user_level() & ServerInfo_User::IsModerator;
|
const bool isMod = userInfo->user_level() & ServerInfo_User::IsModerator;
|
||||||
const int reporterId = query->value(1).toInt();
|
|
||||||
if (reporterId != userInfo->id() && !isMod) {
|
if (reporterId != userInfo->id() && !isMod) {
|
||||||
return Response::RespAccessDenied;
|
return Response::RespAccessDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo_Report *info = new ServerInfo_Report;
|
QList<ServerInfo_ReportComment> comments;
|
||||||
info->set_report_id(query->value(0).toInt());
|
if (databaseInterface->getReportComments(reportId, comments)) {
|
||||||
info->set_reporter_name(query->value(2).toString().toStdString());
|
for (const ServerInfo_ReportComment &comment : comments) {
|
||||||
info->set_reported_user_name(query->value(3).toString().toStdString());
|
*info.add_comments() = comment;
|
||||||
|
|
||||||
if (!query->value(4).isNull()) {
|
|
||||||
info->set_game_id(query->value(4).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
info->set_category(query->value(5).toString().toStdString());
|
|
||||||
info->set_description(query->value(6).toString().toStdString());
|
|
||||||
info->set_report_time(query->value(7).toDateTime().toSecsSinceEpoch());
|
|
||||||
info->set_status(query->value(8).toString().toStdString());
|
|
||||||
|
|
||||||
if (!query->value(9).isNull()) {
|
|
||||||
info->set_resolution_note(query->value(9).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(10).isNull()) {
|
|
||||||
info->set_assigned_mod_name(query->value(10).toString().toStdString());
|
|
||||||
}
|
|
||||||
if (!query->value(11).isNull()) {
|
|
||||||
info->set_resolved_by_name(query->value(11).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(12).isNull()) {
|
|
||||||
info->set_chat_log(query->value(12).toString().toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(13).isNull()) {
|
|
||||||
info->set_room_id(query->value(13).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(14).isNull()) {
|
|
||||||
info->set_resolution_time(query->value(14).toDateTime().toSecsSinceEpoch());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query->value(15).isNull()) {
|
|
||||||
info->set_replay_id(query->value(15).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
QSqlQuery *commentQuery =
|
|
||||||
sqlInterface->prepareQuery("SELECT c.author_name, c.comment_text, c.created_at, c.is_moderator "
|
|
||||||
"FROM {prefix}_report_comments c "
|
|
||||||
"WHERE c.report_id = :report_id ORDER BY c.created_at ASC");
|
|
||||||
commentQuery->bindValue(":report_id", reportId);
|
|
||||||
|
|
||||||
if (sqlInterface->execSqlQuery(commentQuery)) {
|
|
||||||
while (commentQuery->next()) {
|
|
||||||
ServerInfo_ReportComment *comment = info->add_comments();
|
|
||||||
comment->set_author_name(commentQuery->value(0).toString().toStdString());
|
|
||||||
comment->set_comment_text(commentQuery->value(1).toString().toStdString());
|
|
||||||
comment->set_comment_time(commentQuery->value(2).toDateTime().toSecsSinceEpoch());
|
|
||||||
comment->set_is_moderator(commentQuery->value(3).toBool());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Response_ReportDetails *re = new Response_ReportDetails;
|
Response_ReportDetails *re = new Response_ReportDetails;
|
||||||
re->set_allocated_report(info);
|
re->set_allocated_report(new ServerInfo_Report(info));
|
||||||
rc.setResponseExtension(re);
|
rc.setResponseExtension(re);
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue