From ff3eb9b5f414f15ff2f1bf3ddd167fcbb674b1c4 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 1 Jan 2012 19:38:52 +0100 Subject: [PATCH] display reason for ban to banned user --- cockatrice/src/abstractclient.h | 2 +- cockatrice/src/localserver.h | 2 +- cockatrice/src/remoteclient.cpp | 4 +- cockatrice/src/userlist.cpp | 15 ++++++- cockatrice/src/userlist.h | 3 +- cockatrice/src/window_main.cpp | 25 ++++++----- cockatrice/src/window_main.h | 2 +- common/pb/proto/event_connection_closed.proto | 9 +++- common/pb/proto/moderator_commands.proto | 1 + common/pb/proto/response.proto | 1 + common/pb/proto/response_login.proto | 1 + common/server.cpp | 6 +-- common/server.h | 6 +-- common/server_protocolhandler.cpp | 43 +++++++++++-------- servatrice/servatrice.pro | 3 +- servatrice/servatrice.sql | 1 + servatrice/src/servatrice.cpp | 22 +++++----- servatrice/src/servatrice.h | 2 +- servatrice/src/serversocketinterface.cpp | 9 ++-- 19 files changed, 98 insertions(+), 59 deletions(-) diff --git a/cockatrice/src/abstractclient.h b/cockatrice/src/abstractclient.h index 49e196a4..86bd8266 100644 --- a/cockatrice/src/abstractclient.h +++ b/cockatrice/src/abstractclient.h @@ -36,7 +36,7 @@ class AbstractClient : public QObject { Q_OBJECT signals: void statusChanged(ClientStatus _status); - void serverError(Response::ResponseCode resp); + void serverError(Response::ResponseCode resp, QString reasonStr); // Room events void roomEventReceived(const RoomEvent &event); diff --git a/cockatrice/src/localserver.h b/cockatrice/src/localserver.h index 6b87fcd7..23f3f68b 100644 --- a/cockatrice/src/localserver.h +++ b/cockatrice/src/localserver.h @@ -11,7 +11,7 @@ class LocalServer : public Server public: LocalServer(QObject *parent = 0); ~LocalServer(); - AuthenticationResult checkUserPassword(Server_ProtocolHandler * /*handler*/, const QString & /*user*/, const QString & /*password*/) { return UnknownUser; } + AuthenticationResult checkUserPassword(Server_ProtocolHandler * /*handler*/, const QString & /*user*/, const QString & /*password*/, QString & /*reasonStr*/) { return UnknownUser; } QString getLoginMessage() const { return QString(); } bool getGameShouldPing() const { return false; } int getMaxGameInactivityTime() const { return 9999999; } diff --git a/cockatrice/src/remoteclient.cpp b/cockatrice/src/remoteclient.cpp index 8015e189..2db6d2c8 100644 --- a/cockatrice/src/remoteclient.cpp +++ b/cockatrice/src/remoteclient.cpp @@ -56,8 +56,8 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica void RemoteClient::loginResponse(const Response &response) { + const Response_Login &resp = response.GetExtension(Response_Login::ext); if (response.response_code() == Response::RespOk) { - const Response_Login &resp = response.GetExtension(Response_Login::ext); setStatus(StatusLoggedIn); emit userInfoChanged(resp.user_info()); @@ -71,7 +71,7 @@ void RemoteClient::loginResponse(const Response &response) ignoreList.append(resp.ignore_list(i)); emit ignoreListReceived(ignoreList); } else { - emit serverError(response.response_code()); + emit serverError(response.response_code(), QString::fromStdString(resp.denied_reason_str())); setStatus(StatusDisconnecting); } } diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index 0b9593c9..d87b95dd 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -81,6 +81,9 @@ BanDialog::BanDialog(const ServerInfo_User &info, QWidget *parent) QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person.")); reasonEdit = new QPlainTextEdit; + QLabel *visibleReasonLabel = new QLabel(tr("Please enter the reason for the ban that will be visible to the banned person.")); + visibleReasonEdit = new QPlainTextEdit; + QPushButton *okButton = new QPushButton(tr("&OK")); okButton->setAutoDefault(true); connect(okButton, SIGNAL(clicked()), this, SLOT(okClicked())); @@ -97,6 +100,8 @@ BanDialog::BanDialog(const ServerInfo_User &info, QWidget *parent) vbox->addWidget(durationGroupBox); vbox->addWidget(reasonLabel); vbox->addWidget(reasonEdit); + vbox->addWidget(visibleReasonLabel); + vbox->addWidget(visibleReasonEdit); vbox->addLayout(buttonLayout); setLayout(vbox); @@ -142,6 +147,11 @@ QString BanDialog::getReason() const return reasonEdit->toPlainText(); } +QString BanDialog::getVisibleReason() const +{ + return visibleReasonEdit->toPlainText(); +} + UserListItemDelegate::UserListItemDelegate(QObject *const parent) : QStyledItemDelegate(parent) { @@ -344,6 +354,7 @@ void UserList::banUser_dialogFinished() cmd.set_address(dlg->getBanIP().toStdString()); cmd.set_minutes(dlg->getMinutes()); cmd.set_reason(dlg->getReason().toStdString()); + cmd.set_visible_reason(dlg->getVisibleReason().toStdString()); client->sendCommand(client->prepareModeratorCommand(cmd)); } @@ -418,7 +429,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(ProtocolResponse *)), this, SLOT(gamesOfUserReceived(ProtocolResponse *))); + connect(pend, SIGNAL(finished(const Response &)), this, SLOT(gamesOfUserReceived(const Response &))); client->sendCommand(pend); } else if (actionClicked == aAddToIgnoreList) { @@ -438,7 +449,7 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) cmd.set_user_name(userName.toStdString()); PendingCommand *pend = client->prepareSessionCommand(cmd); - connect(pend, SIGNAL(finished(ProtocolResponse *)), this, SLOT(banUser_processUserInfoResponse(ProtocolResponse *))); + connect(pend, SIGNAL(finished(const Response &)), this, SLOT(banUser_processUserInfoResponse(const Response &))); client->sendCommand(pend); } diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h index 360a1242..fae319fa 100644 --- a/cockatrice/src/userlist.h +++ b/cockatrice/src/userlist.h @@ -25,7 +25,7 @@ private: QLineEdit *nameBanEdit, *ipBanEdit; QSpinBox *daysEdit, *hoursEdit, *minutesEdit; QRadioButton *permanentRadio, *temporaryRadio; - QPlainTextEdit *reasonEdit; + QPlainTextEdit *reasonEdit, *visibleReasonEdit; private slots: void okClicked(); void enableTemporaryEdits(bool enabled); @@ -35,6 +35,7 @@ public: QString getBanIP() const; int getMinutes() const; QString getReason() const; + QString getVisibleReason() const; }; class UserListItemDelegate : public QStyledItemDelegate { diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 051cdc84..b31bd000 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -53,17 +53,19 @@ void MainWindow::updateTabMenu(QMenu *menu) void MainWindow::processConnectionClosedEvent(const Event_ConnectionClosed &event) { - QString reason = QString::fromStdString(event.reason()); client->disconnectFromServer(); QString reasonStr; - if (reason == "too_many_connections") - reasonStr = tr("There are too many concurrent connections from your address."); - else if (reason == "banned") - reasonStr = tr("Banned by moderator."); - else if (reason == "server_shutdown") - reasonStr = tr("Scheduled server shutdown."); - else - reasonStr = tr("Unknown reason."); + switch (event.reason()) { + case Event_ConnectionClosed::TOO_MANY_CONNECTIONS: reasonStr = tr("There are too many concurrent connections from your address."); break; + case Event_ConnectionClosed::BANNED: { + reasonStr = tr("Banned by moderator"); + if (event.has_reason_str()) + reasonStr.append("\n\n" + QString::fromStdString(event.reason_str())); + break; + } + case Event_ConnectionClosed::SERVER_SHUTDOWN: reasonStr = tr("Scheduled server shutdown."); break; + default: reasonStr = QString::fromStdString(event.reason_str()); + } QMessageBox::critical(this, tr("Connection closed"), tr("The server has terminated your connection.\nReason: %1").arg(reasonStr)); } @@ -201,11 +203,12 @@ void MainWindow::serverTimeout() QMessageBox::critical(this, tr("Error"), tr("Server timeout")); } -void MainWindow::serverError(Response::ResponseCode r) +void MainWindow::serverError(Response::ResponseCode r, QString reasonStr) { switch (r) { case Response::RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Invalid login data.")); break; case Response::RespWouldOverwriteOldSession: QMessageBox::critical(this, tr("Error"), tr("There is already an active session using this user name.\nPlease close that session first and re-login.")); break; + case Response::RespUserIsBanned: QMessageBox::critical(this, tr("Error"), tr("You are banned.\n%1").arg(reasonStr)); break; default: ; } } @@ -304,7 +307,7 @@ MainWindow::MainWindow(QWidget *parent) client = new RemoteClient(this); connect(client, SIGNAL(connectionClosedEventReceived(const Event_ConnectionClosed &)), this, SLOT(processConnectionClosedEvent(const Event_ConnectionClosed &))); connect(client, SIGNAL(serverShutdownEventReceived(const Event_ServerShutdown &)), this, SLOT(processServerShutdownEvent(const Event_ServerShutdown &))); - connect(client, SIGNAL(serverError(Response::ResponseCode)), this, SLOT(serverError(Response::ResponseCode))); + connect(client, SIGNAL(serverError(Response::ResponseCode, QString)), this, SLOT(serverError(Response::ResponseCode, QString))); connect(client, SIGNAL(socketError(const QString &)), this, SLOT(socketError(const QString &))); connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus))); diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index e223d7c4..83307d37 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -38,7 +38,7 @@ private slots: void processConnectionClosedEvent(const Event_ConnectionClosed &event); void processServerShutdownEvent(const Event_ServerShutdown &event); void serverTimeout(); - void serverError(Response::ResponseCode r); + void serverError(Response::ResponseCode r, QString reasonStr); void socketError(const QString &errorStr); void protocolVersionMismatch(int localVersion, int remoteVersion); void userInfoReceived(const ServerInfo_User &userInfo); diff --git a/common/pb/proto/event_connection_closed.proto b/common/pb/proto/event_connection_closed.proto index 4b92fae8..9908c84e 100644 --- a/common/pb/proto/event_connection_closed.proto +++ b/common/pb/proto/event_connection_closed.proto @@ -4,5 +4,12 @@ message Event_ConnectionClosed { extend SessionEvent { optional Event_ConnectionClosed ext = 1002; } - optional string reason = 1; + enum CloseReason { + OTHER = 1; + SERVER_SHUTDOWN = 2; + TOO_MANY_CONNECTIONS = 3; + BANNED = 4; + } + optional CloseReason reason = 1; + optional string reason_str = 2; } diff --git a/common/pb/proto/moderator_commands.proto b/common/pb/proto/moderator_commands.proto index 2ef616a1..18324ef1 100644 --- a/common/pb/proto/moderator_commands.proto +++ b/common/pb/proto/moderator_commands.proto @@ -13,4 +13,5 @@ message Command_BanFromServer { optional string address = 2; optional uint32 minutes = 3; optional string reason = 4; + optional string visible_reason = 5; } diff --git a/common/pb/proto/response.proto b/common/pb/proto/response.proto index 18813559..d3f680c9 100644 --- a/common/pb/proto/response.proto +++ b/common/pb/proto/response.proto @@ -19,6 +19,7 @@ message Response { RespInIgnoreList = 16; RespWouldOverwriteOldSession = 17; RespChatFlood = 18; + RespUserIsBanned = 19; } enum ResponseType { JOIN_ROOM = 1000; diff --git a/common/pb/proto/response_login.proto b/common/pb/proto/response_login.proto index 09a8835c..f79b4194 100644 --- a/common/pb/proto/response_login.proto +++ b/common/pb/proto/response_login.proto @@ -8,4 +8,5 @@ message Response_Login { optional ServerInfo_User user_info = 1; repeated ServerInfo_User buddy_list = 2; repeated ServerInfo_User ignore_list = 3; + optional string denied_reason_str = 4; } diff --git a/common/server.cpp b/common/server.cpp index 762c0874..5be3b6f8 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -49,13 +49,13 @@ void Server::prepareDestroy() delete roomIterator.next().value(); } -AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password) +AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr) { QMutexLocker locker(&serverMutex); if (name.size() > 35) name = name.left(35); - AuthenticationResult authState = checkUserPassword(session, name, password); - if (authState == PasswordWrong) + AuthenticationResult authState = checkUserPassword(session, name, password, reasonStr); + if ((authState == NotLoggedIn) || (authState == UserIsBanned)) return authState; ServerInfo_User data = getUserData(name); diff --git a/common/server.h b/common/server.h index 6bda9fb5..45d76481 100644 --- a/common/server.h +++ b/common/server.h @@ -11,7 +11,7 @@ class Server_Game; class Server_Room; class Server_ProtocolHandler; -enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3 }; +enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3, UserIsBanned = 4 }; class Server : public QObject { @@ -24,7 +24,7 @@ public: mutable QMutex serverMutex; Server(QObject *parent = 0); ~Server(); - AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password); + AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason); const QMap &getRooms() { return rooms; } int getNextGameId() { return nextGameId++; } @@ -55,7 +55,7 @@ protected: virtual int startSession(const QString &userName, const QString &address) = 0; virtual void endSession(int sessionId) = 0; virtual bool userExists(const QString &user) = 0; - virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0; + virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reason) = 0; virtual ServerInfo_User getUserData(const QString &name) = 0; int getUsersCount() const; int getGamesCount() const; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index f0eaaf69..293649e5 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -85,7 +85,7 @@ #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) - : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive) + : QObject(parent), server(_server), authState(NotLoggedIn), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive) { connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); } @@ -247,7 +247,7 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; Server_Room *room = rooms.value(cont.room_id(), 0); @@ -282,7 +282,7 @@ Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; gameListMutex.lock(); @@ -493,11 +493,19 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd QString userName = QString::fromStdString(cmd.user_name()).simplified(); if (userName.isEmpty() || (userInfo != 0)) return Response::RespContextError; - authState = server->loginUser(this, userName, QString::fromStdString(cmd.password())); - if (authState == PasswordWrong) - return Response::RespWrongPassword; - if (authState == WouldOverwriteOldSession) - return Response::RespWouldOverwriteOldSession; + QString reasonStr; + AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr); + switch (res) { + case UserIsBanned: { + Response_Login *re = new Response_Login; + re->set_denied_reason_str(reasonStr.toStdString()); + rc.setResponseExtension(re); + return Response::RespUserIsBanned; + } + case NotLoggedIn: return Response::RespWrongPassword; + case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession; + default: authState = res; + } userName = QString::fromStdString(userInfo->name()); Event_ServerMessage event; @@ -505,8 +513,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); Response_Login *re = new Response_Login; - // XXX stimmt so nicht, beim alten Kopierkonstruktor wurde hier "true" übergeben - re->mutable_user_info()->CopyFrom(*userInfo); + re->mutable_user_info()->CopyFrom(copyUserInfo(true)); if (authState == PasswordRight) { QMapIterator buddyIterator(server->getBuddyList(userName)); @@ -569,7 +576,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; QString receiver = QString::fromStdString(cmd.user_name()); @@ -592,7 +599,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; server->serverMutex.lock(); @@ -618,7 +625,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_G Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; QString userName = QString::fromStdString(cmd.user_name()); @@ -638,7 +645,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetU Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; Event_ListRooms event; @@ -653,7 +660,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRo Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; if (rooms.contains(cmd.room_id())) @@ -681,7 +688,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoo Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUsers & /*cmd*/, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; Response_ListUsers *re = new Response_ListUsers; @@ -731,7 +738,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; if (server->getMaxGamesPerUser() > 0) @@ -779,7 +786,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_Creat Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == PasswordWrong) + if (authState == NotLoggedIn) return Response::RespLoginNeeded; QMutexLocker gameListLocker(&gameListMutex); diff --git a/servatrice/servatrice.pro b/servatrice/servatrice.pro index b702c3ed..edd37d00 100755 --- a/servatrice/servatrice.pro +++ b/servatrice/servatrice.pro @@ -9,8 +9,9 @@ INCLUDEPATH += . src ../common MOC_DIR = build OBJECTS_DIR = build LIBS += -lgcrypt -lprotobuf +QMAKE_CXXFLAGS_RELEASE += -O2 -CONFIG += qt debug +CONFIG += qt QT += network sql QT -= gui diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 192cdef7..9beaf334 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -157,6 +157,7 @@ CREATE TABLE `cockatrice_bans` ( `time_from` datetime NOT NULL, `minutes` int(6) NOT NULL, `reason` text NOT NULL, + `visible_reason` text NOT NULL, PRIMARY KEY (`user_name`,`time_from`), KEY `time_from` (`time_from`,`ip_address`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 4ea857a7..9702ce87 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -167,7 +167,7 @@ bool Servatrice::execSqlQuery(QSqlQuery &query) return false; } -AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) +AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr) { QMutexLocker locker(&dbMutex); const QString method = settings->value("authentication/method").toString(); @@ -177,33 +177,35 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl checkSql(); QSqlQuery ipBanQuery; - ipBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_bans b where b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.ip_address = :address) and b.ip_address = :address2"); + ipBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0, b.visible_reason from " + dbPrefix + "_bans b where b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.ip_address = :address) and b.ip_address = :address2"); ipBanQuery.bindValue(":address", static_cast(handler)->getPeerAddress().toString()); ipBanQuery.bindValue(":address2", static_cast(handler)->getPeerAddress().toString()); if (!execSqlQuery(ipBanQuery)) { qDebug("Login denied: SQL error"); - return PasswordWrong; + return NotLoggedIn; } if (ipBanQuery.next()) if (ipBanQuery.value(0).toInt() || ipBanQuery.value(1).toInt()) { + reasonStr = ipBanQuery.value(2).toString(); qDebug("Login denied: banned by address"); - return PasswordWrong; + return UserIsBanned; } QSqlQuery nameBanQuery; - nameBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0 from " + dbPrefix + "_bans b where b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.user_name = :name2) and b.user_name = :name1"); + nameBanQuery.prepare("select time_to_sec(timediff(now(), date_add(b.time_from, interval b.minutes minute))) < 0, b.minutes <=> 0, b.visible_reason from " + dbPrefix + "_bans b where b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.user_name = :name2) and b.user_name = :name1"); nameBanQuery.bindValue(":name1", user); nameBanQuery.bindValue(":name2", user); if (!execSqlQuery(nameBanQuery)) { qDebug("Login denied: SQL error"); - return PasswordWrong; + return NotLoggedIn; } if (nameBanQuery.next()) if (nameBanQuery.value(0).toInt() || nameBanQuery.value(1).toInt()) { + reasonStr = nameBanQuery.value(2).toString(); qDebug("Login denied: banned by name"); - return PasswordWrong; + return UserIsBanned; } QSqlQuery passwordQuery; @@ -211,7 +213,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl passwordQuery.bindValue(":name", user); if (!execSqlQuery(passwordQuery)) { qDebug("Login denied: SQL error"); - return PasswordWrong; + return NotLoggedIn; } if (passwordQuery.next()) { @@ -221,7 +223,7 @@ AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handl return PasswordRight; } else { qDebug("Login denied: password wrong"); - return PasswordWrong; + return NotLoggedIn; } } else { qDebug("Login accepted: unknown user"); @@ -527,7 +529,7 @@ void Servatrice::shutdownTimeout() se = Server_ProtocolHandler::prepareSessionEvent(event); } else { Event_ConnectionClosed event; - event.set_reason("server_shutdown"); + event.set_reason(Event_ConnectionClosed::SERVER_SHUTDOWN); se = Server_ProtocolHandler::prepareSessionEvent(event); } diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 01038ee4..69f306a3 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -85,7 +85,7 @@ protected: int startSession(const QString &userName, const QString &address); void endSession(int sessionId); bool userExists(const QString &user); - AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password); + AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr); private: QTimer *pingClock, *statusUpdateClock; QTcpServer *tcpServer; diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 037c26fa..d7e2726e 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -65,7 +65,7 @@ ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_s int maxUsers = _server->getMaxUsersPerAddress(); if ((maxUsers > 0) && (_server->getUsersWithAddress(socket->peerAddress()) >= maxUsers)) { Event_ConnectionClosed event; - event.set_reason("too_many_connections"); + event.set_reason(Event_ConnectionClosed::TOO_MANY_CONNECTIONS); SessionEvent *se = prepareSessionEvent(event); sendProtocolItem(*se); delete se; @@ -482,19 +482,22 @@ Response::ResponseCode ServerSocketInterface::cmdBanFromServer(const Command_Ban servatrice->dbMutex.lock(); QSqlQuery query; - query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (user_name, ip_address, id_admin, time_from, minutes, reason) values(:user_name, :ip_address, :id_admin, NOW(), :minutes, :reason)"); + query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (user_name, ip_address, id_admin, time_from, minutes, reason, visible_reason) values(:user_name, :ip_address, :id_admin, NOW(), :minutes, :reason, :visible_reason)"); query.bindValue(":user_name", userName); query.bindValue(":ip_address", address); query.bindValue(":id_admin", servatrice->getUserIdInDB(QString::fromStdString(userInfo->name()))); query.bindValue(":minutes", minutes); query.bindValue(":reason", QString::fromStdString(cmd.reason()) + "\n"); + query.bindValue(":visible_reason", QString::fromStdString(cmd.visible_reason()) + "\n"); servatrice->execSqlQuery(query); servatrice->dbMutex.unlock(); ServerSocketInterface *user = static_cast(server->getUsers().value(userName)); if (user) { Event_ConnectionClosed event; - event.set_reason("banned"); + event.set_reason(Event_ConnectionClosed::BANNED); + if (cmd.has_visible_reason()) + event.set_reason_str(cmd.visible_reason()); SessionEvent *se = user->prepareSessionEvent(event); user->sendProtocolItem(*se); delete se;