From d96fde7a69e919ce8d184315047d0cff2a551411 Mon Sep 17 00:00:00 2001 From: scatterflower Date: Tue, 29 Sep 2020 14:45:57 -0500 Subject: [PATCH] user count robustness, and added user management commands --- include/aoclient.h | 8 +++++-- include/db_manager.h | 3 ++- src/commands.cpp | 55 ++++++++++++++++++++++++++++++++++++++++---- src/db_manager.cpp | 20 ++++++++++++++-- src/packets.cpp | 10 ++++++++ 5 files changed, 87 insertions(+), 9 deletions(-) diff --git a/include/aoclient.h b/include/aoclient.h index b80f5f4..369768d 100644 --- a/include/aoclient.h +++ b/include/aoclient.h @@ -145,6 +145,8 @@ class AOClient : public QObject { void cmdAddUser(int argc, QStringList argv); void cmdListPerms(int argc, QStringList argv); void cmdAddPerms(int argc, QStringList argv); + void cmdRemovePerms(int argc, QStringList argv); + void cmdListUsers(int argc, QStringList argv); // Command helper functions QStringList buildAreaList(int area_idx); @@ -171,8 +173,10 @@ class AOClient : public QObject { {"bglock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgLock}}, {"bgunlock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgUnlock}}, {"adduser", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddUser}}, - {"listperms", {ACLFlags.value("MODIFY_USERS"), 0, &AOClient::cmdListPerms}}, - {"addperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddPerms}} + {"listperms", {ACLFlags.value("NONE"), 0, &AOClient::cmdListPerms}}, + {"addperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddPerms}}, + {"removeperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdRemovePerms}}, + {"listusers", {ACLFlags.value("MODIFY_USERS"), 0, &AOClient::cmdListUsers}} }; QString partial_packet; diff --git a/include/db_manager.h b/include/db_manager.h index 51e0a4c..c6d466d 100644 --- a/include/db_manager.h +++ b/include/db_manager.h @@ -43,7 +43,8 @@ public: void createUser(QString username, QString salt, QString password, unsigned long long acl); unsigned long long getACL(QString moderator_name); bool authenticate(QString username, QString password); - bool updateACL(QString username, unsigned long long acl); + bool updateACL(QString username, unsigned long long acl, bool mode); + QStringList getUsers(); private: const QString DRIVER; diff --git a/src/commands.cpp b/src/commands.cpp index 819e09b..825f1a1 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -136,7 +136,7 @@ void AOClient::cmdKick(int argc, QStringList argv) } if (did_kick) - sendServerMessage("Banned user with ipid " + target_ipid + " for reason: " + reason); + sendServerMessage("Kicked user with ipid " + target_ipid + " for reason: " + reason); else sendServerMessage("User with ipid not found!"); } @@ -219,7 +219,7 @@ void AOClient::cmdListPerms(int argc, QStringList argv) QStringList message; if (argc == 0) { // Just print out all permissions available to the user. - message.append("You can add the following permissions to users:"); + message.append("You have been given the following permissions:"); for (QString perm : ACLFlags.keys()) { if (perm == "NONE"); // don't need to list this one else if (perm == "SUPER") { @@ -232,6 +232,11 @@ void AOClient::cmdListPerms(int argc, QStringList argv) } } else { + if ((user_acl & ACLFlags.value("MANAGE_USERS")) == 0) { + sendServerMessage("You do not have permission to view other users' permissions."); + return; + } + message.append("User " + argv[0] + " has the following permissions:"); unsigned long long acl = server->db_manager->getACL(argv[0]); if (acl == 0) { @@ -272,7 +277,7 @@ void AOClient::cmdAddPerms(int argc, QStringList argv) unsigned long long newperm = ACLFlags.value(argv[1]); if ((newperm & user_acl) != 0) { - if (server->db_manager->updateACL(argv[0], newperm)) + if (server->db_manager->updateACL(argv[0], newperm, true)) sendServerMessage("Successfully added permission " + argv[1] + " to user " + argv[0]); else sendServerMessage(argv[0] + " wasn't found!"); @@ -282,6 +287,46 @@ void AOClient::cmdAddPerms(int argc, QStringList argv) sendServerMessage("You aren't allowed to add that permission!"); } +void AOClient::cmdRemovePerms(int argc, QStringList argv) +{ + unsigned long long user_acl = server->db_manager->getACL(moderator_name); + argv[1] = argv[1].toUpper(); + + if (!ACLFlags.keys().contains(argv[1])) { + sendServerMessage("That permission doesn't exist!"); + return; + } + + if (argv[1] == "SUPER") { + if (user_acl != ACLFlags.value("SUPER")) { + // This has to be checked separately, because SUPER & anything will always be truthy + sendServerMessage("You aren't allowed to remove that permission!"); + return; + } + } + if (argv[1] == "NONE") { + sendServerMessage("Removed no permissions!"); + return; + } + + unsigned long long newperm = ACLFlags.value(argv[1]); + if ((newperm & user_acl) != 0) { + if (server->db_manager->updateACL(argv[0], newperm, false)) + sendServerMessage("Successfully removed permission " + argv[1] + " from user " + argv[0]); + else + sendServerMessage(argv[0] + " wasn't found!"); + return; + } + + sendServerMessage("You aren't allowed to remove that permission!"); +} + +void AOClient::cmdListUsers(int argc, QStringList argv) +{ + QStringList users = server->db_manager->getUsers(); + sendServerMessage("All users:\n" + users.join("\n")); +} + QStringList AOClient::buildAreaList(int area_idx) { QStringList entries; @@ -290,8 +335,10 @@ QStringList AOClient::buildAreaList(int area_idx) entries.append("=== " + area_name + " ==="); entries.append("[" + QString::number(area->player_count) + " users][" + area->status + "]"); for (AOClient* client : server->clients) { - if (client->current_area == area_idx) { + if (client->current_area == area_idx && client->authenticated) { QString char_entry = client->current_char; + if (char_entry == "") + char_entry = "Spectator"; if (authenticated) char_entry += " (" + client->getIpid() + "): " + client->ooc_name; entries.append(char_entry); diff --git a/src/db_manager.cpp b/src/db_manager.cpp index 858f984..106b145 100644 --- a/src/db_manager.cpp +++ b/src/db_manager.cpp @@ -146,7 +146,7 @@ bool DBManager::authenticate(QString username, QString password) return salted_password == stored_pass; } -bool DBManager::updateACL(QString username, unsigned long long acl) +bool DBManager::updateACL(QString username, unsigned long long acl, bool mode) { QSqlQuery username_exists; username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?"); @@ -157,7 +157,11 @@ bool DBManager::updateACL(QString username, unsigned long long acl) return false; unsigned long long old_acl = username_exists.value(0).toULongLong(); - unsigned long long new_acl = acl | old_acl; + unsigned long long new_acl; + if (mode) // adding perm + new_acl = old_acl | acl; + else // removing perm + new_acl = old_acl & ~acl; if (acl == 0) // Allow clearing all perms via adding perm "NONE" new_acl = 0; @@ -169,6 +173,18 @@ bool DBManager::updateACL(QString username, unsigned long long acl) return true; } +QStringList DBManager::getUsers() +{ + QStringList users; + + QSqlQuery query("SELECT USERNAME FROM users ORDER BY ID"); + while (query.next()) { + users.append(query.value(0).toString()); + } + + return users; +} + DBManager::~DBManager() { db.close(); diff --git a/src/packets.cpp b/src/packets.cpp index b1bb755..11317cb 100644 --- a/src/packets.cpp +++ b/src/packets.cpp @@ -75,6 +75,16 @@ void AOClient::pktRequestMusic(AreaData* area, int argc, QStringList argv, AOPac void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPacket packet) { + if (getHwid() == "") { + // No early connecting! + socket->close(); + return; + } + + if (joined) { + return; + } + server->player_count++; area->player_count++; joined = true;