mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-05 09:33:25 -08:00
[Report] Add report reopen action for closed reports (#7442)
- New Command_ReportReopen moderator command (extension 1206) with server handler that reopens resolved/dismissed reports, resets resolution state and notified, and records the reopening note in the audit log - Reopen... button in the report queue action bar, gated to resolved and dismissed reports, with optional note prompt and tooltip - Success confirmations for Assign, Resolve/Dismiss and Reopen now survive the list refresh via a pending status message instead of being clobbered - Dispatch/auth coverage in server_moderator_role_test Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
315cbae345
commit
4a010bd17f
9 changed files with 280 additions and 2 deletions
156
tests/server_moderator_role_test.cpp
Normal file
156
tests/server_moderator_role_test.cpp
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/** @file server_moderator_role_test.cpp
|
||||
* @brief Tests for the moderator staff role authorization and dispatch.
|
||||
* @ingroup Tests
|
||||
*/
|
||||
|
||||
#include "libcockatrice/protocol/pb/response.pb.h"
|
||||
#include "libcockatrice/protocol/pb/server_message.pb.h"
|
||||
|
||||
#include <QString>
|
||||
#include <gtest/gtest.h>
|
||||
#include <libcockatrice/network/server/remote/server.h>
|
||||
#include <libcockatrice/network/server/remote/server_protocolhandler.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_reopen.pb.h>
|
||||
#include <libcockatrice/protocol/pb/commands.pb.h>
|
||||
#include <libcockatrice/protocol/pb/moderator_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
#include <libcockatrice/rng/rng_abstract.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
// The server_remote library references the global RNG, which is normally
|
||||
// defined by the servatrice/client executable main(). Provide a stub so the
|
||||
// unit test can link against it.
|
||||
RNG_Abstract *rng = nullptr;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class TestModeratorHandler : public Server_ProtocolHandler
|
||||
{
|
||||
public:
|
||||
explicit TestModeratorHandler(Server *_server) : Server_ProtocolHandler(_server, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
QString getAddress() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
QString getConnectionType() const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Buffer the last response code sent to the client so tests can assert on
|
||||
// the outcome of processCommandContainer().
|
||||
Response::ResponseCode lastResponseCode = Response::RespNothing;
|
||||
int dispatchCount = 0;
|
||||
|
||||
protected:
|
||||
void transmitProtocolItem(const ServerMessage &item) override
|
||||
{
|
||||
if (item.message_type() == ServerMessage::RESPONSE) {
|
||||
lastResponseCode = item.response().response_code();
|
||||
}
|
||||
}
|
||||
|
||||
Response::ResponseCode
|
||||
processExtendedModeratorCommand(int cmdType, const ModeratorCommand &, ResponseContainer &) override
|
||||
{
|
||||
++dispatchCount;
|
||||
// Fail closed for anything not explicitly handled.
|
||||
if (cmdType != ModeratorCommand::REPORT_REOPEN) {
|
||||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
return Response::RespOk;
|
||||
}
|
||||
};
|
||||
|
||||
class ModeratorRoleTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
Server server;
|
||||
TestModeratorHandler handler{&server};
|
||||
|
||||
void setUserLevel(uint32_t level)
|
||||
{
|
||||
ServerInfo_User user;
|
||||
user.set_user_level(level);
|
||||
handler.setUserInfo(user);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ModeratorRoleTest, RejectsWhenNotLoggedIn)
|
||||
{
|
||||
CommandContainer cont;
|
||||
cont.add_moderator_command();
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded);
|
||||
EXPECT_EQ(handler.dispatchCount, 0);
|
||||
}
|
||||
|
||||
TEST_F(ModeratorRoleTest, RejectsPlainUser)
|
||||
{
|
||||
setUserLevel(ServerInfo_User::IsUser | ServerInfo_User::IsRegistered);
|
||||
|
||||
CommandContainer cont;
|
||||
cont.add_moderator_command();
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded);
|
||||
EXPECT_EQ(handler.dispatchCount, 0);
|
||||
}
|
||||
|
||||
TEST_F(ModeratorRoleTest, DispatchesToModeratorCommandForModerator)
|
||||
{
|
||||
setUserLevel(ServerInfo_User::IsModerator);
|
||||
|
||||
CommandContainer cont;
|
||||
ModeratorCommand *cmd = cont.add_moderator_command();
|
||||
cmd->MutableExtension(Command_ReportReopen::ext);
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespOk);
|
||||
EXPECT_EQ(handler.dispatchCount, 1);
|
||||
}
|
||||
|
||||
TEST_F(ModeratorRoleTest, DispatchesToModeratorCommandForAdmin)
|
||||
{
|
||||
setUserLevel(ServerInfo_User::IsModerator | ServerInfo_User::IsAdmin);
|
||||
|
||||
CommandContainer cont;
|
||||
ModeratorCommand *cmd = cont.add_moderator_command();
|
||||
cmd->MutableExtension(Command_ReportReopen::ext);
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespOk);
|
||||
EXPECT_EQ(handler.dispatchCount, 1);
|
||||
}
|
||||
|
||||
TEST_F(ModeratorRoleTest, RejectsDeveloperThatIsNotModerator)
|
||||
{
|
||||
setUserLevel(ServerInfo_User::IsDeveloper);
|
||||
|
||||
CommandContainer cont;
|
||||
cont.add_moderator_command();
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespLoginNeeded);
|
||||
EXPECT_EQ(handler.dispatchCount, 0);
|
||||
}
|
||||
|
||||
TEST_F(ModeratorRoleTest, FailClosedForUnknownModeratorCommand)
|
||||
{
|
||||
setUserLevel(ServerInfo_User::IsModerator);
|
||||
|
||||
CommandContainer cont;
|
||||
cont.add_moderator_command(); // no extension set -> getPbExtension() returns -1
|
||||
handler.processCommandContainer(cont);
|
||||
EXPECT_EQ(handler.lastResponseCode, Response::RespFunctionNotAllowed);
|
||||
EXPECT_EQ(handler.dispatchCount, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue