mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[Server/Client/Protocol] Add developer staff role
Introduce a Developer staff level (proto flag 32, DB admin bit 8) that sits between admin and moderator: no kick/ban/warn/report/admin powers, but gets server log access via a new developer command container family (GET_SERVER_STATS, VIEWLOG_HISTORY) and an idle-timeout exemption. - Protocol: IsDeveloper flag, developer_commands.proto envelope, Command_GetServerStats/Command_GetLogHistory, Response_GetServerStats, Command_AdjustMod.should_be_developer - Servatrice: fail-closed developer dispatcher, uptime snapshot handler, shared log history handler reuse, bit-8 DB mapping - Client: burgundy pawn/badge/labels/sort order, prepareDeveloperCommand, minimal Developer stats tab, log tab access, promote/demote actions Took 24 minutes Took 18 seconds
This commit is contained in:
parent
7d867b9745
commit
1ff7ffcaa4
31 changed files with 515 additions and 23 deletions
|
|
@ -253,3 +253,11 @@ PendingCommand *AbstractClient::prepareAdminCommand(const ::google::protobuf::Me
|
|||
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
||||
return new PendingCommand(cont);
|
||||
}
|
||||
|
||||
PendingCommand *AbstractClient::prepareDeveloperCommand(const ::google::protobuf::Message &cmd)
|
||||
{
|
||||
CommandContainer cont;
|
||||
DeveloperCommand *c = cont.add_developer_command();
|
||||
c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
|
||||
return new PendingCommand(cont);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ public:
|
|||
static PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId);
|
||||
static PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd);
|
||||
static PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd);
|
||||
static PendingCommand *prepareDeveloperCommand(const ::google::protobuf::Message &cmd);
|
||||
|
||||
QMap<QString, bool> clientFeatures;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -388,6 +388,33 @@ Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(cons
|
|||
return finalResponseCode;
|
||||
}
|
||||
|
||||
Response::ResponseCode Server_ProtocolHandler::processDeveloperCommandContainer(const CommandContainer &cont,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
if (!userInfo) {
|
||||
return Response::RespLoginNeeded;
|
||||
}
|
||||
if (!(userInfo->user_level() & ServerInfo_User::IsDeveloper)) {
|
||||
return Response::RespLoginNeeded;
|
||||
}
|
||||
|
||||
resetIdleTimer();
|
||||
|
||||
Response::ResponseCode finalResponseCode = Response::RespOk;
|
||||
for (int i = cont.developer_command_size() - 1; i >= 0; --i) {
|
||||
Response::ResponseCode resp = Response::RespInvalidCommand;
|
||||
const DeveloperCommand &sc = cont.developer_command(i);
|
||||
const int num = getPbExtension(sc);
|
||||
logDebugMessage(getSafeDebugString(sc));
|
||||
|
||||
resp = processExtendedDeveloperCommand(num, sc, rc);
|
||||
if (resp != Response::RespOk) {
|
||||
finalResponseCode = resp;
|
||||
}
|
||||
}
|
||||
return finalResponseCode;
|
||||
}
|
||||
|
||||
void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont)
|
||||
{
|
||||
// Command processing must be disabled after prepareDestroy() has been called.
|
||||
|
|
@ -410,6 +437,8 @@ void Server_ProtocolHandler::processCommandContainer(const CommandContainer &con
|
|||
finalResponseCode = processModeratorCommandContainer(cont, responseContainer);
|
||||
} else if (cont.admin_command_size()) {
|
||||
finalResponseCode = processAdminCommandContainer(cont, responseContainer);
|
||||
} else if (cont.developer_command_size()) {
|
||||
finalResponseCode = processDeveloperCommandContainer(cont, responseContainer);
|
||||
} else {
|
||||
finalResponseCode = Response::RespInvalidCommand;
|
||||
}
|
||||
|
|
@ -454,11 +483,12 @@ void Server_ProtocolHandler::pingClockTimeout()
|
|||
prepareDestroy();
|
||||
}
|
||||
|
||||
// PrivLevel users, Moderators, and Admins are not subject to the server idle timeout policy
|
||||
// PrivLevel users, Moderators, Admins, and Developers are not subject to the server idle timeout policy
|
||||
const bool hasPrivLevel = userInfo && QString::fromStdString(userInfo->privlevel()).toLower() != "none";
|
||||
const bool isModOrAdmin =
|
||||
userInfo && (userInfo->user_level() & (ServerInfo_User::IsModerator | ServerInfo_User::IsAdmin));
|
||||
if (!hasPrivLevel && !isModOrAdmin) {
|
||||
const bool isStaff =
|
||||
userInfo && (userInfo->user_level() &
|
||||
(ServerInfo_User::IsModerator | ServerInfo_User::IsAdmin | ServerInfo_User::IsDeveloper));
|
||||
if (!hasPrivLevel && !isStaff) {
|
||||
if ((server->getIdleClientTimeout() > 0) && (idleClientWarningSent)) {
|
||||
if (timeRunning - lastActionReceived > server->getIdleClientTimeout()) {
|
||||
prepareDestroy();
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class CommandContainer;
|
|||
class SessionCommand;
|
||||
class ModeratorCommand;
|
||||
class AdminCommand;
|
||||
class DeveloperCommand;
|
||||
|
||||
class Command_Ping;
|
||||
class Command_Login;
|
||||
|
|
@ -98,6 +99,12 @@ private:
|
|||
{
|
||||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
Response::ResponseCode processDeveloperCommandContainer(const CommandContainer &cont, ResponseContainer &rc);
|
||||
virtual Response::ResponseCode
|
||||
processExtendedDeveloperCommand(int /* cmdType */, const DeveloperCommand & /* cmd */, ResponseContainer & /* rc */)
|
||||
{
|
||||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
|
||||
void resetIdleTimer();
|
||||
private slots:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue