Commit 05ebb83b authored by Max-Wilhelm Bruker's avatar Max-Wilhelm Bruker
Browse files

improved banning; added [url] and [card] tags for chat

parent 4b84168b
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -484,11 +484,12 @@ Command_ShutdownServer::Command_ShutdownServer(const QString &_reason, int _minu
insertItem(new SerializableItem_String("reason", _reason));
insertItem(new SerializableItem_Int("minutes", _minutes));
}
Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes)
Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes, const QString &_reason)
: ModeratorCommand("ban_from_server")
{
insertItem(new SerializableItem_String("user_name", _userName));
insertItem(new SerializableItem_Int("minutes", _minutes));
insertItem(new SerializableItem_String("reason", _reason));
}
void ProtocolItem::initializeHashAuto()
{
......
......@@ -80,4 +80,4 @@
6:mulligan:i,number
7:update_server_message
7:shutdown_server:s,reason:i,minutes
8:ban_from_server:s,user_name:i,minutes
\ No newline at end of file
8:ban_from_server:s,user_name:i,minutes:s,reason
\ No newline at end of file
......@@ -735,9 +735,10 @@ public:
class Command_BanFromServer : public ModeratorCommand {
Q_OBJECT
public:
Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1);
Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1, const QString &_reason = QString());
QString getUserName() const { return static_cast<SerializableItem_String *>(itemMap.value("user_name"))->getData(); };
int getMinutes() const { return static_cast<SerializableItem_Int *>(itemMap.value("minutes"))->getData(); };
QString getReason() const { return static_cast<SerializableItem_String *>(itemMap.value("reason"))->getData(); };
static SerializableItem *newItem() { return new Command_BanFromServer; }
int getItemId() const { return ItemId_Command_BanFromServer; }
};
......
......@@ -52,7 +52,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
QMutexLocker locker(&serverMutex);
if (name.size() > 35)
name = name.left(35);
AuthenticationResult authState = checkUserPassword(name, password);
AuthenticationResult authState = checkUserPassword(session, name, password);
if (authState == PasswordWrong)
return authState;
......
......@@ -43,7 +43,6 @@ public:
virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0;
virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0;
virtual bool getUserBanned(Server_ProtocolHandler * /*client*/, const QString & /*userName*/) const { return false; }
protected:
void prepareDestroy();
QList<Server_ProtocolHandler *> clients;
......@@ -51,7 +50,7 @@ protected:
QMap<int, Server_Room *> rooms;
virtual bool userExists(const QString &user) = 0;
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0;
virtual ServerInfo_User *getUserData(const QString &name) = 0;
int getUsersCount() const;
int getGamesCount() const;
......
......@@ -280,8 +280,6 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
QString userName = cmd->getUsername().simplified();
if (userName.isEmpty() || (userInfo != 0))
return RespContextError;
if (server->getUserBanned(this, userName))
return RespWrongPassword;
authState = server->loginUser(this, userName, cmd->getPassword());
if (authState == PasswordWrong)
return RespWrongPassword;
......
......@@ -111,7 +111,6 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` (
`avatar_bmp` blob NOT NULL,
`registrationDate` datetime NOT NULL,
`active` tinyint(1) NOT NULL,
`banned` tinyint(1) NOT NULL,
`token` char(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
......@@ -149,3 +148,12 @@ CREATE TABLE `cockatrice_buddylist` (
KEY `id_user2` (`id_user2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `cockatrice_bans` (
`id_user` int(7) unsigned zerofill NOT NULL,
`id_admin` int(7) unsigned zerofill NOT NULL,
`time_from` datetime NOT NULL,
`minutes` int(6) NOT NULL,
`reason` text NOT NULL,
KEY `id_user` (`id_user`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
......@@ -169,25 +169,32 @@ bool Servatrice::execSqlQuery(QSqlQuery &query)
return false;
}
AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QString &password)
AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password)
{
serverMutex.lock();
QHostAddress address = static_cast<ServerSocketInterface *>(handler)->getPeerAddress();
for (int i = 0; i < addressBanList.size(); ++i)
if (address == addressBanList[i].first)
return PasswordWrong;
serverMutex.unlock();
QMutexLocker locker(&dbMutex);
const QString method = settings->value("authentication/method").toString();
if (method == "none")
return UnknownUser;
else if (method == "sql") {
checkSql();
QSqlQuery query;
query.prepare("select banned, password from " + dbPrefix + "_users where name = :name and active = 1");
query.prepare("select a.password, timediff(now(), date_add(b.time_from, interval b.minutes minute)) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1");
query.bindValue(":name", user);
if (!execSqlQuery(query))
return PasswordWrong;
if (query.next()) {
if (query.value(0).toInt())
if (query.value(1).toInt() || query.value(2).toInt())
return PasswordWrong;
if (query.value(1).toString() == password)
if (query.value(0).toString() == password)
return PasswordRight;
else
return PasswordWrong;
......@@ -325,19 +332,6 @@ QMap<QString, ServerInfo_User *> Servatrice::getIgnoreList(const QString &name)
return result;
}
bool Servatrice::getUserBanned(Server_ProtocolHandler *client, const QString &userName) const
{
QMutexLocker locker(&serverMutex);
QHostAddress address = static_cast<ServerSocketInterface *>(client)->getPeerAddress();
for (int i = 0; i < addressBanList.size(); ++i)
if (address == addressBanList[i].first)
return true;
for (int i = 0; i < nameBanList.size(); ++i)
if (userName == nameBanList[i].first)
return true;
return false;
}
void Servatrice::updateBanTimer()
{
QMutexLocker locker(&serverMutex);
......@@ -346,11 +340,6 @@ void Servatrice::updateBanTimer()
addressBanList.removeAt(i);
else
++i;
for (int i = 0; i < nameBanList.size(); )
if (--(nameBanList[i].second) <= 0)
nameBanList.removeAt(i);
else
++i;
}
void Servatrice::updateLoginMessage()
......
......@@ -74,13 +74,11 @@ public:
int getUsersWithAddress(const QHostAddress &address) const;
QMap<QString, ServerInfo_User *> getBuddyList(const QString &name);
QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name);
bool getUserBanned(Server_ProtocolHandler *client, const QString &userName) const;
void addAddressBan(const QHostAddress &address, int minutes) { addressBanList.append(QPair<QHostAddress, int>(address, minutes)); }
void addNameBan(const QString &name, int minutes) { nameBanList.append(QPair<QString, int>(name, minutes)); }
void scheduleShutdown(const QString &reason, int minutes);
protected:
bool userExists(const QString &user);
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password);
private:
QTimer *pingClock, *statusUpdateClock, *banTimeoutClock;
QTcpServer *tcpServer;
......@@ -90,7 +88,6 @@ private:
int serverId;
int uptime;
QList<QPair<QHostAddress, int> > addressBanList;
QList<QPair<QString, int> > nameBanList;
int maxGameInactivityTime, maxPlayerInactivityTime;
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser;
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
......
......@@ -488,14 +488,14 @@ ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd,
ServerSocketInterface *user = static_cast<ServerSocketInterface *>(server->getUsers().value(userName));
if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) {
// Registered users can be banned by name.
if (minutes == 0) {
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query;
query.prepare("update " + servatrice->getDbPrefix() + "_users set banned=1 where name = :name");
query.bindValue(":name", userName);
servatrice->execSqlQuery(query);
} else
servatrice->addNameBan(userName, minutes);
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query;
query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (id_user, id_admin, time_from, minutes, reason) values(:id_user, :id_admin, NOW(), :minutes, :reason)");
query.bindValue(":id_user", getUserIdInDB(userName));
query.bindValue(":id_admin", getUserIdInDB(userInfo->getName()));
query.bindValue(":minutes", minutes);
query.bindValue(":reason", cmd->getReason());
servatrice->execSqlQuery(query);
} else {
// Unregistered users must be banned by IP address.
// Indefinite address bans are not reasonable -> default to 30 minutes.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment