Merge pull request #34 from AttorneyOnline/recent-bans

Add /bans, /unban, and /removeuser, clean up some DB code and add additional helper functions
This commit is contained in:
scatterflower 2021-03-14 17:44:19 -05:00 committed by GitHub
commit 82960d0729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 172 additions and 23 deletions

View File

@ -193,6 +193,7 @@ class AOClient : public QObject {
void cmdChangeAuth(int argc, QStringList argv);
void cmdSetRootPass(int argc, QStringList argv);
void cmdAddUser(int argc, QStringList argv);
void cmdRemoveUser(int argc, QStringList argv);
void cmdListPerms(int argc, QStringList argv);
void cmdAddPerms(int argc, QStringList argv);
void cmdRemovePerms(int argc, QStringList argv);
@ -218,12 +219,14 @@ class AOClient : public QObject {
// Moderation
void cmdMods(int argc, QStringList argv);
void cmdBan(int argc, QStringList argv);
void cmdUnBan(int argc, QStringList argv);
void cmdKick(int argc, QStringList argv);
void cmdAnnounce(int argc, QStringList argv);
void cmdM(int argc, QStringList argv);
void cmdGM(int argc, QStringList argv);
void cmdMute(int argc, QStringList argv);
void cmdUnmute(int argc, QStringList argv);
void cmdBans(int argc, QStringList argv);
// Casing/RP
void cmdPlay(int argc, QStringList argv);
void cmdNeed(int argc, QStringList argv);
@ -317,6 +320,9 @@ class AOClient : public QObject {
{"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}},
{"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}},
{"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnmute}},
{"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}},
{"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}},
{"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}},
{"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}},
};

View File

@ -39,11 +39,25 @@ public:
QString getBanReason(QHostAddress ip);
QString getBanReason(QString hdid);
long long getBanDuration(QString hdid);
long long getBanDuration(QHostAddress hdid);
long long getBanDuration(QHostAddress ip);
int getBanID(QString hdid);
int getBanID(QHostAddress ip);
void addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration);
struct BanInfo {
QString ipid;
QHostAddress ip;
QString hdid;
unsigned long time;
QString reason;
long long duration;
};
QList<BanInfo> getRecentBans();
void addBan(BanInfo ban);
bool invalidateBan(int id);
bool createUser(QString username, QString salt, QString password, unsigned long long acl);
bool deleteUser(QString username);
unsigned long long getACL(QString moderator_name);
bool authenticate(QString username, QString password);
bool updateACL(QString username, unsigned long long acl, bool mode);

View File

@ -95,6 +95,8 @@ void AOClient::cmdBan(int argc, QStringList argv)
args_str += " " + argv[i];
}
DBManager::BanInfo ban;
QRegularExpression quoteMatcher("['\"](.+?)[\"']");
QRegularExpressionMatchIterator matches = quoteMatcher.globalMatch(args_str);
QList<QString> unquoted_args;
@ -103,7 +105,6 @@ void AOClient::cmdBan(int argc, QStringList argv)
unquoted_args.append(match.captured(1));
}
QString reason;
QString duration = "perma";
if (unquoted_args.length() < 1) {
@ -111,7 +112,7 @@ void AOClient::cmdBan(int argc, QStringList argv)
return;
}
reason = unquoted_args.at(0);
ban.reason = unquoted_args.at(0);
if (unquoted_args.length() > 1)
duration = unquoted_args.at(1);
@ -126,34 +127,34 @@ void AOClient::cmdBan(int argc, QStringList argv)
return;
}
QString target_ipid = argv[0];
QHostAddress ip;
QString hdid;
unsigned long time = QDateTime::currentDateTime().toSecsSinceEpoch();
ban.duration = duration_seconds;
ban.ipid = argv[0];
ban.time = QDateTime::currentDateTime().toSecsSinceEpoch();
bool ban_logged = false;
int kick_counter = 0;
if (argc > 2) {
for (int i = 2; i < argv.length(); i++) {
reason += " " + argv[i];
ban.reason += " " + argv[i];
}
}
for (AOClient* client : server->getClientsByIpid(target_ipid)) {
for (AOClient* client : server->getClientsByIpid(ban.ipid)) {
if (!ban_logged) {
ip = client->remote_ip;
hdid = client->hwid;
server->db_manager->addBan(target_ipid, ip, hdid, time, reason, duration_seconds);
sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason);
ban.ip = client->remote_ip;
ban.hdid = client->hwid;
server->db_manager->addBan(ban);
sendServerMessage("Banned user with ipid " + ban.ipid + " for reason: " + ban.reason);
ban_logged = true;
}
client->sendPacket("KB", {reason});
client->sendPacket("KB", {ban.reason + "\nID: " + QString::number(server->db_manager->getBanID(ban.ip)) + "\nUntil: " + QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm")});
client->socket->close();
kick_counter++;
}
if (kick_counter > 1)
sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids");
sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids.");
if (!ban_logged)
sendServerMessage("User with ipid not found!");
}
@ -268,6 +269,14 @@ void AOClient::cmdAddUser(int argc, QStringList argv)
sendServerMessage("Unable to create user " + argv[0] + ".\nDoes a user with that name already exist?");
}
void AOClient::cmdRemoveUser(int argc, QStringList argv)
{
if (server->db_manager->deleteUser(argv[0]))
sendServerMessage("Successfully removed user " + argv[0] + ".");
else
sendServerMessage("Unable to remove user " + argv[0] + ".\nDoes it exist?");
}
void AOClient::cmdListPerms(int argc, QStringList argv)
{
unsigned long long user_acl = server->db_manager->getACL(moderator_name);
@ -971,6 +980,41 @@ void AOClient::cmdUnmute(int argc, QStringList argv)
server->getClientByID(uid)->is_muted = false;
}
void AOClient::cmdBans(int argc, QStringList argv)
{
QStringList recent_bans;
recent_bans << "Last 5 bans:";
recent_bans << "-----";
for (DBManager::BanInfo ban : server->db_manager->getRecentBans()) {
QString banned_until;
if (ban.duration == -2)
banned_until = "The heat death of the universe";
else
banned_until = QDateTime::fromSecsSinceEpoch(ban.time).addSecs(ban.duration).toString("dd.MM.yyyy, hh:mm");
recent_bans << "Affected IPID: " + ban.ipid;
recent_bans << "Affected HDID: " + ban.hdid;
recent_bans << "Reason for ban: " + ban.reason;
recent_bans << "Date of ban: " + QDateTime::fromSecsSinceEpoch(ban.time).toString("dd.MM.yyyy, hh:mm");
recent_bans << "Ban lasts until: " + banned_until;
recent_bans << "-----";
}
sendServerMessage(recent_bans.join("\n"));
}
void AOClient::cmdUnBan(int argc, QStringList argv)
{
bool ok;
int target_ban = argv[0].toInt(&ok);
if (!ok) {
sendServerMessage("Invalid ban ID.");
return;
}
else if (server->db_manager->invalidateBan(target_ban))
sendServerMessage("Successfully invalidated ban " + argv[0] + ".");
else
sendServerMessage("Couldn't invalidate ban " + argv[0] + ", are you sure it exists?");
}
void AOClient::cmdSubTheme(int argc, QStringList argv)
{
QString subtheme = argv.join(" ");

View File

@ -122,20 +122,88 @@ long long DBManager::getBanDuration(QHostAddress ip)
}
}
void DBManager::addBan(QString ipid, QHostAddress ip, QString hdid, unsigned long time, QString reason, long long duration)
int DBManager::getBanID(QString hdid)
{
QSqlQuery query;
query.prepare("SELECT ID FROM BANS WHERE HDID = ?");
query.addBindValue(hdid);
query.exec();
if (query.first()) {
return query.value(0).toInt();
}
else {
return -1;
}
}
int DBManager::getBanID(QHostAddress ip)
{
QSqlQuery query;
query.prepare("SELECT ID FROM BANS WHERE IP = ?");
query.addBindValue(ip.toString());
query.exec();
if (query.first()) {
return query.value(0).toInt();
}
else {
return -1;
}
}
QList<DBManager::BanInfo> DBManager::getRecentBans()
{
QList<BanInfo> return_list;
QSqlQuery query;
query.prepare("SELECT TOP(5) * FROM BANS ORDER BY TIME DESC");
query.setForwardOnly(true);
query.exec();
while (query.next()) {
BanInfo ban;
ban.ipid = query.value(0).toString();
ban.hdid = query.value(1).toString();
ban.ip = QHostAddress(query.value(2).toString());
ban.time = static_cast<unsigned long>(query.value(3).toULongLong());
ban.reason = query.value(4).toString();
ban.duration = query.value(5).toLongLong();
return_list.append(ban);
}
std::reverse(return_list.begin(), return_list.end());
return return_list;
}
void DBManager::addBan(BanInfo ban)
{
QSqlQuery query;
query.prepare("INSERT INTO BANS(IPID, HDID, IP, TIME, REASON, DURATION) VALUES(?, ?, ?, ?, ?, ?)");
query.addBindValue(ipid);
query.addBindValue(hdid);
query.addBindValue(ip.toString());
query.addBindValue(QString::number(time));
query.addBindValue(reason);
query.addBindValue(duration);
query.addBindValue(ban.ipid);
query.addBindValue(ban.hdid);
query.addBindValue(ban.ip.toString());
query.addBindValue(QString::number(ban.time));
query.addBindValue(ban.reason);
query.addBindValue(ban.duration);
if (!query.exec())
qDebug() << "SQL Error:" << query.lastError().text();
}
bool DBManager::invalidateBan(int id)
{
QSqlQuery ban_exists;
ban_exists.prepare("SELECT DURATION FROM bans WHERE ID = ?");
ban_exists.addBindValue(id);
ban_exists.exec();
if (ban_exists.first())
return false;
QSqlQuery query;
query.prepare("UPDATE bans SET DURATION = 0 WHERE ID = ?");
query.addBindValue(id);
query.exec();
return true;
}
bool DBManager::createUser(QString username, QString salt, QString password, unsigned long long acl)
{
QSqlQuery username_exists;
@ -164,6 +232,23 @@ bool DBManager::createUser(QString username, QString salt, QString password, uns
return true;
}
bool DBManager::deleteUser(QString username)
{
QSqlQuery username_exists;
username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?");
username_exists.addBindValue(username);
username_exists.exec();
if (username_exists.first())
return false;
QSqlQuery query;
query.prepare("DELETE FROM users WHERE USERNAME = ?");
username_exists.addBindValue(username);
username_exists.exec();
return true;
}
unsigned long long DBManager::getACL(QString moderator_name)
{
if (moderator_name == "")