mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 03:53:26 -08:00
206 lines
6.5 KiB
C++
206 lines
6.5 KiB
C++
/** @file server_forced_password_change_test.cpp
|
|
* @brief Tests for the restricted session a forced password change leaves behind at login.
|
|
* @ingroup Tests
|
|
*/
|
|
|
|
#include "libcockatrice/protocol/pb/response.pb.h"
|
|
#include "libcockatrice/protocol/pb/server_message.pb.h"
|
|
#include "libcockatrice/server/dev/servatrice_in_memory_database_interface.h"
|
|
#include "server.h"
|
|
#include "server_protocolhandler.h"
|
|
|
|
#include <QString>
|
|
#include <gtest/gtest.h>
|
|
#include <libcockatrice/protocol/pb/commands.pb.h>
|
|
#include <libcockatrice/protocol/pb/room_commands.pb.h>
|
|
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
|
#include <libcockatrice/protocol/pb/session_commands.pb.h>
|
|
#include <libcockatrice/rng/rng_abstract.h>
|
|
|
|
RNG_Abstract *rng = nullptr; // referenced by the server_remote library
|
|
|
|
namespace
|
|
{
|
|
|
|
class FakeServer : public Server
|
|
{
|
|
public:
|
|
FakeServer()
|
|
{
|
|
auto *db = new Servatrice_InMemoryDatabaseInterface();
|
|
db->setAuthenticationResult(PasswordChangeRequired);
|
|
|
|
ServerInfo_User user;
|
|
user.set_name("mod");
|
|
user.set_user_level(ServerInfo_User::IsUser | ServerInfo_User::IsRegistered | ServerInfo_User::IsModerator);
|
|
user.set_id(1);
|
|
db->addUser(user);
|
|
|
|
setDatabaseInterface(db);
|
|
}
|
|
};
|
|
|
|
class TestHandler : public Server_ProtocolHandler
|
|
{
|
|
public:
|
|
TestHandler(Server *_server, Server_DatabaseInterface *_db) : Server_ProtocolHandler(_server, _db)
|
|
{
|
|
}
|
|
|
|
QString getAddress() const override
|
|
{
|
|
return {};
|
|
}
|
|
QString getConnectionType() const override
|
|
{
|
|
return {};
|
|
}
|
|
|
|
Response::ResponseCode lastResponseCode = Response::RespNothing;
|
|
int lastExtendedSessionCommand = -1;
|
|
|
|
protected:
|
|
Response::ResponseCode
|
|
processExtendedSessionCommand(int cmdType, const SessionCommand & /*cmd*/, ResponseContainer & /*rc*/) override
|
|
{
|
|
lastExtendedSessionCommand = cmdType;
|
|
return Response::RespOk;
|
|
}
|
|
|
|
void transmitProtocolItem(const ServerMessage &item) override
|
|
{
|
|
if (item.message_type() == ServerMessage::RESPONSE) {
|
|
lastResponseCode = item.response().response_code();
|
|
}
|
|
}
|
|
};
|
|
|
|
class ForcedPasswordChangeTest : public ::testing::Test
|
|
{
|
|
protected:
|
|
FakeServer server;
|
|
TestHandler handler{&server, server.getDatabaseInterface()};
|
|
|
|
void login()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(1);
|
|
Command_Login cmd;
|
|
cmd.set_user_name("mod");
|
|
cont.add_session_command()->MutableExtension(Command_Login::ext)->CopyFrom(cmd);
|
|
handler.processCommandContainer(cont);
|
|
}
|
|
|
|
Response::ResponseCode sendPing()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(2);
|
|
cont.add_session_command()->MutableExtension(Command_Ping::ext);
|
|
handler.processCommandContainer(cont);
|
|
return handler.lastResponseCode;
|
|
}
|
|
|
|
Response::ResponseCode sendSessionCommand()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(3);
|
|
cont.add_session_command()->MutableExtension(Command_ListRooms::ext);
|
|
handler.processCommandContainer(cont);
|
|
return handler.lastResponseCode;
|
|
}
|
|
|
|
Response::ResponseCode sendRoomCommand()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(4);
|
|
cont.add_room_command()->MutableExtension(Command_RoomSay::ext)->set_message("hello");
|
|
handler.processCommandContainer(cont);
|
|
return handler.lastResponseCode;
|
|
}
|
|
|
|
Response::ResponseCode sendMixedSessionAndRoomCommand()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(5);
|
|
cont.add_session_command()->MutableExtension(Command_Ping::ext);
|
|
cont.add_room_command()->MutableExtension(Command_RoomSay::ext)->set_message("hello");
|
|
handler.processCommandContainer(cont);
|
|
return handler.lastResponseCode;
|
|
}
|
|
|
|
Response::ResponseCode sendAccountPassword()
|
|
{
|
|
CommandContainer cont;
|
|
cont.set_cmd_id(6);
|
|
Command_AccountPassword cmd;
|
|
cmd.set_old_password("temporary-password");
|
|
cmd.set_new_password("replacement-password");
|
|
cont.add_session_command()->MutableExtension(Command_AccountPassword::ext)->CopyFrom(cmd);
|
|
handler.processCommandContainer(cont);
|
|
return handler.lastResponseCode;
|
|
}
|
|
};
|
|
|
|
TEST_F(ForcedPasswordChangeTest, LoginReportsTheRequiredChange)
|
|
{
|
|
login();
|
|
|
|
EXPECT_EQ(Response::RespPasswordChangeRequired, handler.lastResponseCode);
|
|
ASSERT_NE(nullptr, handler.getUserInfo());
|
|
EXPECT_EQ("mod", QString::fromStdString(handler.getUserInfo()->name()));
|
|
}
|
|
|
|
TEST_F(ForcedPasswordChangeTest, PendingSessionIsNotRegisteredAsAUser)
|
|
{
|
|
login();
|
|
// The session may change its password, but it must not take a user slot or appear in
|
|
// the session table before the client reconnects with the new password.
|
|
EXPECT_FALSE(handler.getUserInfo()->has_session_id());
|
|
EXPECT_EQ(0, server.getUsersCount());
|
|
}
|
|
|
|
TEST_F(ForcedPasswordChangeTest, PendingModeratorIsNotReportedOnline)
|
|
{
|
|
login();
|
|
server.addClient(&handler);
|
|
|
|
EXPECT_TRUE(server.getOnlineModeratorList().isEmpty());
|
|
}
|
|
|
|
TEST_F(ForcedPasswordChangeTest, OnlyPingAndPasswordChangeAreServed)
|
|
{
|
|
login();
|
|
|
|
EXPECT_EQ(Response::RespOk, sendPing());
|
|
EXPECT_EQ(Response::RespFunctionNotAllowed, sendSessionCommand());
|
|
EXPECT_EQ(Response::RespFunctionNotAllowed, sendRoomCommand());
|
|
// Dispatch prefers game/room over session, so a container carrying both must not slip past
|
|
// the restriction by carrying a session command.
|
|
EXPECT_EQ(Response::RespFunctionNotAllowed, sendMixedSessionAndRoomCommand());
|
|
}
|
|
|
|
TEST_F(ForcedPasswordChangeTest, AccountPasswordReachesTheCommand)
|
|
{
|
|
login();
|
|
// The forced change is useless if the gate refuses the command it needs. ACCOUNT_PASSWORD is
|
|
// served by the extended-command hook, so it must arrive there instead of being filtered.
|
|
EXPECT_EQ(Response::RespOk, sendAccountPassword());
|
|
EXPECT_EQ(SessionCommand::ACCOUNT_PASSWORD, handler.lastExtendedSessionCommand);
|
|
}
|
|
|
|
TEST_F(ForcedPasswordChangeTest, CompletedLoginIsStillReportedOnline)
|
|
{
|
|
TestHandler loggedIn{&server, server.getDatabaseInterface()};
|
|
ServerInfo_User user;
|
|
user.set_name("online-mod");
|
|
user.set_user_level(ServerInfo_User::IsUser | ServerInfo_User::IsRegistered | ServerInfo_User::IsModerator);
|
|
user.set_session_id(7);
|
|
loggedIn.setUserInfo(user);
|
|
server.addClient(&loggedIn);
|
|
|
|
const QList<QString> moderators = server.getOnlineModeratorList();
|
|
ASSERT_EQ(1, moderators.size());
|
|
EXPECT_EQ("online-mod", moderators.first());
|
|
}
|
|
|
|
} // namespace
|