mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
Allow Moderators/Admins to Grant Replay Access
- Only to themselves, at this time - Automatically refreshes feed, no need to re-login
This commit is contained in:
parent
17893d9747
commit
3524231500
7 changed files with 129 additions and 6 deletions
|
|
@ -1,19 +1,20 @@
|
||||||
#include "tab_admin.h"
|
#include "tab_admin.h"
|
||||||
|
|
||||||
|
#include "../../server/pending_command.h"
|
||||||
#include "../game_logic/abstract_client.h"
|
#include "../game_logic/abstract_client.h"
|
||||||
#include "pb/admin_commands.pb.h"
|
#include "pb/admin_commands.pb.h"
|
||||||
|
#include "pb/event_replay_added.pb.h"
|
||||||
|
#include "pb/moderator_commands.pb.h"
|
||||||
#include "trice_limits.h"
|
#include "trice_limits.h"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
ShutdownDialog::ShutdownDialog(QWidget *parent) : QDialog(parent)
|
ShutdownDialog::ShutdownDialog(QWidget *parent) : QDialog(parent)
|
||||||
{
|
{
|
||||||
|
|
@ -63,10 +64,23 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
|
||||||
reloadConfigButton = new QPushButton;
|
reloadConfigButton = new QPushButton;
|
||||||
connect(reloadConfigButton, &QPushButton::clicked, this, &TabAdmin::actReloadConfig);
|
connect(reloadConfigButton, &QPushButton::clicked, this, &TabAdmin::actReloadConfig);
|
||||||
|
|
||||||
|
grantReplayAccessButton = new QPushButton;
|
||||||
|
grantReplayAccessButton->setEnabled(false);
|
||||||
|
connect(grantReplayAccessButton, &QPushButton::clicked, this, &TabAdmin::actGrantReplayAccess);
|
||||||
|
replayIdToGrant = new QLineEdit;
|
||||||
|
replayIdToGrant->setMaximumWidth(500);
|
||||||
|
replayIdToGrant->setValidator(new QIntValidator(0, INT_MAX, this));
|
||||||
|
connect(replayIdToGrant, &QLineEdit::textChanged, this,
|
||||||
|
[=, this]() { grantReplayAccessButton->setEnabled(!replayIdToGrant->text().isEmpty()); });
|
||||||
|
auto *grandReplayAccessLayout = new QGridLayout(this);
|
||||||
|
grandReplayAccessLayout->addWidget(replayIdToGrant, 0, 0);
|
||||||
|
grandReplayAccessLayout->addWidget(grantReplayAccessButton, 0, 1);
|
||||||
|
|
||||||
QVBoxLayout *vbox = new QVBoxLayout;
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
vbox->addWidget(updateServerMessageButton);
|
vbox->addWidget(updateServerMessageButton);
|
||||||
vbox->addWidget(shutdownServerButton);
|
vbox->addWidget(shutdownServerButton);
|
||||||
vbox->addWidget(reloadConfigButton);
|
vbox->addWidget(reloadConfigButton);
|
||||||
|
vbox->addLayout(grandReplayAccessLayout);
|
||||||
vbox->addStretch();
|
vbox->addStretch();
|
||||||
|
|
||||||
adminGroupBox = new QGroupBox;
|
adminGroupBox = new QGroupBox;
|
||||||
|
|
@ -100,6 +114,9 @@ void TabAdmin::retranslateUi()
|
||||||
reloadConfigButton->setText(tr("&Reload configuration"));
|
reloadConfigButton->setText(tr("&Reload configuration"));
|
||||||
adminGroupBox->setTitle(tr("Server administration functions"));
|
adminGroupBox->setTitle(tr("Server administration functions"));
|
||||||
|
|
||||||
|
replayIdToGrant->setPlaceholderText(tr("Replay ID"));
|
||||||
|
grantReplayAccessButton->setText(tr("Grant Replay Access"));
|
||||||
|
|
||||||
unlockButton->setText(tr("&Unlock functions"));
|
unlockButton->setText(tr("&Unlock functions"));
|
||||||
lockButton->setText(tr("&Lock functions"));
|
lockButton->setText(tr("&Lock functions"));
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +144,41 @@ void TabAdmin::actReloadConfig()
|
||||||
client->sendCommand(client->prepareAdminCommand(cmd));
|
client->sendCommand(client->prepareAdminCommand(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TabAdmin::actGrantReplayAccess()
|
||||||
|
{
|
||||||
|
if (!replayIdToGrant) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command_GrantReplayAccess cmd;
|
||||||
|
cmd.set_replay_id(replayIdToGrant->text().toUInt());
|
||||||
|
cmd.set_moderator_name(client->getUserName().toStdString());
|
||||||
|
|
||||||
|
auto *pend = client->prepareModeratorCommand(cmd);
|
||||||
|
connect(pend,
|
||||||
|
QOverload<const Response &, const CommandContainer &, const QVariant &>::of(&PendingCommand::finished),
|
||||||
|
this, &TabAdmin::grantReplayAccessProcessResponse);
|
||||||
|
client->sendCommand(pend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabAdmin::grantReplayAccessProcessResponse(const Response &response, const CommandContainer &, const QVariant &)
|
||||||
|
{
|
||||||
|
auto *event = new Event_ReplayAdded();
|
||||||
|
|
||||||
|
switch (response.response_code()) {
|
||||||
|
case Response::RespOk:
|
||||||
|
client->replayAddedEventReceived(*event);
|
||||||
|
QMessageBox::information(this, tr("Success"), tr("Replay access granted"));
|
||||||
|
break;
|
||||||
|
case Response::RespContextError:
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Unable to grant replay access. Replay ID invalid"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Unable to grant replay access: Internal error"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TabAdmin::actUnlock()
|
void TabAdmin::actUnlock()
|
||||||
{
|
{
|
||||||
if (fullAdmin)
|
if (fullAdmin)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef TAB_ADMIN_H
|
#ifndef TAB_ADMIN_H
|
||||||
#define TAB_ADMIN_H
|
#define TAB_ADMIN_H
|
||||||
|
|
||||||
|
#include "pb/commands.pb.h"
|
||||||
|
#include "pb/response.pb.h"
|
||||||
#include "tab.h"
|
#include "tab.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
@ -32,15 +34,18 @@ private:
|
||||||
bool locked;
|
bool locked;
|
||||||
AbstractClient *client;
|
AbstractClient *client;
|
||||||
bool fullAdmin;
|
bool fullAdmin;
|
||||||
QPushButton *updateServerMessageButton, *shutdownServerButton, *reloadConfigButton;
|
QPushButton *updateServerMessageButton, *shutdownServerButton, *reloadConfigButton, *grantReplayAccessButton;
|
||||||
QGroupBox *adminGroupBox;
|
QGroupBox *adminGroupBox;
|
||||||
QPushButton *unlockButton, *lockButton;
|
QPushButton *unlockButton, *lockButton;
|
||||||
|
QLineEdit *replayIdToGrant;
|
||||||
signals:
|
signals:
|
||||||
void adminLockChanged(bool lock);
|
void adminLockChanged(bool lock);
|
||||||
private slots:
|
private slots:
|
||||||
void actUpdateServerMessage();
|
void actUpdateServerMessage();
|
||||||
void actShutdownServer();
|
void actShutdownServer();
|
||||||
void actReloadConfig();
|
void actReloadConfig();
|
||||||
|
void actGrantReplayAccess();
|
||||||
|
void grantReplayAccessProcessResponse(const Response &resp, const CommandContainer &, const QVariant &);
|
||||||
|
|
||||||
void actUnlock();
|
void actUnlock();
|
||||||
void actLock();
|
void actLock();
|
||||||
|
|
|
||||||
|
|
@ -401,5 +401,11 @@ void TabReplays::deleteRemoteReplayFinished(const Response &r, const CommandCont
|
||||||
|
|
||||||
void TabReplays::replayAddedEventReceived(const Event_ReplayAdded &event)
|
void TabReplays::replayAddedEventReceived(const Event_ReplayAdded &event)
|
||||||
{
|
{
|
||||||
serverDirView->addMatchInfo(event.match_info());
|
if (event.has_match_info()) {
|
||||||
|
// 99.9% of events will have match info (Normal Workflow)
|
||||||
|
serverDirView->addMatchInfo(event.match_info());
|
||||||
|
} else {
|
||||||
|
// When a Moderator force adds a replay, we need to refresh their view
|
||||||
|
serverDirView->refreshTree();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ private:
|
||||||
Node(const QString &_name) : name(_name)
|
Node(const QString &_name) : name(_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~Node(){};
|
virtual ~Node() {};
|
||||||
QString getName() const
|
QString getName() const
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
|
|
@ -115,7 +115,9 @@ public:
|
||||||
ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &ind) const;
|
ServerInfo_ReplayMatch const *getReplayMatch(const QModelIndex &ind) const;
|
||||||
QList<ServerInfo_Replay const *> getSelectedReplays() const;
|
QList<ServerInfo_Replay const *> getSelectedReplays() const;
|
||||||
QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const;
|
QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const;
|
||||||
void refreshTree();
|
void refreshTree() {
|
||||||
|
treeModel->refreshTree();
|
||||||
|
}
|
||||||
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
|
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
|
||||||
{
|
{
|
||||||
treeModel->addMatchInfo(matchInfo);
|
treeModel->addMatchInfo(matchInfo);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ message ModeratorCommand {
|
||||||
WARN_HISTORY = 1003;
|
WARN_HISTORY = 1003;
|
||||||
WARN_LIST = 1004;
|
WARN_LIST = 1004;
|
||||||
VIEWLOG_HISTORY = 1005;
|
VIEWLOG_HISTORY = 1005;
|
||||||
|
GRANT_REPLAY_ACCESS = 1006;
|
||||||
}
|
}
|
||||||
extensions 100 to max;
|
extensions 100 to max;
|
||||||
}
|
}
|
||||||
|
|
@ -71,3 +72,11 @@ message Command_ViewLogHistory {
|
||||||
required uint32 date_range = 7; // the length of time (in minutes) to look back for
|
required uint32 date_range = 7; // the length of time (in minutes) to look back for
|
||||||
optional uint32 maximum_results = 8; // the maximum number of query results
|
optional uint32 maximum_results = 8; // the maximum number of query results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Command_GrantReplayAccess {
|
||||||
|
extend ModeratorCommand {
|
||||||
|
optional Command_GrantReplayAccess ext = 1006;
|
||||||
|
}
|
||||||
|
optional uint32 replay_id = 1;
|
||||||
|
optional string moderator_name = 2;
|
||||||
|
}
|
||||||
|
|
@ -224,6 +224,8 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedModeratorCo
|
||||||
return cmdGetWarnList(cmd.GetExtension(Command_GetWarnList::ext), rc);
|
return cmdGetWarnList(cmd.GetExtension(Command_GetWarnList::ext), rc);
|
||||||
case ModeratorCommand::VIEWLOG_HISTORY:
|
case ModeratorCommand::VIEWLOG_HISTORY:
|
||||||
return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::ext), rc);
|
return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::ext), rc);
|
||||||
|
case ModeratorCommand::GRANT_REPLAY_ACCESS:
|
||||||
|
return cmdGrantReplayAccess(cmd.GetExtension(Command_GrantReplayAccess::ext), rc);
|
||||||
default:
|
default:
|
||||||
return Response::RespFunctionNotAllowed;
|
return Response::RespFunctionNotAllowed;
|
||||||
}
|
}
|
||||||
|
|
@ -1656,6 +1658,52 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAdjustMod(const Command
|
||||||
return Response::RespOk;
|
return Response::RespOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Response::ResponseCode AbstractServerSocketInterface::cmdGrantReplayAccess(const Command_GrantReplayAccess &cmd,
|
||||||
|
ResponseContainer & /*rc*/)
|
||||||
|
{
|
||||||
|
// Determine if the replay actually exists already
|
||||||
|
auto *replayExistsQuery =
|
||||||
|
sqlInterface->prepareQuery("select count(*) from {prefix}_replays_access where id_game = :idgame");
|
||||||
|
replayExistsQuery->bindValue(":idgame", cmd.replay_id());
|
||||||
|
if (!sqlInterface->execSqlQuery(replayExistsQuery)) {
|
||||||
|
return Response::RespInternalError;
|
||||||
|
}
|
||||||
|
if (!replayExistsQuery->next()) {
|
||||||
|
return Response::RespInternalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &replayExists = replayExistsQuery->value(0).toInt() > 0;
|
||||||
|
if (!replayExists) {
|
||||||
|
return Response::RespContextError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the Moderator's User ID (As it's not apart of client, only username is)
|
||||||
|
auto *getModeratorUserIdQuery = sqlInterface->prepareQuery("select id from {prefix}_users WHERE name = :name");
|
||||||
|
getModeratorUserIdQuery->bindValue(":name", QString::fromStdString(cmd.moderator_name()));
|
||||||
|
if (!sqlInterface->execSqlQuery(getModeratorUserIdQuery)) {
|
||||||
|
return Response::RespInternalError;
|
||||||
|
}
|
||||||
|
if (!getModeratorUserIdQuery->next()) {
|
||||||
|
return Response::RespInternalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &moderator_id = getModeratorUserIdQuery->value(0).toString();
|
||||||
|
|
||||||
|
// Grant the Moderator access to the replay
|
||||||
|
auto *grantReplayAccessQuery =
|
||||||
|
sqlInterface->prepareQuery("insert into {prefix}_replays_access (id_game, id_player, replay_name, do_not_hide) "
|
||||||
|
"values(:idgame, :idplayer, :replayname, 0)");
|
||||||
|
grantReplayAccessQuery->bindValue(":idgame", cmd.replay_id());
|
||||||
|
grantReplayAccessQuery->bindValue(":idplayer", moderator_id);
|
||||||
|
grantReplayAccessQuery->bindValue(":replayname", "Moderator Access Replay Grant");
|
||||||
|
|
||||||
|
if (!sqlInterface->execSqlQuery(grantReplayAccessQuery)) {
|
||||||
|
return Response::RespInternalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response::RespOk;
|
||||||
|
}
|
||||||
|
|
||||||
TcpServerSocketInterface::TcpServerSocketInterface(Servatrice *_server,
|
TcpServerSocketInterface::TcpServerSocketInterface(Servatrice *_server,
|
||||||
Servatrice_DatabaseInterface *_databaseInterface,
|
Servatrice_DatabaseInterface *_databaseInterface,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ private:
|
||||||
Response::ResponseCode cmdAccountEdit(const Command_AccountEdit &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdAccountEdit(const Command_AccountEdit &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdAccountImage(const Command_AccountImage &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdAccountImage(const Command_AccountImage &cmd, ResponseContainer &rc);
|
||||||
Response::ResponseCode cmdAccountPassword(const Command_AccountPassword &cmd, ResponseContainer &rc);
|
Response::ResponseCode cmdAccountPassword(const Command_AccountPassword &cmd, ResponseContainer &rc);
|
||||||
|
Response::ResponseCode cmdGrantReplayAccess(const Command_GrantReplayAccess &cmd, ResponseContainer &rc);
|
||||||
|
|
||||||
bool addAdminFlagToUser(const QString &user, int flag);
|
bool addAdminFlagToUser(const QString &user, int flag);
|
||||||
bool removeAdminFlagFromUser(const QString &user, int flag);
|
bool removeAdminFlagFromUser(const QString &user, int flag);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue