add some user management command
This commit is contained in:
parent
7c6b892fb9
commit
2cc415e42b
@ -53,12 +53,13 @@ class AOClient : public QObject {
|
|||||||
QString moderator_name = "";
|
QString moderator_name = "";
|
||||||
QString ooc_name = "";
|
QString ooc_name = "";
|
||||||
|
|
||||||
enum ACLFlags {
|
QMap<QString, unsigned long long> ACLFlags {
|
||||||
NONE = 0ULL,
|
{"NONE", 0ULL},
|
||||||
KICK = 1ULL << 0,
|
{"KICK", 1ULL << 0},
|
||||||
BAN = 1ULL << 1,
|
{"BAN", 1ULL << 1},
|
||||||
BGLOCK = 1ULL << 2,
|
{"BGLOCK", 1ULL << 2},
|
||||||
SUPER = ~0ULL
|
{"MODIFY_USERS", 1ULL << 3},
|
||||||
|
{"SUPER", ~0ULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -112,21 +113,21 @@ class AOClient : public QObject {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QMap<QString, PacketInfo> packets {
|
const QMap<QString, PacketInfo> packets {
|
||||||
{"HI", {ACLFlags::NONE, 1, &AOClient::pktHardwareId}},
|
{"HI", {ACLFlags.value("NONE"), 1, &AOClient::pktHardwareId}},
|
||||||
{"ID", {ACLFlags::NONE, 2, &AOClient::pktSoftwareId}},
|
{"ID", {ACLFlags.value("NONE"), 2, &AOClient::pktSoftwareId}},
|
||||||
{"askchaa", {ACLFlags::NONE, 0, &AOClient::pktBeginLoad}},
|
{"askchaa", {ACLFlags.value("NONE"), 0, &AOClient::pktBeginLoad}},
|
||||||
{"RC", {ACLFlags::NONE, 0, &AOClient::pktRequestChars}},
|
{"RC", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestChars}},
|
||||||
{"RM", {ACLFlags::NONE, 0, &AOClient::pktRequestMusic}},
|
{"RM", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestMusic}},
|
||||||
{"RD", {ACLFlags::NONE, 0, &AOClient::pktLoadingDone}},
|
{"RD", {ACLFlags.value("NONE"), 0, &AOClient::pktLoadingDone}},
|
||||||
{"PW", {ACLFlags::NONE, 1, &AOClient::pktCharPassword}},
|
{"PW", {ACLFlags.value("NONE"), 1, &AOClient::pktCharPassword}},
|
||||||
{"CC", {ACLFlags::NONE, 3, &AOClient::pktSelectChar}},
|
{"CC", {ACLFlags.value("NONE"), 3, &AOClient::pktSelectChar}},
|
||||||
{"MS", {ACLFlags::NONE, 1, &AOClient::pktIcChat}}, // TODO: doublecheck
|
{"MS", {ACLFlags.value("NONE"), 1, &AOClient::pktIcChat}}, // TODO: doublecheck
|
||||||
{"CT", {ACLFlags::NONE, 2, &AOClient::pktOocChat}},
|
{"CT", {ACLFlags.value("NONE"), 2, &AOClient::pktOocChat}},
|
||||||
{"CH", {ACLFlags::NONE, 1, &AOClient::pktPing}},
|
{"CH", {ACLFlags.value("NONE"), 1, &AOClient::pktPing}},
|
||||||
{"MC", {ACLFlags::NONE, 2, &AOClient::pktChangeMusic}},
|
{"MC", {ACLFlags.value("NONE"), 2, &AOClient::pktChangeMusic}},
|
||||||
{"RT", {ACLFlags::NONE, 1, &AOClient::pktWtCe}},
|
{"RT", {ACLFlags.value("NONE"), 1, &AOClient::pktWtCe}},
|
||||||
{"HP", {ACLFlags::NONE, 2, &AOClient::pktHpBar}},
|
{"HP", {ACLFlags.value("NONE"), 2, &AOClient::pktHpBar}},
|
||||||
{"WSIP", {ACLFlags::NONE, 1, &AOClient::pktWebSocketIp}}
|
{"WSIP", {ACLFlags.value("NONE"), 1, &AOClient::pktWebSocketIp}}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
@ -141,6 +142,9 @@ class AOClient : public QObject {
|
|||||||
void cmdSetBackground(int argc, QStringList argv);
|
void cmdSetBackground(int argc, QStringList argv);
|
||||||
void cmdBgLock(int argc, QStringList argv);
|
void cmdBgLock(int argc, QStringList argv);
|
||||||
void cmdBgUnlock(int argc, QStringList argv);
|
void cmdBgUnlock(int argc, QStringList argv);
|
||||||
|
void cmdAddUser(int argc, QStringList argv);
|
||||||
|
void cmdListPerms(int argc, QStringList argv);
|
||||||
|
void cmdAddPerms(int argc, QStringList argv);
|
||||||
|
|
||||||
// Command helper functions
|
// Command helper functions
|
||||||
QStringList buildAreaList(int area_idx);
|
QStringList buildAreaList(int area_idx);
|
||||||
@ -155,17 +159,20 @@ class AOClient : public QObject {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const QMap<QString, CommandInfo> commands {
|
const QMap<QString, CommandInfo> commands {
|
||||||
{"login", {ACLFlags::NONE, 1, &AOClient::cmdLogin}},
|
{"login", {ACLFlags.value("NONE"), 1, &AOClient::cmdLogin}},
|
||||||
{"getareas", {ACLFlags::NONE, 0 , &AOClient::cmdGetAreas}},
|
{"getareas", {ACLFlags.value("NONE"), 0 , &AOClient::cmdGetAreas}},
|
||||||
{"getarea", {ACLFlags::NONE, 0, &AOClient::cmdGetArea}},
|
{"getarea", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}},
|
||||||
{"ban", {ACLFlags::BAN, 2, &AOClient::cmdBan}},
|
{"ban", {ACLFlags.value("BAN"), 2, &AOClient::cmdBan}},
|
||||||
{"kick", {ACLFlags::KICK, 2, &AOClient::cmdKick}},
|
{"kick", {ACLFlags.value("KICK"), 2, &AOClient::cmdKick}},
|
||||||
{"changeauth", {ACLFlags::SUPER, 0, &AOClient::cmdChangeAuth}},
|
{"changeauth", {ACLFlags.value("SUPER"), 0, &AOClient::cmdChangeAuth}},
|
||||||
{"rootpass", {ACLFlags::SUPER, 1, &AOClient::cmdSetRootPass}},
|
{"rootpass", {ACLFlags.value("SUPER"), 1, &AOClient::cmdSetRootPass}},
|
||||||
{"background", {ACLFlags::NONE, 1, &AOClient::cmdSetBackground}},
|
{"background", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
||||||
{"bg", {ACLFlags::NONE, 1, &AOClient::cmdSetBackground}},
|
{"bg", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
||||||
{"bglock", {ACLFlags::BGLOCK, 0, &AOClient::cmdBgLock}},
|
{"bglock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgLock}},
|
||||||
{"bgunlock", {ACLFlags::BGLOCK, 0, &AOClient::cmdBgUnlock}}
|
{"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}}
|
||||||
};
|
};
|
||||||
|
|
||||||
QString partial_packet;
|
QString partial_packet;
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
#ifndef BAN_MANAGER_H
|
#ifndef BAN_MANAGER_H
|
||||||
#define BAN_MANAGER_H
|
#define BAN_MANAGER_H
|
||||||
|
|
||||||
#include "include/aoclient.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QMessageAuthenticationCode>
|
#include <QMessageAuthenticationCode>
|
||||||
@ -45,6 +43,7 @@ public:
|
|||||||
void createUser(QString username, QString salt, QString password, unsigned long long acl);
|
void createUser(QString username, QString salt, QString password, unsigned long long acl);
|
||||||
unsigned long long getACL(QString moderator_name);
|
unsigned long long getACL(QString moderator_name);
|
||||||
bool authenticate(QString username, QString password);
|
bool authenticate(QString username, QString password);
|
||||||
|
bool updateACL(QString username, unsigned long long acl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString DRIVER;
|
const QString DRIVER;
|
||||||
|
@ -218,7 +218,7 @@ void AOClient::sendServerMessage(QString message)
|
|||||||
|
|
||||||
bool AOClient::checkAuth(unsigned long long acl_mask)
|
bool AOClient::checkAuth(unsigned long long acl_mask)
|
||||||
{
|
{
|
||||||
if (acl_mask != ACLFlags::NONE) {
|
if (acl_mask != ACLFlags.value("NONE")) {
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,11 @@ void AOClient::cmdLogin(int argc, QStringList argv)
|
|||||||
QString modpass = config.value("modpass", "default").toString();
|
QString modpass = config.value("modpass", "default").toString();
|
||||||
QString auth_type = config.value("auth", "simple").toString();
|
QString auth_type = config.value("auth", "simple").toString();
|
||||||
|
|
||||||
|
if (authenticated) {
|
||||||
|
sendServerMessage("You are already logged in!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: tell the user if no modpass is set
|
// TODO: tell the user if no modpass is set
|
||||||
if (auth_type == "simple") {
|
if (auth_type == "simple") {
|
||||||
if(argv[0] == modpass) {
|
if(argv[0] == modpass) {
|
||||||
@ -162,7 +167,7 @@ void AOClient::cmdSetRootPass(int argc, QStringList argv)
|
|||||||
quint64 salt_number = QRandomGenerator::system()->generate64();
|
quint64 salt_number = QRandomGenerator::system()->generate64();
|
||||||
QString salt = QStringLiteral("%1").arg(salt_number, 16, 16, QLatin1Char('0'));
|
QString salt = QStringLiteral("%1").arg(salt_number, 16, 16, QLatin1Char('0'));
|
||||||
|
|
||||||
server->db_manager->createUser("root", salt, argv[0], ACLFlags::SUPER);
|
server->db_manager->createUser("root", salt, argv[0], ACLFlags.value("SUPER"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOClient::cmdSetBackground(int argc, QStringList argv)
|
void AOClient::cmdSetBackground(int argc, QStringList argv)
|
||||||
@ -199,6 +204,84 @@ void AOClient::cmdBgUnlock(int argc, QStringList argv)
|
|||||||
server->broadcast(AOPacket("CT", {"Server", current_char + " unlocked the background.", "1"}), current_area);
|
server->broadcast(AOPacket("CT", {"Server", current_char + " unlocked the background.", "1"}), current_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AOClient::cmdAddUser(int argc, QStringList argv)
|
||||||
|
{
|
||||||
|
quint64 salt_number = QRandomGenerator::system()->generate64();
|
||||||
|
QString salt = QStringLiteral("%1").arg(salt_number, 16, 16, QLatin1Char('0'));
|
||||||
|
|
||||||
|
server->db_manager->createUser(argv[0], salt, argv[1], ACLFlags.value("NONE"));
|
||||||
|
sendServerMessage("Created user " + argv[0] + ".\nUse /addperm to modify their permissions.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::cmdListPerms(int argc, QStringList argv)
|
||||||
|
{
|
||||||
|
unsigned long long user_acl = server->db_manager->getACL(moderator_name);
|
||||||
|
QStringList message;
|
||||||
|
if (argc == 0) {
|
||||||
|
// Just print out all permissions available to the user.
|
||||||
|
message.append("You can add the following permissions to users:");
|
||||||
|
for (QString perm : ACLFlags.keys()) {
|
||||||
|
if (perm == "NONE"); // don't need to list this one
|
||||||
|
else if (perm == "SUPER") {
|
||||||
|
if (user_acl == ACLFlags.value("SUPER")) // This has to be checked separately, because SUPER & anything will always be truthy
|
||||||
|
message.append("SUPER (Be careful! This grants the user all permissions.)");
|
||||||
|
}
|
||||||
|
else if ((ACLFlags.value(perm) & user_acl) == 0); // user doesn't have this permission, don't print it
|
||||||
|
else
|
||||||
|
message.append(perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message.append("User " + argv[0] + " has the following permissions:");
|
||||||
|
unsigned long long acl = server->db_manager->getACL(argv[0]);
|
||||||
|
if (acl == 0) {
|
||||||
|
sendServerMessage("This user either doesn't exist, or has no permissions set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QString perm : ACLFlags.keys()) {
|
||||||
|
if ((ACLFlags.value(perm) & acl) != 0 && perm != "SUPER") {
|
||||||
|
message.append(perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendServerMessage(message.join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AOClient::cmdAddPerms(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 add that permission!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argv[1] == "NONE") {
|
||||||
|
sendServerMessage("Added no permissions!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long newperm = ACLFlags.value(argv[1]);
|
||||||
|
if ((newperm & user_acl) != 0) {
|
||||||
|
if (server->db_manager->updateACL(argv[0], newperm))
|
||||||
|
sendServerMessage("Successfully added permission " + argv[1] + " to user " + argv[0]);
|
||||||
|
else
|
||||||
|
sendServerMessage(argv[0] + " wasn't found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendServerMessage("You aren't allowed to add that permission!");
|
||||||
|
}
|
||||||
|
|
||||||
QStringList AOClient::buildAreaList(int area_idx)
|
QStringList AOClient::buildAreaList(int area_idx)
|
||||||
{
|
{
|
||||||
QStringList entries;
|
QStringList entries;
|
||||||
|
@ -110,12 +110,12 @@ void DBManager::createUser(QString username, QString salt, QString password, uns
|
|||||||
unsigned long long DBManager::getACL(QString moderator_name)
|
unsigned long long DBManager::getACL(QString moderator_name)
|
||||||
{
|
{
|
||||||
if (moderator_name == "")
|
if (moderator_name == "")
|
||||||
return AOClient::ACLFlags::NONE;
|
return 0;
|
||||||
QSqlQuery query("SELECT ACL FROM users WHERE USERNAME = ?");
|
QSqlQuery query("SELECT ACL FROM users WHERE USERNAME = ?");
|
||||||
query.addBindValue(moderator_name);
|
query.addBindValue(moderator_name);
|
||||||
query.exec();
|
query.exec();
|
||||||
if (!query.first())
|
if (!query.first())
|
||||||
return AOClient::ACLFlags::NONE;
|
return 0;
|
||||||
return query.value(0).toULongLong();
|
return query.value(0).toULongLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +146,29 @@ bool DBManager::authenticate(QString username, QString password)
|
|||||||
return salted_password == stored_pass;
|
return salted_password == stored_pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DBManager::updateACL(QString username, unsigned long long acl)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
unsigned long long old_acl = username_exists.value(0).toULongLong();
|
||||||
|
unsigned long long new_acl = acl | old_acl;
|
||||||
|
if (acl == 0) // Allow clearing all perms via adding perm "NONE"
|
||||||
|
new_acl = 0;
|
||||||
|
|
||||||
|
QSqlQuery update_acl;
|
||||||
|
update_acl.prepare("UPDATE users SET ACL = ? WHERE USERNAME = ?");
|
||||||
|
update_acl.addBindValue(new_acl);
|
||||||
|
update_acl.addBindValue(username);
|
||||||
|
update_acl.exec();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DBManager::~DBManager()
|
DBManager::~DBManager()
|
||||||
{
|
{
|
||||||
db.close();
|
db.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user