parent
b0555207d6
commit
657a47b029
@ -25,6 +25,7 @@ DESTDIR = $$PWD/../bin
|
||||
#DEFINES += NET_DEBUG
|
||||
|
||||
SOURCES += \
|
||||
src/acl_roles_handler.cpp \
|
||||
src/aoclient.cpp \
|
||||
src/aopacket.cpp \
|
||||
src/area_data.cpp \
|
||||
@ -51,6 +52,7 @@ SOURCES += \
|
||||
src/music_manager.cpp
|
||||
|
||||
HEADERS += include/aoclient.h \
|
||||
include/acl_roles_handler.h \
|
||||
include/aopacket.h \
|
||||
include/area_data.h \
|
||||
include/config_manager.h \
|
||||
|
210
core/include/acl_roles_handler.h
Normal file
210
core/include/acl_roles_handler.h
Normal file
@ -0,0 +1,210 @@
|
||||
#ifndef ACL_ROLES_HANDLER_H
|
||||
#define ACL_ROLES_HANDLER_H
|
||||
|
||||
#include <QFlags>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
|
||||
class ACLRole
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief This enum is used to specify permissions of a role.
|
||||
*/
|
||||
enum Permission : unsigned int
|
||||
{
|
||||
NONE = 0,
|
||||
KICK = 1 << 0,
|
||||
BAN = 1 << 1,
|
||||
BGLOCK = 1 << 2,
|
||||
MODIFY_USERS = 1 << 3,
|
||||
CM = 1 << 4,
|
||||
GLOBAL_TIMER = 1 << 5,
|
||||
EVI_MOD = 1 << 6,
|
||||
MOTD = 1 << 7,
|
||||
ANNOUNCE = 1 << 8,
|
||||
MODCHAT = 1 << 9,
|
||||
MUTE = 1 << 10,
|
||||
UNCM = 1 << 11,
|
||||
SAVETEST = 1 << 12,
|
||||
FORCE_CHARSELECT = 1 << 13,
|
||||
BYPASS_LOCKS = 1 << 14,
|
||||
IGNORE_BGLIST = 1 << 15,
|
||||
SEND_NOTICE = 1 << 16,
|
||||
JUKEBOX = 1 << 17,
|
||||
SUPER = 0xffffffff,
|
||||
};
|
||||
Q_DECLARE_FLAGS(Permissions, Permission);
|
||||
|
||||
/**
|
||||
* @brief Shared read-only captions for each permissions.
|
||||
*
|
||||
* @see ACLRoleHandler#loadFile and ACLRoleHandler#saveFile
|
||||
*/
|
||||
static const QHash<ACLRole::Permission, QString> permission_captions;
|
||||
|
||||
/**
|
||||
* @brief Constructs a role without any permissions.
|
||||
*/
|
||||
ACLRole();
|
||||
|
||||
/**
|
||||
* @brief Constructs a role of the given permissions.
|
||||
*
|
||||
* @param f_permissions The permissions to which
|
||||
*/
|
||||
ACLRole(ACLRole::Permissions f_permissions);
|
||||
|
||||
/**
|
||||
* @brief Destroys the role.
|
||||
*/
|
||||
~ACLRole();
|
||||
|
||||
/**
|
||||
* @brief Returns the permission flags for this role.
|
||||
*
|
||||
* @return Permission flags.
|
||||
*/
|
||||
ACLRole::Permissions getPermissions() const;
|
||||
|
||||
/**
|
||||
* @brief Checks if a given permission is set.
|
||||
*
|
||||
* @param f_permission The permission flag to check.
|
||||
*
|
||||
* @return True if the permission is set, false otherwise.
|
||||
*/
|
||||
bool checkPermission(ACLRole::Permission f_permission) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the permission if f_mode is true or unsets if f_mode is false.
|
||||
*
|
||||
* @param f_permission The permission flag to set.
|
||||
*
|
||||
* @param f_mode If true, will set the flag, unsets otherwise.
|
||||
*/
|
||||
void setPermission(ACLRole::Permission f_permission, bool f_mode);
|
||||
|
||||
/**
|
||||
* @brief Sets the permission flags to the given permission flags.
|
||||
*
|
||||
* @param f_permissions The permission flags to set to.
|
||||
*/
|
||||
void setPermissions(ACLRole::Permissions f_permissions);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief The permission flags of the role.
|
||||
*/
|
||||
ACLRole::Permissions m_permissions;
|
||||
};
|
||||
|
||||
class ACLRolesHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The identifier of the NONE role.
|
||||
*/
|
||||
static const QString NONE_ID;
|
||||
|
||||
/**
|
||||
* @brief The identifier of the SUPER role.
|
||||
*/
|
||||
static const QString SUPER_ID;
|
||||
|
||||
/**
|
||||
* @brief Constructs a role handler with parent object.
|
||||
*
|
||||
* @details The role handler starts off empty without any roles known with the exception of the shared read-only roles.
|
||||
*
|
||||
* The role handler do not load or save roles automatically.
|
||||
*
|
||||
* Multiple role handlers can exist simultaneously with different roles and these same roles may have entirely different permissions.
|
||||
*
|
||||
* @param parent Qt-based parent.
|
||||
*/
|
||||
ACLRolesHandler(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Destroys the role handler.
|
||||
*/
|
||||
~ACLRolesHandler();
|
||||
|
||||
/**
|
||||
* @brief Checks if a role with the given identifier exists.
|
||||
*
|
||||
* @param f_id The identifier of the role. The identifier is not case-sensitive.
|
||||
*
|
||||
* @return True if the role exists, false otherwise.
|
||||
*/
|
||||
bool roleExists(QString f_id);
|
||||
|
||||
/**
|
||||
* @brief Returns a role with the given identifier. If the role does not exist, a default constructed role will be returned.
|
||||
*
|
||||
* @param f_id The identifier of the role. The identifier is not case-sensitive.
|
||||
*
|
||||
* @return A role.
|
||||
*/
|
||||
ACLRole getRoleById(QString f_id);
|
||||
|
||||
/**
|
||||
* @brief Inserts a role with the given identifier. If a role already exists, it will be overwritten. Read-only roles cannot be replaced and will return false.
|
||||
*
|
||||
* @param f_id The identifier of the role. The identifier is not case-sensitive.
|
||||
*
|
||||
* @param f_role The role to insert.
|
||||
*
|
||||
* @return True if the role was inserted, false otherwise.
|
||||
*/
|
||||
bool insertRole(QString f_id, ACLRole f_role);
|
||||
|
||||
/**
|
||||
* @brief Removes a role of the given identifier. Read-only roles cannot be removed and will return false.
|
||||
*
|
||||
* @param f_id The identifier of the role. The identifier is not case-sensitive.
|
||||
*
|
||||
* @return True if the role was removed, false otherwise.
|
||||
*/
|
||||
bool removeRole(QString f_id);
|
||||
|
||||
/**
|
||||
* @brief Removes all roles.
|
||||
*/
|
||||
void clearRoles();
|
||||
|
||||
/**
|
||||
* @brief Clear the current roles and load the roles from the given file. The file must be INI format compatible.
|
||||
*
|
||||
* @param f_filename The filename may have no path, a relative path or an absolute path.
|
||||
*
|
||||
* @return True if successfull, false otherwise.
|
||||
*/
|
||||
bool loadFile(QString f_filename);
|
||||
|
||||
/**
|
||||
* @brief Save the current roles to the given file. The file is saved to the INI format.
|
||||
*
|
||||
* @warning This will completely overwrite the given file.
|
||||
*
|
||||
* @param f_filename The filename may have no path, a relative path or an absolute path.
|
||||
*
|
||||
* @return True if successfull, false otherwise.
|
||||
*/
|
||||
bool saveFile(QString f_filename);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Shared read-only standard roles with the appropriate permissions.
|
||||
*/
|
||||
static const QHash<QString, ACLRole> readonly_roles;
|
||||
|
||||
/**
|
||||
* @brief The roles of the handler.
|
||||
*/
|
||||
QHash<QString, ACLRole> m_roles;
|
||||
};
|
||||
|
||||
#endif // ACL_ROLES_HANDLER_H
|
@ -24,12 +24,13 @@
|
||||
#include <QHostAddress>
|
||||
#include <QRegularExpression>
|
||||
#include <QTcpSocket>
|
||||
#include <QtGlobal>
|
||||
#include <QTimer>
|
||||
#include <QtGlobal>
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0)
|
||||
#include <QRandomGenerator>
|
||||
#endif
|
||||
|
||||
#include "include/acl_roles_handler.h"
|
||||
#include "include/aopacket.h"
|
||||
|
||||
class AreaData;
|
||||
@ -87,6 +88,13 @@ class AOClient : public QObject
|
||||
*/
|
||||
bool hasJoined() const;
|
||||
|
||||
/**
|
||||
* @brief Returns true if the client has logged-in as a role.
|
||||
*
|
||||
* @return True if loggged-in, false otherwise.
|
||||
*/
|
||||
bool isAuthenticated() const;
|
||||
|
||||
/**
|
||||
* @brief Calculates the client's IPID based on a hashed version of its IP.
|
||||
*/
|
||||
@ -146,11 +154,6 @@ class AOClient : public QObject
|
||||
*/
|
||||
QString m_current_iniswap;
|
||||
|
||||
/**
|
||||
* @brief If true, the client is a logged-in moderator.
|
||||
*/
|
||||
bool m_authenticated = false;
|
||||
|
||||
/**
|
||||
* @brief If using advanced authentication, this is the moderator name that the client has logged in with.
|
||||
*/
|
||||
@ -221,33 +224,6 @@ class AOClient : public QObject
|
||||
*/
|
||||
ClientVersion m_version;
|
||||
|
||||
/**
|
||||
* @brief The authorisation bitflag, representing what permissions a client can have.
|
||||
*
|
||||
* @showinitializer
|
||||
*/
|
||||
QMap<QString, unsigned long long> ACLFlags{
|
||||
{"NONE", 0ULL},
|
||||
{"KICK", 1ULL << 0},
|
||||
{"BAN", 1ULL << 1},
|
||||
{"BGLOCK", 1ULL << 2},
|
||||
{"MODIFY_USERS", 1ULL << 3},
|
||||
{"CM", 1ULL << 4},
|
||||
{"GLOBAL_TIMER", 1ULL << 5},
|
||||
{"EVI_MOD", 1ULL << 6},
|
||||
{"MOTD", 1ULL << 7},
|
||||
{"ANNOUNCE", 1ULL << 8},
|
||||
{"MODCHAT", 1ULL << 9},
|
||||
{"MUTE", 1ULL << 10},
|
||||
{"UNCM", 1ULL << 11},
|
||||
{"SAVETEST", 1ULL << 12},
|
||||
{"FORCE_CHARSELECT", 1ULL << 13},
|
||||
{"BYPASS_LOCKS", 1ULL << 14},
|
||||
{"IGNORE_BGLIST", 1ULL << 15},
|
||||
{"SEND_NOTICE", 1ULL << 16},
|
||||
{"JUKEBOX", 1ULL << 17},
|
||||
{"SUPER", ~0ULL}};
|
||||
|
||||
/**
|
||||
* @brief A list of 5 casing preferences (def, pro, judge, jury, steno)
|
||||
*/
|
||||
@ -310,14 +286,13 @@ class AOClient : public QObject
|
||||
bool m_is_logging_in = false;
|
||||
|
||||
/**
|
||||
* @brief Checks if the client would be authorised to something based on its necessary permissions.
|
||||
* @brief Checks if the client's ACL role has permission for the given permission.
|
||||
*
|
||||
* @param acl_mask The permissions bitflag that the client's own permissions should be checked against.
|
||||
* @param f_permission The permission flags.
|
||||
*
|
||||
* @return True if the client's permissions are high enough for `acl_mask`, or higher than it.
|
||||
* False if the client is missing some permissions.
|
||||
* @return True if the client has permission, false otherwise.
|
||||
*/
|
||||
bool checkAuth(unsigned long long acl_mask);
|
||||
bool checkPermission(ACLRole::Permission f_permission) const;
|
||||
|
||||
public slots:
|
||||
/**
|
||||
@ -611,6 +586,16 @@ class AOClient : public QObject
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief If true, the client is a logged-in moderator.
|
||||
*/
|
||||
bool m_authenticated = false;
|
||||
|
||||
/**
|
||||
* @brief The ACL role identifier, used to determine what ACL role the client is linked to.
|
||||
*/
|
||||
QString m_acl_role_id;
|
||||
|
||||
/**
|
||||
* @brief The client's character ID.
|
||||
*
|
||||
@ -660,8 +645,8 @@ class AOClient : public QObject
|
||||
/// Describes a packet's interpretation details.
|
||||
struct PacketInfo
|
||||
{
|
||||
unsigned long long acl_mask; //!< The permissions necessary for the packet.
|
||||
int minArgs; //!< The minimum arguments needed for the packet to be interpreted correctly / make sense.
|
||||
ACLRole::Permission acl_permission; //!< The permissions necessary for the packet.
|
||||
int minArgs; //!< The minimum arguments needed for the packet to be interpreted correctly / make sense.
|
||||
void (AOClient::*action)(AreaData *, int, QStringList, AOPacket);
|
||||
};
|
||||
|
||||
@ -686,27 +671,27 @@ class AOClient : public QObject
|
||||
* See @ref PacketInfo "the type's documentation" for more details.
|
||||
*/
|
||||
const QMap<QString, PacketInfo> packets{
|
||||
{"HI", {ACLFlags.value("NONE"), 1, &AOClient::pktHardwareId}},
|
||||
{"ID", {ACLFlags.value("NONE"), 2, &AOClient::pktSoftwareId}},
|
||||
{"askchaa", {ACLFlags.value("NONE"), 0, &AOClient::pktBeginLoad}},
|
||||
{"RC", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestChars}},
|
||||
{"RM", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestMusic}},
|
||||
{"RD", {ACLFlags.value("NONE"), 0, &AOClient::pktLoadingDone}},
|
||||
{"PW", {ACLFlags.value("NONE"), 1, &AOClient::pktCharPassword}},
|
||||
{"CC", {ACLFlags.value("NONE"), 3, &AOClient::pktSelectChar}},
|
||||
{"MS", {ACLFlags.value("NONE"), 15, &AOClient::pktIcChat}},
|
||||
{"CT", {ACLFlags.value("NONE"), 2, &AOClient::pktOocChat}},
|
||||
{"CH", {ACLFlags.value("NONE"), 1, &AOClient::pktPing}},
|
||||
{"MC", {ACLFlags.value("NONE"), 2, &AOClient::pktChangeMusic}},
|
||||
{"RT", {ACLFlags.value("NONE"), 1, &AOClient::pktWtCe}},
|
||||
{"HP", {ACLFlags.value("NONE"), 2, &AOClient::pktHpBar}},
|
||||
{"WSIP", {ACLFlags.value("NONE"), 1, &AOClient::pktWebSocketIp}},
|
||||
{"ZZ", {ACLFlags.value("NONE"), 0, &AOClient::pktModCall}},
|
||||
{"PE", {ACLFlags.value("NONE"), 3, &AOClient::pktAddEvidence}},
|
||||
{"DE", {ACLFlags.value("NONE"), 1, &AOClient::pktRemoveEvidence}},
|
||||
{"EE", {ACLFlags.value("NONE"), 4, &AOClient::pktEditEvidence}},
|
||||
{"SETCASE", {ACLFlags.value("NONE"), 7, &AOClient::pktSetCase}},
|
||||
{"CASEA", {ACLFlags.value("NONE"), 6, &AOClient::pktAnnounceCase}},
|
||||
{"HI", {ACLRole::NONE, 1, &AOClient::pktHardwareId}},
|
||||
{"ID", {ACLRole::NONE, 2, &AOClient::pktSoftwareId}},
|
||||
{"askchaa", {ACLRole::NONE, 0, &AOClient::pktBeginLoad}},
|
||||
{"RC", {ACLRole::NONE, 0, &AOClient::pktRequestChars}},
|
||||
{"RM", {ACLRole::NONE, 0, &AOClient::pktRequestMusic}},
|
||||
{"RD", {ACLRole::NONE, 0, &AOClient::pktLoadingDone}},
|
||||
{"PW", {ACLRole::NONE, 1, &AOClient::pktCharPassword}},
|
||||
{"CC", {ACLRole::NONE, 3, &AOClient::pktSelectChar}},
|
||||
{"MS", {ACLRole::NONE, 15, &AOClient::pktIcChat}},
|
||||
{"CT", {ACLRole::NONE, 2, &AOClient::pktOocChat}},
|
||||
{"CH", {ACLRole::NONE, 1, &AOClient::pktPing}},
|
||||
{"MC", {ACLRole::NONE, 2, &AOClient::pktChangeMusic}},
|
||||
{"RT", {ACLRole::NONE, 1, &AOClient::pktWtCe}},
|
||||
{"HP", {ACLRole::NONE, 2, &AOClient::pktHpBar}},
|
||||
{"WSIP", {ACLRole::NONE, 1, &AOClient::pktWebSocketIp}},
|
||||
{"ZZ", {ACLRole::NONE, 0, &AOClient::pktModCall}},
|
||||
{"PE", {ACLRole::NONE, 3, &AOClient::pktAddEvidence}},
|
||||
{"DE", {ACLRole::NONE, 1, &AOClient::pktRemoveEvidence}},
|
||||
{"EE", {ACLRole::NONE, 4, &AOClient::pktEditEvidence}},
|
||||
{"SETCASE", {ACLRole::NONE, 7, &AOClient::pktSetCase}},
|
||||
{"CASEA", {ACLRole::NONE, 6, &AOClient::pktAnnounceCase}},
|
||||
};
|
||||
|
||||
/**
|
||||
@ -779,7 +764,7 @@ class AOClient : public QObject
|
||||
*
|
||||
* @iscommand
|
||||
*/
|
||||
void cmdAddPerms(int argc, QStringList argv);
|
||||
void cmdSetPerms(int argc, QStringList argv);
|
||||
|
||||
/**
|
||||
* @brief Removes permissions from a given user.
|
||||
@ -2062,8 +2047,8 @@ class AOClient : public QObject
|
||||
*/
|
||||
struct CommandInfo
|
||||
{
|
||||
unsigned long long acl_mask; //!< The permissions necessary to be able to run the command. @see ACLFlags.
|
||||
int minArgs; //!< The minimum mandatory arguments needed for the command to function.
|
||||
ACLRole::Permission acl_permission; //!< The permissions necessary to be able to run the command. @see ACLRole::Permission.
|
||||
int minArgs; //!< The minimum mandatory arguments needed for the command to function.
|
||||
void (AOClient::*action)(int, QStringList);
|
||||
};
|
||||
|
||||
@ -2087,145 +2072,145 @@ class AOClient : public QObject
|
||||
* See @ref CommandInfo "the type's documentation" for more details.
|
||||
*/
|
||||
const QMap<QString, CommandInfo> commands{
|
||||
{"login", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogin}},
|
||||
{"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
|
||||
{"gas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
|
||||
{"getarea", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}},
|
||||
{"ga", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}},
|
||||
{"ban", {ACLFlags.value("BAN"), 3, &AOClient::cmdBan}},
|
||||
{"kick", {ACLFlags.value("KICK"), 2, &AOClient::cmdKick}},
|
||||
{"changeauth", {ACLFlags.value("SUPER"), 0, &AOClient::cmdChangeAuth}},
|
||||
{"rootpass", {ACLFlags.value("SUPER"), 1, &AOClient::cmdSetRootPass}},
|
||||
{"background", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
||||
{"bg", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
||||
{"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("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}},
|
||||
{"logout", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogout}},
|
||||
{"pos", {ACLFlags.value("NONE"), 1, &AOClient::cmdPos}},
|
||||
{"g", {ACLFlags.value("NONE"), 1, &AOClient::cmdG}},
|
||||
{"need", {ACLFlags.value("NONE"), 1, &AOClient::cmdNeed}},
|
||||
{"coinflip", {ACLFlags.value("NONE"), 0, &AOClient::cmdFlip}},
|
||||
{"roll", {ACLFlags.value("NONE"), 0, &AOClient::cmdRoll}},
|
||||
{"r", {ACLFlags.value("NONE"), 0, &AOClient::cmdRoll}},
|
||||
{"rollp", {ACLFlags.value("NONE"), 0, &AOClient::cmdRollP}},
|
||||
{"doc", {ACLFlags.value("NONE"), 0, &AOClient::cmdDoc}},
|
||||
{"cleardoc", {ACLFlags.value("NONE"), 0, &AOClient::cmdClearDoc}},
|
||||
{"cm", {ACLFlags.value("NONE"), 0, &AOClient::cmdCM}},
|
||||
{"uncm", {ACLFlags.value("CM"), 0, &AOClient::cmdUnCM}},
|
||||
{"invite", {ACLFlags.value("CM"), 1, &AOClient::cmdInvite}},
|
||||
{"uninvite", {ACLFlags.value("CM"), 1, &AOClient::cmdUnInvite}},
|
||||
{"lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
|
||||
{"area_lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
|
||||
{"spectatable", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
|
||||
{"area_spectate", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
|
||||
{"unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
|
||||
{"area_unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
|
||||
{"timer", {ACLFlags.value("CM"), 0, &AOClient::cmdTimer}},
|
||||
{"area", {ACLFlags.value("NONE"), 1, &AOClient::cmdArea}},
|
||||
{"play", {ACLFlags.value("CM"), 1, &AOClient::cmdPlay}},
|
||||
{"areakick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
|
||||
{"area_kick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
|
||||
{"randomchar", {ACLFlags.value("NONE"), 0, &AOClient::cmdRandomChar}},
|
||||
{"switch", {ACLFlags.value("NONE"), 1, &AOClient::cmdSwitch}},
|
||||
{"toggleglobal", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleGlobal}},
|
||||
{"mods", {ACLFlags.value("NONE"), 0, &AOClient::cmdMods}},
|
||||
{"commands", {ACLFlags.value("NONE"), 0, &AOClient::cmdCommands}},
|
||||
{"status", {ACLFlags.value("NONE"), 1, &AOClient::cmdStatus}},
|
||||
{"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}},
|
||||
{"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}},
|
||||
{"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}},
|
||||
{"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}},
|
||||
{"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}},
|
||||
{"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}},
|
||||
{"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}},
|
||||
{"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}},
|
||||
{"about", {ACLFlags.value("NONE"), 0, &AOClient::cmdAbout}},
|
||||
{"evidence_swap", {ACLFlags.value("CM"), 2, &AOClient::cmdEvidence_Swap}},
|
||||
{"notecard", {ACLFlags.value("NONE"), 1, &AOClient::cmdNoteCard}},
|
||||
{"notecardreveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
|
||||
{"notecard_reveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
|
||||
{"notecardclear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
|
||||
{"notecard_clear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
|
||||
{"8ball", {ACLFlags.value("NONE"), 1, &AOClient::cmd8Ball}},
|
||||
{"lm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdLM}},
|
||||
{"judgelog", {ACLFlags.value("CM"), 0, &AOClient::cmdJudgeLog}},
|
||||
{"allowblankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllowBlankposting}},
|
||||
{"allow_blankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllowBlankposting}},
|
||||
{"gimp", {ACLFlags.value("MUTE"), 1, &AOClient::cmdGimp}},
|
||||
{"ungimp", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnGimp}},
|
||||
{"baninfo", {ACLFlags.value("BAN"), 1, &AOClient::cmdBanInfo}},
|
||||
{"testify", {ACLFlags.value("CM"), 0, &AOClient::cmdTestify}},
|
||||
{"testimony", {ACLFlags.value("NONE"), 0, &AOClient::cmdTestimony}},
|
||||
{"examine", {ACLFlags.value("CM"), 0, &AOClient::cmdExamine}},
|
||||
{"pause", {ACLFlags.value("CM"), 0, &AOClient::cmdPauseTestimony}},
|
||||
{"delete", {ACLFlags.value("CM"), 0, &AOClient::cmdDeleteStatement}},
|
||||
{"update", {ACLFlags.value("CM"), 0, &AOClient::cmdUpdateStatement}},
|
||||
{"add", {ACLFlags.value("CM"), 0, &AOClient::cmdAddStatement}},
|
||||
{"reload", {ACLFlags.value("SUPER"), 0, &AOClient::cmdReload}},
|
||||
{"disemvowel", {ACLFlags.value("MUTE"), 1, &AOClient::cmdDisemvowel}},
|
||||
{"undisemvowel", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnDisemvowel}},
|
||||
{"shake", {ACLFlags.value("MUTE"), 1, &AOClient::cmdShake}},
|
||||
{"unshake", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnShake}},
|
||||
{"forceimmediate", {ACLFlags.value("CM"), 0, &AOClient::cmdForceImmediate}},
|
||||
{"force_noint_pres", {ACLFlags.value("CM"), 0, &AOClient::cmdForceImmediate}},
|
||||
{"allowiniswap", {ACLFlags.value("CM"), 0, &AOClient::cmdAllowIniswap}},
|
||||
{"allow_iniswap", {ACLFlags.value("CM"), 0, &AOClient::cmdAllowIniswap}},
|
||||
{"afk", {ACLFlags.value("NONE"), 0, &AOClient::cmdAfk}},
|
||||
{"savetestimony", {ACLFlags.value("NONE"), 1, &AOClient::cmdSaveTestimony}},
|
||||
{"loadtestimony", {ACLFlags.value("CM"), 1, &AOClient::cmdLoadTestimony}},
|
||||
{"permitsaving", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdPermitSaving}},
|
||||
{"mutepm", {ACLFlags.value("NONE"), 0, &AOClient::cmdMutePM}},
|
||||
{"toggleadverts", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleAdverts}},
|
||||
{"oocmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocMute}},
|
||||
{"ooc_mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocMute}},
|
||||
{"oocunmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocUnMute}},
|
||||
{"ooc_unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocUnMute}},
|
||||
{"blockwtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockWtce}},
|
||||
{"block_wtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockWtce}},
|
||||
{"unblockwtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockWtce}},
|
||||
{"unblock_wtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockWtce}},
|
||||
{"blockdj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockDj}},
|
||||
{"block_dj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockDj}},
|
||||
{"unblockdj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockDj}},
|
||||
{"unblock_dj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockDj}},
|
||||
{"charcurse", {ACLFlags.value("MUTE"), 1, &AOClient::cmdCharCurse}},
|
||||
{"uncharcurse", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnCharCurse}},
|
||||
{"charselect", {ACLFlags.value("NONE"), 0, &AOClient::cmdCharSelect}},
|
||||
{"togglemusic", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleMusic}},
|
||||
{"a", {ACLFlags.value("NONE"), 2, &AOClient::cmdA}},
|
||||
{"s", {ACLFlags.value("NONE"), 0, &AOClient::cmdS}},
|
||||
{"kickuid", {ACLFlags.value("KICK"), 2, &AOClient::cmdKickUid}},
|
||||
{"kick_uid", {ACLFlags.value("KICK"), 2, &AOClient::cmdKickUid}},
|
||||
{"firstperson", {ACLFlags.value("NONE"), 0, &AOClient::cmdFirstPerson}},
|
||||
{"updateban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}},
|
||||
{"update_ban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}},
|
||||
{"changepass", {ACLFlags.value("NONE"), 1, &AOClient::cmdChangePassword}},
|
||||
{"ignorebglist", {ACLFlags.value("IGNORE_BGLIST"), 0, &AOClient::cmdIgnoreBgList}},
|
||||
{"ignore_bglist", {ACLFlags.value("IGNORE_BGLIST"), 0, &AOClient::cmdIgnoreBgList}},
|
||||
{"notice", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNotice}},
|
||||
{"noticeg", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNoticeGlobal}},
|
||||
{"togglejukebox", {ACLFlags.value("None"), 0, &AOClient::cmdToggleJukebox}},
|
||||
{"help", {ACLFlags.value("NONE"), 1, &AOClient::cmdHelp}},
|
||||
{"clearcm", {ACLFlags.value("KICK"), 0, &AOClient::cmdClearCM}},
|
||||
{"togglemessage", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleAreaMessageOnJoin}},
|
||||
{"clearmessage", {ACLFlags.value("CM"), 0, &AOClient::cmdClearAreaMessage}},
|
||||
{"areamessage", {ACLFlags.value("CM"), 0, &AOClient::cmdAreaMessage}},
|
||||
{"addsong", {ACLFlags.value("CM"), 1, &AOClient::cmdAddSong}},
|
||||
{"addcategory", {ACLFlags.value("CM"), 1, &AOClient::cmdAddCategory}},
|
||||
{"removeentry", {ACLFlags.value("CM"), 1, &AOClient::cmdRemoveCategorySong}},
|
||||
{"toggleroot", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleRootlist}},
|
||||
{"clearcustom", {ACLFlags.value("CM"), 0, &AOClient::cmdClearCustom}}};
|
||||
{"login", {ACLRole::NONE, 0, &AOClient::cmdLogin}},
|
||||
{"getareas", {ACLRole::NONE, 0, &AOClient::cmdGetAreas}},
|
||||
{"gas", {ACLRole::NONE, 0, &AOClient::cmdGetAreas}},
|
||||
{"getarea", {ACLRole::NONE, 0, &AOClient::cmdGetArea}},
|
||||
{"ga", {ACLRole::NONE, 0, &AOClient::cmdGetArea}},
|
||||
{"ban", {ACLRole::BAN, 3, &AOClient::cmdBan}},
|
||||
{"kick", {ACLRole::KICK, 2, &AOClient::cmdKick}},
|
||||
{"changeauth", {ACLRole::SUPER, 0, &AOClient::cmdChangeAuth}},
|
||||
{"rootpass", {ACLRole::SUPER, 1, &AOClient::cmdSetRootPass}},
|
||||
{"background", {ACLRole::NONE, 1, &AOClient::cmdSetBackground}},
|
||||
{"bg", {ACLRole::NONE, 1, &AOClient::cmdSetBackground}},
|
||||
{"bglock", {ACLRole::BGLOCK, 0, &AOClient::cmdBgLock}},
|
||||
{"bgunlock", {ACLRole::BGLOCK, 0, &AOClient::cmdBgUnlock}},
|
||||
{"adduser", {ACLRole::MODIFY_USERS, 2, &AOClient::cmdAddUser}},
|
||||
{"removeuser", {ACLRole::MODIFY_USERS, 1, &AOClient::cmdRemoveUser}},
|
||||
{"listusers", {ACLRole::MODIFY_USERS, 0, &AOClient::cmdListUsers}},
|
||||
{"setperms", {ACLRole::MODIFY_USERS, 2, &AOClient::cmdSetPerms}},
|
||||
{"removeperms", {ACLRole::MODIFY_USERS, 1, &AOClient::cmdRemovePerms}},
|
||||
{"listperms", {ACLRole::NONE, 0, &AOClient::cmdListPerms}},
|
||||
{"logout", {ACLRole::NONE, 0, &AOClient::cmdLogout}},
|
||||
{"pos", {ACLRole::NONE, 1, &AOClient::cmdPos}},
|
||||
{"g", {ACLRole::NONE, 1, &AOClient::cmdG}},
|
||||
{"need", {ACLRole::NONE, 1, &AOClient::cmdNeed}},
|
||||
{"coinflip", {ACLRole::NONE, 0, &AOClient::cmdFlip}},
|
||||
{"roll", {ACLRole::NONE, 0, &AOClient::cmdRoll}},
|
||||
{"r", {ACLRole::NONE, 0, &AOClient::cmdRoll}},
|
||||
{"rollp", {ACLRole::NONE, 0, &AOClient::cmdRollP}},
|
||||
{"doc", {ACLRole::NONE, 0, &AOClient::cmdDoc}},
|
||||
{"cleardoc", {ACLRole::NONE, 0, &AOClient::cmdClearDoc}},
|
||||
{"cm", {ACLRole::NONE, 0, &AOClient::cmdCM}},
|
||||
{"uncm", {ACLRole::CM, 0, &AOClient::cmdUnCM}},
|
||||
{"invite", {ACLRole::CM, 1, &AOClient::cmdInvite}},
|
||||
{"uninvite", {ACLRole::CM, 1, &AOClient::cmdUnInvite}},
|
||||
{"lock", {ACLRole::CM, 0, &AOClient::cmdLock}},
|
||||
{"area_lock", {ACLRole::CM, 0, &AOClient::cmdLock}},
|
||||
{"spectatable", {ACLRole::CM, 0, &AOClient::cmdSpectatable}},
|
||||
{"area_spectate", {ACLRole::CM, 0, &AOClient::cmdSpectatable}},
|
||||
{"unlock", {ACLRole::CM, 0, &AOClient::cmdUnLock}},
|
||||
{"area_unlock", {ACLRole::CM, 0, &AOClient::cmdUnLock}},
|
||||
{"timer", {ACLRole::CM, 0, &AOClient::cmdTimer}},
|
||||
{"area", {ACLRole::NONE, 1, &AOClient::cmdArea}},
|
||||
{"play", {ACLRole::CM, 1, &AOClient::cmdPlay}},
|
||||
{"areakick", {ACLRole::CM, 1, &AOClient::cmdAreaKick}},
|
||||
{"area_kick", {ACLRole::CM, 1, &AOClient::cmdAreaKick}},
|
||||
{"randomchar", {ACLRole::NONE, 0, &AOClient::cmdRandomChar}},
|
||||
{"switch", {ACLRole::NONE, 1, &AOClient::cmdSwitch}},
|
||||
{"toggleglobal", {ACLRole::NONE, 0, &AOClient::cmdToggleGlobal}},
|
||||
{"mods", {ACLRole::NONE, 0, &AOClient::cmdMods}},
|
||||
{"commands", {ACLRole::NONE, 0, &AOClient::cmdCommands}},
|
||||
{"status", {ACLRole::NONE, 1, &AOClient::cmdStatus}},
|
||||
{"forcepos", {ACLRole::CM, 2, &AOClient::cmdForcePos}},
|
||||
{"currentmusic", {ACLRole::NONE, 0, &AOClient::cmdCurrentMusic}},
|
||||
{"pm", {ACLRole::NONE, 2, &AOClient::cmdPM}},
|
||||
{"evidence_mod", {ACLRole::EVI_MOD, 1, &AOClient::cmdEvidenceMod}},
|
||||
{"motd", {ACLRole::NONE, 0, &AOClient::cmdMOTD}},
|
||||
{"announce", {ACLRole::ANNOUNCE, 1, &AOClient::cmdAnnounce}},
|
||||
{"m", {ACLRole::MODCHAT, 1, &AOClient::cmdM}},
|
||||
{"gm", {ACLRole::MODCHAT, 1, &AOClient::cmdGM}},
|
||||
{"mute", {ACLRole::MUTE, 1, &AOClient::cmdMute}},
|
||||
{"unmute", {ACLRole::MUTE, 1, &AOClient::cmdUnMute}},
|
||||
{"bans", {ACLRole::BAN, 0, &AOClient::cmdBans}},
|
||||
{"unban", {ACLRole::BAN, 1, &AOClient::cmdUnBan}},
|
||||
{"subtheme", {ACLRole::CM, 1, &AOClient::cmdSubTheme}},
|
||||
{"about", {ACLRole::NONE, 0, &AOClient::cmdAbout}},
|
||||
{"evidence_swap", {ACLRole::CM, 2, &AOClient::cmdEvidence_Swap}},
|
||||
{"notecard", {ACLRole::NONE, 1, &AOClient::cmdNoteCard}},
|
||||
{"notecardreveal", {ACLRole::CM, 0, &AOClient::cmdNoteCardReveal}},
|
||||
{"notecard_reveal", {ACLRole::CM, 0, &AOClient::cmdNoteCardReveal}},
|
||||
{"notecardclear", {ACLRole::NONE, 0, &AOClient::cmdNoteCardClear}},
|
||||
{"notecard_clear", {ACLRole::NONE, 0, &AOClient::cmdNoteCardClear}},
|
||||
{"8ball", {ACLRole::NONE, 1, &AOClient::cmd8Ball}},
|
||||
{"lm", {ACLRole::MODCHAT, 1, &AOClient::cmdLM}},
|
||||
{"judgelog", {ACLRole::CM, 0, &AOClient::cmdJudgeLog}},
|
||||
{"allowblankposting", {ACLRole::MODCHAT, 0, &AOClient::cmdAllowBlankposting}},
|
||||
{"allow_blankposting", {ACLRole::MODCHAT, 0, &AOClient::cmdAllowBlankposting}},
|
||||
{"gimp", {ACLRole::MUTE, 1, &AOClient::cmdGimp}},
|
||||
{"ungimp", {ACLRole::MUTE, 1, &AOClient::cmdUnGimp}},
|
||||
{"baninfo", {ACLRole::BAN, 1, &AOClient::cmdBanInfo}},
|
||||
{"testify", {ACLRole::CM, 0, &AOClient::cmdTestify}},
|
||||
{"testimony", {ACLRole::NONE, 0, &AOClient::cmdTestimony}},
|
||||
{"examine", {ACLRole::CM, 0, &AOClient::cmdExamine}},
|
||||
{"pause", {ACLRole::CM, 0, &AOClient::cmdPauseTestimony}},
|
||||
{"delete", {ACLRole::CM, 0, &AOClient::cmdDeleteStatement}},
|
||||
{"update", {ACLRole::CM, 0, &AOClient::cmdUpdateStatement}},
|
||||
{"add", {ACLRole::CM, 0, &AOClient::cmdAddStatement}},
|
||||
{"reload", {ACLRole::SUPER, 0, &AOClient::cmdReload}},
|
||||
{"disemvowel", {ACLRole::MUTE, 1, &AOClient::cmdDisemvowel}},
|
||||
{"undisemvowel", {ACLRole::MUTE, 1, &AOClient::cmdUnDisemvowel}},
|
||||
{"shake", {ACLRole::MUTE, 1, &AOClient::cmdShake}},
|
||||
{"unshake", {ACLRole::MUTE, 1, &AOClient::cmdUnShake}},
|
||||
{"forceimmediate", {ACLRole::CM, 0, &AOClient::cmdForceImmediate}},
|
||||
{"force_noint_pres", {ACLRole::CM, 0, &AOClient::cmdForceImmediate}},
|
||||
{"allowiniswap", {ACLRole::CM, 0, &AOClient::cmdAllowIniswap}},
|
||||
{"allow_iniswap", {ACLRole::CM, 0, &AOClient::cmdAllowIniswap}},
|
||||
{"afk", {ACLRole::NONE, 0, &AOClient::cmdAfk}},
|
||||
{"savetestimony", {ACLRole::NONE, 1, &AOClient::cmdSaveTestimony}},
|
||||
{"loadtestimony", {ACLRole::CM, 1, &AOClient::cmdLoadTestimony}},
|
||||
{"permitsaving", {ACLRole::MODCHAT, 1, &AOClient::cmdPermitSaving}},
|
||||
{"mutepm", {ACLRole::NONE, 0, &AOClient::cmdMutePM}},
|
||||
{"toggleadverts", {ACLRole::NONE, 0, &AOClient::cmdToggleAdverts}},
|
||||
{"oocmute", {ACLRole::MUTE, 1, &AOClient::cmdOocMute}},
|
||||
{"ooc_mute", {ACLRole::MUTE, 1, &AOClient::cmdOocMute}},
|
||||
{"oocunmute", {ACLRole::MUTE, 1, &AOClient::cmdOocUnMute}},
|
||||
{"ooc_unmute", {ACLRole::MUTE, 1, &AOClient::cmdOocUnMute}},
|
||||
{"blockwtce", {ACLRole::MUTE, 1, &AOClient::cmdBlockWtce}},
|
||||
{"block_wtce", {ACLRole::MUTE, 1, &AOClient::cmdBlockWtce}},
|
||||
{"unblockwtce", {ACLRole::MUTE, 1, &AOClient::cmdUnBlockWtce}},
|
||||
{"unblock_wtce", {ACLRole::MUTE, 1, &AOClient::cmdUnBlockWtce}},
|
||||
{"blockdj", {ACLRole::MUTE, 1, &AOClient::cmdBlockDj}},
|
||||
{"block_dj", {ACLRole::MUTE, 1, &AOClient::cmdBlockDj}},
|
||||
{"unblockdj", {ACLRole::MUTE, 1, &AOClient::cmdUnBlockDj}},
|
||||
{"unblock_dj", {ACLRole::MUTE, 1, &AOClient::cmdUnBlockDj}},
|
||||
{"charcurse", {ACLRole::MUTE, 1, &AOClient::cmdCharCurse}},
|
||||
{"uncharcurse", {ACLRole::MUTE, 1, &AOClient::cmdUnCharCurse}},
|
||||
{"charselect", {ACLRole::NONE, 0, &AOClient::cmdCharSelect}},
|
||||
{"togglemusic", {ACLRole::CM, 0, &AOClient::cmdToggleMusic}},
|
||||
{"a", {ACLRole::NONE, 2, &AOClient::cmdA}},
|
||||
{"s", {ACLRole::NONE, 0, &AOClient::cmdS}},
|
||||
{"kickuid", {ACLRole::KICK, 2, &AOClient::cmdKickUid}},
|
||||
{"kick_uid", {ACLRole::KICK, 2, &AOClient::cmdKickUid}},
|
||||
{"firstperson", {ACLRole::NONE, 0, &AOClient::cmdFirstPerson}},
|
||||
{"updateban", {ACLRole::BAN, 3, &AOClient::cmdUpdateBan}},
|
||||
{"update_ban", {ACLRole::BAN, 3, &AOClient::cmdUpdateBan}},
|
||||
{"changepass", {ACLRole::NONE, 1, &AOClient::cmdChangePassword}},
|
||||
{"ignorebglist", {ACLRole::IGNORE_BGLIST, 0, &AOClient::cmdIgnoreBgList}},
|
||||
{"ignore_bglist", {ACLRole::IGNORE_BGLIST, 0, &AOClient::cmdIgnoreBgList}},
|
||||
{"notice", {ACLRole::SEND_NOTICE, 1, &AOClient::cmdNotice}},
|
||||
{"noticeg", {ACLRole::SEND_NOTICE, 1, &AOClient::cmdNoticeGlobal}},
|
||||
{"togglejukebox", {ACLRole::NONE, 0, &AOClient::cmdToggleJukebox}},
|
||||
{"help", {ACLRole::NONE, 1, &AOClient::cmdHelp}},
|
||||
{"clearcm", {ACLRole::KICK, 0, &AOClient::cmdClearCM}},
|
||||
{"togglemessage", {ACLRole::CM, 0, &AOClient::cmdToggleAreaMessageOnJoin}},
|
||||
{"clearmessage", {ACLRole::CM, 0, &AOClient::cmdClearAreaMessage}},
|
||||
{"areamessage", {ACLRole::CM, 0, &AOClient::cmdAreaMessage}},
|
||||
{"addsong", {ACLRole::CM, 1, &AOClient::cmdAddSong}},
|
||||
{"addcategory", {ACLRole::CM, 1, &AOClient::cmdAddCategory}},
|
||||
{"removeentry", {ACLRole::CM, 1, &AOClient::cmdRemoveCategorySong}},
|
||||
{"toggleroot", {ACLRole::CM, 0, &AOClient::cmdToggleRootlist}},
|
||||
{"clearcustom", {ACLRole::CM, 0, &AOClient::cmdClearCustom}}};
|
||||
|
||||
/**
|
||||
* @brief Filled with part of a packet if said packet could not be read fully from the client's socket.
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "include/acl_roles_handler.h"
|
||||
|
||||
/**
|
||||
* @brief A class used to handle database interaction.
|
||||
*
|
||||
@ -138,14 +140,14 @@ class DBManager : public QObject
|
||||
* @param username The username clients can use to log in with.
|
||||
* @param salt The salt to obfuscate the password with.
|
||||
* @param password The user's password.
|
||||
* @param acl The user's authority bitflag -- what special permissions does the user have.
|
||||
* @param acl The ACL role identifier.
|
||||
*
|
||||
* @return False if the user already exists, true if the user was successfully created.
|
||||
*
|
||||
* @see AOClient::cmdLogin() and AOClient::cmdLogout() for the username and password's contexts.
|
||||
* @see AOClient::ACLFlags for the potential special permissions a user may have.
|
||||
* @see AOClient#cmdLogin and AOClient#cmdLogout for the username and password's contexts.
|
||||
* @see ACLRolesHandler for details regarding ACL roles and ACL role identifiers.
|
||||
*/
|
||||
bool createUser(QString username, QString salt, QString password, unsigned long long acl);
|
||||
bool createUser(QString username, QString salt, QString password, QString acl);
|
||||
|
||||
/**
|
||||
* @brief Deletes an authorised user from the database.
|
||||
@ -157,16 +159,15 @@ class DBManager : public QObject
|
||||
bool deleteUser(QString username);
|
||||
|
||||
/**
|
||||
* @brief Gets the permissions of a given user.
|
||||
* @brief Gets the ACL role of a given user.
|
||||
*
|
||||
* @param moderator_name The authorised user's name.
|
||||
* @param username The authorised user's name.
|
||||
*
|
||||
* @return `0` if `moderator_name` is empty, `0` if such user does not exist in the Users table,
|
||||
* or the primitive representation of an AOClient::ACLFlags permission matrix if neither of the above are true.
|
||||
* @return The name identifier of a ACL role.
|
||||
*
|
||||
* @see AOClient::ACLFlags for the potential permissions a user may have.
|
||||
* @see ACLRolesHandler for details about ACL roles.
|
||||
*/
|
||||
unsigned long long getACL(QString moderator_name);
|
||||
QString getACL(QString f_username);
|
||||
|
||||
/**
|
||||
* @brief Authenticates a given user.
|
||||
@ -180,38 +181,17 @@ class DBManager : public QObject
|
||||
bool authenticate(QString username, QString password);
|
||||
|
||||
/**
|
||||
* @brief Updates the permissions of a given user.
|
||||
* @brief Updates the ACL role identifier of a given user.
|
||||
*
|
||||
* @details This function can add or remove permissions as needed.
|
||||
* `acl` determines what permissions are modified, while `mode` determines whether said permissions are
|
||||
* added or removed.
|
||||
* @details This function **DOES NOT** modify the ACL role itself. It is simply an identifier that determines which ACL role the user is linked to.
|
||||
*
|
||||
* `acl` **is not** the user's current permissions *or* the sum permissions you want for the user at the end
|
||||
* -- it is the 'difference' between the user's current and desired permissions.
|
||||
* @param username The username of the user to be updated.
|
||||
*
|
||||
* If `acl` is `"NONE"`, then no matter the mode, the user's permissions are cleared.
|
||||
*
|
||||
* For some practical examples, consult this example table:
|
||||
*
|
||||
* | Starting permissions | `acl` | `mode` | Resulting permissions |
|
||||
* | -------------------: | :---------: | :-----: | :-------------------- |
|
||||
* | KICK | BAN | `TRUE` | KICK, BAN |
|
||||
* | BAN, KICK | BAN | `TRUE` | KICK, BAN |
|
||||
* | KICK | BAN, BGLOCK | `TRUE` | KICK, BAN, BGLOCK |
|
||||
* | BGLOCK, BAN, KICK | NONE | `TRUE` | NONE |
|
||||
* | KICK | BAN | `FALSE` | KICK |
|
||||
* | BAN, KICK | BAN | `FALSE` | KICK |
|
||||
* | BGLOCK, BAN, KICK | BAN, BGLOCK | `FALSE` | KICK |
|
||||
* | BGLOCK, BAN, KICK | NONE | `FALSE` | NONE |
|
||||
*
|
||||
* @param username The username of the user whose permissions should be updated.
|
||||
* @param acl The primitive representation of the permission matrix being modified.
|
||||
* @param mode If true, the permissions described in `acl` are *added* to the user;
|
||||
* if false, they are removed instead.
|
||||
* @param acl The ACL role identifier.
|
||||
*
|
||||
* @return True if the modification was successful, false if the user does not exist in the records.
|
||||
*/
|
||||
bool updateACL(QString username, unsigned long long acl, bool mode);
|
||||
bool updateACL(QString username, QString acl);
|
||||
|
||||
/**
|
||||
* @brief Returns a list of the recorded users' usernames, ordered by ID.
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "include/aopacket.h"
|
||||
|
||||
class ACLRolesHandler;
|
||||
class Advertiser;
|
||||
class AOClient;
|
||||
class AreaData;
|
||||
@ -285,6 +286,8 @@ class Server : public QObject
|
||||
*/
|
||||
DBManager *getDatabaseManager();
|
||||
|
||||
ACLRolesHandler *getACLRolesHandler();
|
||||
|
||||
/**
|
||||
* @brief The server-wide global timer.
|
||||
*/
|
||||
@ -508,6 +511,8 @@ class Server : public QObject
|
||||
*/
|
||||
DBManager *db_manager;
|
||||
|
||||
ACLRolesHandler *acl_roles_handler;
|
||||
|
||||
/**
|
||||
* @brief Connects new AOClient to logger and disconnect handling.
|
||||
**/
|
||||
|
283
core/src/acl_roles_handler.cpp
Normal file
283
core/src/acl_roles_handler.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
#include "include/acl_roles_handler.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
|
||||
const QString ACLRolesHandler::NONE_ID = "NONE";
|
||||
|
||||
const QString ACLRolesHandler::SUPER_ID = "SUPER";
|
||||
|
||||
const QHash<QString, ACLRole> ACLRolesHandler::readonly_roles{
|
||||
{ACLRolesHandler::NONE_ID, ACLRole(ACLRole::NONE)},
|
||||
{ACLRolesHandler::SUPER_ID, ACLRole(ACLRole::SUPER)},
|
||||
};
|
||||
|
||||
const QHash<ACLRole::Permission, QString> ACLRole::permission_captions{
|
||||
{
|
||||
ACLRole::Permission::KICK,
|
||||
"kick",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::BAN,
|
||||
"ban",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::BGLOCK,
|
||||
"lock_background",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::MODIFY_USERS,
|
||||
"modify_users",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::CM,
|
||||
"set_gamemaster",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::GLOBAL_TIMER,
|
||||
"use_global_timer",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::EVI_MOD,
|
||||
"modify_evidence",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::MOTD,
|
||||
"set_motd",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::ANNOUNCE,
|
||||
"announcer",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::MODCHAT,
|
||||
"chat_moderator",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::MUTE,
|
||||
"mute",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::UNCM,
|
||||
"remove_gamemaster",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::SAVETEST,
|
||||
"save_testimony",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::FORCE_CHARSELECT,
|
||||
"force_charselect",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::BYPASS_LOCKS,
|
||||
"bypass_locks",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::IGNORE_BGLIST,
|
||||
"ignore_bg_list",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::SEND_NOTICE,
|
||||
"send_notice",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::JUKEBOX,
|
||||
"jukebox",
|
||||
},
|
||||
{
|
||||
ACLRole::Permission::SUPER,
|
||||
"super",
|
||||
},
|
||||
};
|
||||
|
||||
ACLRole::ACLRole() {}
|
||||
|
||||
ACLRole::ACLRole(ACLRole::Permissions f_permissions) :
|
||||
m_permissions(f_permissions)
|
||||
{
|
||||
}
|
||||
|
||||
ACLRole::~ACLRole() {}
|
||||
|
||||
ACLRole::Permissions ACLRole::getPermissions() const
|
||||
{
|
||||
return m_permissions;
|
||||
}
|
||||
|
||||
bool ACLRole::checkPermission(Permission f_permission) const
|
||||
{
|
||||
if (f_permission == ACLRole::NONE) {
|
||||
return true;
|
||||
}
|
||||
return m_permissions.testFlag(f_permission);
|
||||
}
|
||||
|
||||
void ACLRole::setPermissions(ACLRole::Permissions f_permissions)
|
||||
{
|
||||
m_permissions = f_permissions;
|
||||
}
|
||||
|
||||
void ACLRole::setPermission(Permission f_permission, bool f_mode)
|
||||
{
|
||||
m_permissions.setFlag(f_permission, f_mode);
|
||||
}
|
||||
|
||||
ACLRolesHandler::ACLRolesHandler(QObject *parent) :
|
||||
QObject(parent)
|
||||
{}
|
||||
|
||||
ACLRolesHandler::~ACLRolesHandler() {}
|
||||
|
||||
bool ACLRolesHandler::roleExists(QString f_id)
|
||||
{
|
||||
f_id = f_id.toUpper();
|
||||
return readonly_roles.contains(f_id) || m_roles.contains(f_id);
|
||||
}
|
||||
|
||||
ACLRole ACLRolesHandler::getRoleById(QString f_id)
|
||||
{
|
||||
f_id = f_id.toUpper();
|
||||
return readonly_roles.contains(f_id) ? readonly_roles.value(f_id) : m_roles.value(f_id);
|
||||
}
|
||||
|
||||
bool ACLRolesHandler::insertRole(QString f_id, ACLRole f_role)
|
||||
{
|
||||
f_id = f_id.toUpper();
|
||||
if (readonly_roles.contains(f_id)) {
|
||||
return false;
|
||||
}
|
||||
m_roles.insert(f_id, f_role);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ACLRolesHandler::removeRole(QString f_id)
|
||||
{
|
||||
f_id = f_id.toUpper();
|
||||
if (readonly_roles.contains(f_id)) {
|
||||
return false;
|
||||
}
|
||||
else if (!m_roles.contains(f_id)) {
|
||||
return false;
|
||||
}
|
||||
m_roles.remove(f_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ACLRolesHandler::clearRoles()
|
||||
{
|
||||
m_roles.clear();
|
||||
}
|
||||
|
||||
bool ACLRolesHandler::loadFile(QString f_file_name)
|
||||
{
|
||||
QSettings l_settings(f_file_name, QSettings::IniFormat);
|
||||
l_settings.setIniCodec("UTF-8");
|
||||
if (l_settings.status() != QSettings::NoError) {
|
||||
switch (l_settings.status()) {
|
||||
case QSettings::AccessError:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: failed to open file; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
|
||||
case QSettings::FormatError:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: file is malformed; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: unknown error; aborting; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_roles.clear();
|
||||
QStringList l_role_records;
|
||||
const QStringList l_group_list = l_settings.childGroups();
|
||||
for (const QString &i_group : l_group_list) {
|
||||
const QString l_upper_group = i_group.toUpper();
|
||||
if (readonly_roles.contains(l_upper_group)) {
|
||||
qWarning() << "ACLRolesHandler warning: cannot modify role;" << i_group << "is read-only";
|
||||
continue;
|
||||
}
|
||||
|
||||
l_settings.beginGroup(i_group);
|
||||
if (l_role_records.contains(l_upper_group)) {
|
||||
qWarning() << "ACLRolesHandler warning: role" << l_upper_group << "already exist! Overwriting.";
|
||||
}
|
||||
l_role_records.append(l_upper_group);
|
||||
|
||||
ACLRole l_role;
|
||||
const QList<ACLRole::Permission> l_permissions = ACLRole::permission_captions.keys();
|
||||
for (const ACLRole::Permission &i_permission : l_permissions) {
|
||||
l_role.setPermission(i_permission, l_settings.value(ACLRole::permission_captions.value(i_permission), false).toBool());
|
||||
}
|
||||
m_roles.insert(l_upper_group, std::move(l_role));
|
||||
|
||||
l_settings.endGroup();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ACLRolesHandler::saveFile(QString f_file_name)
|
||||
{
|
||||
QSettings l_settings(f_file_name, QSettings::IniFormat);
|
||||
l_settings.setIniCodec("UTF-8");
|
||||
if (l_settings.status() != QSettings::NoError) {
|
||||
switch (l_settings.status()) {
|
||||
case QSettings::AccessError:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: failed to open file; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
|
||||
case QSettings::FormatError:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: file is malformed; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: unknown error; aborting; aborting (" << f_file_name << ")";
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
l_settings.clear();
|
||||
const QStringList l_role_id_list = m_roles.keys();
|
||||
for (const QString &l_role_id : l_role_id_list) {
|
||||
const QString l_upper_role_id = l_role_id.toUpper();
|
||||
if (readonly_roles.contains(l_upper_role_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const ACLRole i_role = m_roles.value(l_upper_role_id);
|
||||
l_settings.beginGroup(l_upper_role_id);
|
||||
if (i_role.checkPermission(ACLRole::SUPER)) {
|
||||
l_settings.setValue(ACLRole::permission_captions.value(ACLRole::SUPER), true);
|
||||
}
|
||||
else {
|
||||
const QList<ACLRole::Permission> l_permissions = ACLRole::permission_captions.keys();
|
||||
for (const ACLRole::Permission i_permission : l_permissions) {
|
||||
if (!i_role.checkPermission(i_permission)) {
|
||||
continue;
|
||||
}
|
||||
l_settings.setValue(ACLRole::permission_captions.value(i_permission), true);
|
||||
}
|
||||
}
|
||||
l_settings.endGroup();
|
||||
}
|
||||
l_settings.sync();
|
||||
if (l_settings.status() != QSettings::NoError) {
|
||||
qWarning() << "ACLRolesHandler"
|
||||
<< "error: failed to write file; aborting (" << f_file_name << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -87,13 +87,13 @@ void AOClient::handlePacket(AOPacket packet)
|
||||
qDebug() << "Received packet:" << packet.header << ":" << packet.contents << "args length:" << packet.contents.length();
|
||||
#endif
|
||||
AreaData *l_area = server->getAreaById(m_current_area);
|
||||
PacketInfo l_info = packets.value(packet.header, {false, 0, &AOClient::pktDefault});
|
||||
PacketInfo l_info = packets.value(packet.header, {ACLRole::NONE, 0, &AOClient::pktDefault});
|
||||
|
||||
if (packet.contents.join("").size() > 16384) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checkAuth(l_info.acl_mask)) {
|
||||
if (!checkPermission(l_info.acl_permission)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ void AOClient::changeArea(int new_area)
|
||||
sendServerMessage("You are already in area " + server->getAreaName(m_current_area));
|
||||
return;
|
||||
}
|
||||
if (server->getAreaById(new_area)->lockStatus() == AreaData::LockStatus::LOCKED && !server->getAreaById(new_area)->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS"))) {
|
||||
if (server->getAreaById(new_area)->lockStatus() == AreaData::LockStatus::LOCKED && !server->getAreaById(new_area)->invited().contains(m_id) && !checkPermission(ACLRole::BYPASS_LOCKS)) {
|
||||
sendServerMessage("Area " + server->getAreaName(new_area) + " is locked.");
|
||||
return;
|
||||
}
|
||||
@ -202,9 +202,9 @@ void AOClient::changePosition(QString new_pos)
|
||||
|
||||
void AOClient::handleCommand(QString command, int argc, QStringList argv)
|
||||
{
|
||||
CommandInfo l_info = commands.value(command, {false, -1, &AOClient::cmdDefault});
|
||||
CommandInfo l_info = commands.value(command, {ACLRole::NONE, -1, &AOClient::cmdDefault});
|
||||
|
||||
if (!checkAuth(l_info.acl_mask)) {
|
||||
if (!checkPermission(l_info.acl_permission)) {
|
||||
sendServerMessage("You do not have permission to use that command.");
|
||||
return;
|
||||
}
|
||||
@ -331,31 +331,22 @@ void AOClient::sendServerBroadcast(QString message)
|
||||
server->broadcast(AOPacket("CT", {ConfigManager::serverName(), message, "1"}));
|
||||
}
|
||||
|
||||
bool AOClient::checkAuth(unsigned long long acl_mask)
|
||||
bool AOClient::checkPermission(ACLRole::Permission f_permission) const
|
||||
{
|
||||
#ifdef SKIP_AUTH
|
||||
return true;
|
||||
#endif
|
||||
if (acl_mask != ACLFlags.value("NONE")) {
|
||||
if (acl_mask == ACLFlags.value("CM")) {
|
||||
AreaData *l_area = server->getAreaById(m_current_area);
|
||||
if (l_area->owners().contains(m_id))
|
||||
return true;
|
||||
}
|
||||
else if (!m_authenticated) {
|
||||
return false;
|
||||
}
|
||||
switch (ConfigManager::authType()) {
|
||||
case DataTypes::AuthType::SIMPLE:
|
||||
return m_authenticated;
|
||||
break;
|
||||
case DataTypes::AuthType::ADVANCED:
|
||||
unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
|
||||
return (l_user_acl & acl_mask) != 0;
|
||||
break;
|
||||
}
|
||||
if (f_permission == ACLRole::NONE) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (!isAuthenticated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ConfigManager::authType() == DataTypes::AuthType::SIMPLE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ACLRole l_role = server->getACLRolesHandler()->getRoleById(m_acl_role_id);
|
||||
return l_role.checkPermission(f_permission);
|
||||
}
|
||||
|
||||
QString AOClient::getIpid() const
|
||||
@ -373,6 +364,11 @@ bool AOClient::hasJoined() const
|
||||
return m_joined;
|
||||
}
|
||||
|
||||
bool AOClient::isAuthenticated() const
|
||||
{
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
Server *AOClient::getServer() { return server; }
|
||||
|
||||
void AOClient::onAfkTimeout()
|
||||
|
@ -78,7 +78,7 @@ void AOClient::cmdUnCM(int argc, QStringList argv)
|
||||
l_uid = m_id;
|
||||
sendServerMessage("You are no longer CM in this area.");
|
||||
}
|
||||
else if (checkAuth(ACLFlags.value("UNCM")) && argc == 1) {
|
||||
else if (checkPermission(ACLRole::UNCM) && argc == 1) {
|
||||
bool conv_ok = false;
|
||||
l_uid = argv[0].toInt(&conv_ok);
|
||||
if (!conv_ok) {
|
||||
@ -366,7 +366,7 @@ void AOClient::cmdJudgeLog(int argc, QStringList argv)
|
||||
}
|
||||
QString l_message = l_area->judgelog().join("\n");
|
||||
// Judgelog contains an IPID, so we shouldn't send that unless the caller has appropriate permissions
|
||||
if (checkAuth(ACLFlags.value("KICK")) == 1 || checkAuth(ACLFlags.value("BAN")) == 1) {
|
||||
if (checkPermission(ACLRole::KICK) || checkPermission(ACLRole::BAN)) {
|
||||
sendServerMessage(l_message);
|
||||
}
|
||||
else {
|
||||
|
@ -90,7 +90,7 @@ void AOClient::cmdSetRootPass(int argc, QStringList argv)
|
||||
#endif
|
||||
QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0'));
|
||||
|
||||
server->getDatabaseManager()->createUser("root", l_salt, argv[0], ACLFlags.value("SUPER"));
|
||||
server->getDatabaseManager()->createUser("root", l_salt, argv[0], ACLRolesHandler::SUPER_ID);
|
||||
}
|
||||
|
||||
void AOClient::cmdAddUser(int argc, QStringList argv)
|
||||
@ -111,8 +111,8 @@ void AOClient::cmdAddUser(int argc, QStringList argv)
|
||||
#endif
|
||||
QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0'));
|
||||
|
||||
if (server->getDatabaseManager()->createUser(argv[0], l_salt, argv[1], ACLFlags.value("NONE")))
|
||||
sendServerMessage("Created user " + argv[0] + ".\nUse /addperm to modify their permissions.");
|
||||
if (server->getDatabaseManager()->createUser(argv[0], l_salt, argv[1], ACLRolesHandler::NONE_ID))
|
||||
sendServerMessage("Created user " + argv[0] + ".\nUse /setperms to modify their permissions.");
|
||||
else
|
||||
sendServerMessage("Unable to create user " + argv[0] + ".\nDoes a user with that name already exist?");
|
||||
}
|
||||
@ -129,125 +129,73 @@ void AOClient::cmdRemoveUser(int argc, QStringList argv)
|
||||
|
||||
void AOClient::cmdListPerms(int argc, QStringList argv)
|
||||
{
|
||||
unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
|
||||
const ACLRole l_role = server->getACLRolesHandler()->getRoleById(m_acl_role_id);
|
||||
|
||||
ACLRole l_target_role = l_role;
|
||||
QStringList l_message;
|
||||
const QStringList l_keys = ACLFlags.keys();
|
||||
if (argc == 0) {
|
||||
// Just print out all permissions available to the user.
|
||||
l_message.append("You have been given the following permissions:");
|
||||
for (const QString &l_perm : l_keys) {
|
||||
if (l_perm == "NONE")
|
||||
; // don't need to list this one
|
||||
else if (l_perm == "SUPER") {
|
||||
if (l_user_acl == ACLFlags.value("SUPER")) // This has to be checked separately, because SUPER & anything will always be truthy
|
||||
l_message.append("SUPER (Be careful! This grants the user all permissions.)");
|
||||
}
|
||||
else if ((ACLFlags.value(l_perm) & l_user_acl) == 0)
|
||||
; // user doesn't have this permission, don't print it
|
||||
else
|
||||
l_message.append(l_perm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((l_user_acl & ACLFlags.value("MODIFY_USERS")) == 0) {
|
||||
if (!l_role.checkPermission(ACLRole::MODIFY_USERS)) {
|
||||
sendServerMessage("You do not have permission to view other users' permissions.");
|
||||
return;
|
||||
}
|
||||
|
||||
l_message.append("User " + argv[0] + " has the following permissions:");
|
||||
unsigned long long l_acl = server->getDatabaseManager()->getACL(argv[0]);
|
||||
if (l_acl == 0) {
|
||||
sendServerMessage("This user either doesn't exist, or has no permissions set.");
|
||||
return;
|
||||
}
|
||||
l_target_role = server->getACLRolesHandler()->getRoleById(argv[0]);
|
||||
}
|
||||
|
||||
for (const QString &l_perm : l_keys) {
|
||||
if ((ACLFlags.value(l_perm) & l_acl) != 0 && l_perm != "SUPER") {
|
||||
l_message.append(l_perm);
|
||||
if (l_target_role.getPermissions() == ACLRole::NONE) {
|
||||
l_message.append("NONE");
|
||||
}
|
||||
else if (l_target_role.checkPermission(ACLRole::SUPER)) {
|
||||
l_message.append("SUPER (Be careful! This grants the user all permissions.)");
|
||||
}
|
||||
else {
|
||||
const QList<ACLRole::Permission> l_permissions = ACLRole::permission_captions.keys();
|
||||
for (const ACLRole::Permission i_permission : l_permissions) {
|
||||
if (l_target_role.checkPermission(i_permission)) {
|
||||
l_message.append(ACLRole::permission_captions.value(i_permission));
|
||||
}
|
||||
}
|
||||
}
|
||||
sendServerMessage(l_message.join("\n"));
|
||||
}
|
||||
|
||||
void AOClient::cmdAddPerms(int argc, QStringList argv)
|
||||
void AOClient::cmdSetPerms(int argc, QStringList argv)
|
||||
{
|
||||
Q_UNUSED(argc);
|
||||
|
||||
unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
|
||||
argv[1] = argv[1].toUpper();
|
||||
const QStringList l_keys = ACLFlags.keys();
|
||||
|
||||
if (!l_keys.contains(argv[1])) {
|
||||
sendServerMessage("That permission doesn't exist!");
|
||||
const QString l_target_acl = argv[1];
|
||||
if (!server->getACLRolesHandler()->roleExists(l_target_acl)) {
|
||||
sendServerMessage("That role doesn't exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv[1] == "SUPER") {
|
||||
if (l_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!");
|
||||
if (l_target_acl == ACLRolesHandler::SUPER_ID && !checkPermission(ACLRole::SUPER)) {
|
||||
sendServerMessage("You aren't allowed to set that role!");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long long l_newperm = ACLFlags.value(argv[1]);
|
||||
if ((l_newperm & l_user_acl) != 0) {
|
||||
if (server->getDatabaseManager()->updateACL(argv[0], l_newperm, true))
|
||||
sendServerMessage("Successfully added permission " + argv[1] + " to user " + argv[0]);
|
||||
else
|
||||
sendServerMessage(argv[0] + " wasn't found!");
|
||||
const QString l_target_username = argv[0];
|
||||
if (l_target_username == "root") {
|
||||
sendServerMessage("You can't change root's role!");
|
||||
return;
|
||||
}
|
||||
|
||||
sendServerMessage("You aren't allowed to add that permission!");
|
||||
if (server->getDatabaseManager()->updateACL(l_target_username, l_target_acl)) {
|
||||
sendServerMessage("Successfully changed role " + l_target_acl + " to user " + l_target_username);
|
||||
}
|
||||
else {
|
||||
sendServerMessage(l_target_username + " wasn't found!");
|
||||
}
|
||||
}
|
||||
|
||||
void AOClient::cmdRemovePerms(int argc, QStringList argv)
|
||||
{
|
||||
Q_UNUSED(argc);
|
||||
|
||||
unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
|
||||
argv[1] = argv[1].toUpper();
|
||||
|
||||
const QStringList l_keys = ACLFlags.keys();
|
||||
|
||||
if (!l_keys.contains(argv[1])) {
|
||||
sendServerMessage("That permission doesn't exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv[0] == "root") {
|
||||
sendServerMessage("You cannot change the permissions of the root account!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv[1] == "SUPER") {
|
||||
if (l_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 l_newperm = ACLFlags.value(argv[1]);
|
||||
if ((l_newperm & l_user_acl) != 0) {
|
||||
if (server->getDatabaseManager()->updateACL(argv[0], l_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!");
|
||||
argv.append(ACLRolesHandler::NONE_ID);
|
||||
cmdSetPerms(argc, argv);
|
||||
}
|
||||
|
||||
void AOClient::cmdListUsers(int argc, QStringList argv)
|
||||
@ -269,6 +217,7 @@ void AOClient::cmdLogout(int argc, QStringList argv)
|
||||
return;
|
||||
}
|
||||
m_authenticated = false;
|
||||
m_acl_role_id = "";
|
||||
m_moderator_name = "";
|
||||
sendPacket("AUTH", {"-1"}); // Client: "You were logged out."
|
||||
}
|
||||
@ -284,8 +233,9 @@ void AOClient::cmdChangePassword(int argc, QStringList argv)
|
||||
}
|
||||
l_username = m_moderator_name;
|
||||
}
|
||||
else if (argc == 2 && checkAuth(ACLFlags.value("SUPER"))) {
|
||||
l_username = argv[1];
|
||||
else if (argc == 2 && checkPermission(ACLRole::SUPER)) {
|
||||
l_username = argv[0];
|
||||
l_password = argv[1];
|
||||
}
|
||||
else {
|
||||
sendServerMessage("Invalid command syntax.");
|
||||
|
@ -214,7 +214,7 @@ void AOClient::cmdSaveTestimony(int argc, QStringList argv)
|
||||
Q_UNUSED(argc);
|
||||
|
||||
bool l_permission_found = false;
|
||||
if (checkAuth(ACLFlags.value("SAVETEST")))
|
||||
if (checkPermission(ACLRole::SAVETEST))
|
||||
l_permission_found = true;
|
||||
|
||||
if (m_testimony_saving == true)
|
||||
|
@ -479,7 +479,7 @@ void AOClient::cmdCharSelect(int argc, QStringList argv)
|
||||
sendPacket("DONE");
|
||||
}
|
||||
else {
|
||||
if (!checkAuth(ACLFlags.value("FORCE_CHARSELECT"))) {
|
||||
if (!checkPermission(ACLRole::FORCE_CHARSELECT)) {
|
||||
sendServerMessage("You do not have permission to force another player to character select!");
|
||||
return;
|
||||
}
|
||||
|
@ -141,8 +141,10 @@ void AOClient::cmdMods(int argc, QStringList argv)
|
||||
for (AOClient *l_client : l_clients) {
|
||||
if (l_client->m_authenticated) {
|
||||
l_entries << "---";
|
||||
if (ConfigManager::authType() != DataTypes::AuthType::SIMPLE)
|
||||
if (ConfigManager::authType() != DataTypes::AuthType::SIMPLE) {
|
||||
l_entries << "Moderator: " + l_client->m_moderator_name;
|
||||
l_entries << "Role:" << l_client->m_acl_role_id;
|
||||
}
|
||||
l_entries << "OOC name: " + l_client->m_ooc_name;
|
||||
l_entries << "ID: " + QString::number(l_client->m_id);
|
||||
l_entries << "Area: " + QString::number(l_client->m_current_area);
|
||||
@ -165,7 +167,7 @@ void AOClient::cmdCommands(int argc, QStringList argv)
|
||||
QMap<QString, CommandInfo>::const_iterator i;
|
||||
for (i = commands.constBegin(); i != commands.constEnd(); ++i) {
|
||||
CommandInfo info = i.value();
|
||||
if (checkAuth(info.acl_mask)) { // if we are allowed to use this command
|
||||
if (checkPermission(info.acl_permission)) { // if we are allowed to use this command
|
||||
l_entries << "/" + i.key();
|
||||
}
|
||||
}
|
||||
@ -193,7 +195,7 @@ void AOClient::cmdMOTD(int argc, QStringList argv)
|
||||
sendServerMessage("=== MOTD ===\r\n" + ConfigManager::motd() + "\r\n=============");
|
||||
}
|
||||
else if (argc > 0) {
|
||||
if (checkAuth(ACLFlags.value("MOTD"))) {
|
||||
if (checkPermission(ACLRole::MOTD)) {
|
||||
QString l_MOTD = argv.join(" ");
|
||||
ConfigManager::setMotd(l_MOTD);
|
||||
sendServerMessage("MOTD has been changed.");
|
||||
|
@ -127,7 +127,7 @@ void AOClient::cmdToggleJukebox(int argc, QStringList argv)
|
||||
Q_UNUSED(argc);
|
||||
Q_UNUSED(argv);
|
||||
|
||||
if (checkAuth(ACLFlags.value("CM")) | checkAuth(ACLFlags.value("Jukebox"))) {
|
||||
if (checkPermission(ACLRole::CM) | checkPermission(ACLRole::JUKEBOX)) {
|
||||
AreaData *l_area = server->getAreaById(m_current_area);
|
||||
l_area->toggleJukebox();
|
||||
QString l_state = l_area->isjukeboxEnabled() ? "enabled." : "disabled.";
|
||||
|
@ -84,7 +84,7 @@ void AOClient::cmdTimer(int argc, QStringList argv)
|
||||
// Check against permissions if global timer is selected
|
||||
QTimer *l_requested_timer;
|
||||
if (l_timer_id == 0) {
|
||||
if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) {
|
||||
if (!checkPermission(ACLRole::GLOBAL_TIMER)) {
|
||||
sendServerMessage("You are not authorized to alter the global timer.");
|
||||
return;
|
||||
}
|
||||
|
@ -171,11 +171,11 @@ bool DBManager::invalidateBan(int id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DBManager::createUser(QString username, QString salt, QString password, unsigned long long acl)
|
||||
bool DBManager::createUser(QString f_username, QString f_salt, QString f_password, QString f_acl)
|
||||
{
|
||||
QSqlQuery username_exists;
|
||||
username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?");
|
||||
username_exists.addBindValue(username);
|
||||
username_exists.addBindValue(f_username);
|
||||
username_exists.exec();
|
||||
|
||||
if (username_exists.first())
|
||||
@ -185,15 +185,15 @@ bool DBManager::createUser(QString username, QString salt, QString password, uns
|
||||
|
||||
QString salted_password;
|
||||
QMessageAuthenticationCode hmac(QCryptographicHash::Sha256);
|
||||
hmac.setKey(salt.toUtf8());
|
||||
hmac.addData(password.toUtf8());
|
||||
hmac.setKey(f_salt.toUtf8());
|
||||
hmac.addData(f_password.toUtf8());
|
||||
salted_password = hmac.result().toHex();
|
||||
|
||||
query.prepare("INSERT INTO users(USERNAME, SALT, PASSWORD, ACL) VALUES(?, ?, ?, ?)");
|
||||
query.addBindValue(username);
|
||||
query.addBindValue(salt);
|
||||
query.addBindValue(f_username);
|
||||
query.addBindValue(f_salt);
|
||||
query.addBindValue(salted_password);
|
||||
query.addBindValue(acl);
|
||||
query.addBindValue(f_acl);
|
||||
query.exec();
|
||||
|
||||
return true;
|
||||
@ -226,7 +226,7 @@ bool DBManager::deleteUser(QString username)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long DBManager::getACL(QString moderator_name)
|
||||
QString DBManager::getACL(QString moderator_name)
|
||||
{
|
||||
if (moderator_name == "")
|
||||
return 0;
|
||||
@ -235,7 +235,7 @@ unsigned long long DBManager::getACL(QString moderator_name)
|
||||
query.exec();
|
||||
if (!query.first())
|
||||
return 0;
|
||||
return query.value(0).toULongLong();
|
||||
return query.value(0).toString();
|
||||
}
|
||||
|
||||
bool DBManager::authenticate(QString username, QString password)
|
||||
@ -263,30 +263,21 @@ bool DBManager::authenticate(QString username, QString password)
|
||||
return salted_password == stored_pass;
|
||||
}
|
||||
|
||||
bool DBManager::updateACL(QString username, unsigned long long acl, bool mode)
|
||||
bool DBManager::updateACL(QString f_username, QString f_acl)
|
||||
{
|
||||
QSqlQuery username_exists;
|
||||
username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?");
|
||||
username_exists.addBindValue(username);
|
||||
username_exists.exec();
|
||||
QSqlQuery l_username_exists;
|
||||
l_username_exists.prepare("SELECT ACL FROM users WHERE USERNAME = ?");
|
||||
l_username_exists.addBindValue(f_username);
|
||||
l_username_exists.exec();
|
||||
|
||||
if (!username_exists.first())
|
||||
if (!l_username_exists.first())
|
||||
return false;
|
||||
|
||||
unsigned long long old_acl = username_exists.value(0).toULongLong();
|
||||
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;
|
||||
|
||||
QSqlQuery update_acl;
|
||||
update_acl.prepare("UPDATE users SET ACL = ? WHERE USERNAME = ?");
|
||||
update_acl.addBindValue(new_acl);
|
||||
update_acl.addBindValue(username);
|
||||
update_acl.exec();
|
||||
QSqlQuery l_update_acl;
|
||||
l_update_acl.prepare("UPDATE users SET ACL = ? WHERE USERNAME = ?");
|
||||
l_update_acl.addBindValue(f_acl);
|
||||
l_update_acl.addBindValue(f_username);
|
||||
l_update_acl.exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ void AOClient::pktChangeMusic(AreaData *area, int argc, QStringList argv, AOPack
|
||||
sendServerMessage("You are blocked from changing the music.");
|
||||
return;
|
||||
}
|
||||
if (!area->isMusicAllowed() && !checkAuth(ACLFlags.value("CM"))) {
|
||||
if (!area->isMusicAllowed() && !checkPermission(ACLRole::CM)) {
|
||||
sendServerMessage("Music is disabled in this area.");
|
||||
return;
|
||||
}
|
||||
@ -613,7 +613,7 @@ void AOClient::updateEvidenceList(AreaData *area)
|
||||
|
||||
const QList<AreaData::Evidence> l_area_evidence = area->evidence();
|
||||
for (const AreaData::Evidence &evidence : l_area_evidence) {
|
||||
if (!checkAuth(ACLFlags.value("CM")) && area->eviMod() == AreaData::EvidenceMod::HIDDEN_CM) {
|
||||
if (!checkPermission(ACLRole::CM) && area->eviMod() == AreaData::EvidenceMod::HIDDEN_CM) {
|
||||
QRegularExpression l_regex("<owner=(.*?)>");
|
||||
QRegularExpressionMatch l_match = l_regex.match(evidence.description);
|
||||
if (l_match.hasMatch()) {
|
||||
@ -648,7 +648,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
|
||||
// Spectators cannot use IC
|
||||
return l_invalid;
|
||||
AreaData *area = server->getAreaById(m_current_area);
|
||||
if (area->lockStatus() == AreaData::LockStatus::SPECTATABLE && !area->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS")))
|
||||
if (area->lockStatus() == AreaData::LockStatus::SPECTATABLE && !area->invited().contains(m_id) && !checkPermission(ACLRole::BYPASS_LOCKS))
|
||||
// Non-invited players cannot speak in spectatable areas
|
||||
return l_invalid;
|
||||
|
||||
@ -1007,7 +1007,7 @@ bool AOClient::checkEvidenceAccess(AreaData *area)
|
||||
return true;
|
||||
case AreaData::EvidenceMod::CM:
|
||||
case AreaData::EvidenceMod::HIDDEN_CM:
|
||||
return checkAuth(ACLFlags.value("CM"));
|
||||
return checkPermission(ACLRole::CM);
|
||||
case AreaData::EvidenceMod::MOD:
|
||||
return m_authenticated;
|
||||
default:
|
||||
@ -1043,6 +1043,7 @@ void AOClient::loginAttempt(QString message)
|
||||
sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button."
|
||||
sendServerMessage("Logged in as a moderator."); // pre-2.9.1 clients are hardcoded to display the mod UI when this string is sent in OOC
|
||||
m_authenticated = true;
|
||||
m_acl_role_id = ACLRolesHandler::SUPER_ID;
|
||||
}
|
||||
else {
|
||||
sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful."
|
||||
@ -1062,8 +1063,9 @@ void AOClient::loginAttempt(QString message)
|
||||
QString username = l_login[0];
|
||||
QString password = l_login[1];
|
||||
if (server->getDatabaseManager()->authenticate(username, password)) {
|
||||
m_moderator_name = username;
|
||||
m_authenticated = true;
|
||||
m_acl_role_id = server->getDatabaseManager()->getACL(username);
|
||||
m_moderator_name = username;
|
||||
sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button."
|
||||
if (m_version.release <= 2 && m_version.major <= 9 && m_version.minor <= 0)
|
||||
sendServerMessage("Logged in as a moderator."); // pre-2.9.1 clients are hardcoded to display the mod UI when this string is sent in OOC
|
||||
|
@ -17,6 +17,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "include/server.h"
|
||||
|
||||
#include "include/acl_roles_handler.h"
|
||||
#include "include/advertiser.h"
|
||||
#include "include/aoclient.h"
|
||||
#include "include/aopacket.h"
|
||||
@ -42,7 +43,10 @@ Server::Server(int p_port, int p_ws_port, QObject *parent) :
|
||||
proxy->start();
|
||||
timer = new QTimer(this);
|
||||
|
||||
db_manager = new DBManager();
|
||||
db_manager = new DBManager;
|
||||
|
||||
acl_roles_handler = new ACLRolesHandler;
|
||||
acl_roles_handler->loadFile("config/acl_roles.ini");
|
||||
|
||||
// We create it, even if its not used later on.
|
||||
discord = new Discord(this);
|
||||
@ -304,7 +308,7 @@ void Server::broadcast(AOPacket packet, TARGET_TYPE target)
|
||||
for (AOClient *l_client : qAsConst(m_clients)) {
|
||||
switch (target) {
|
||||
case TARGET_TYPE::MODCHAT:
|
||||
if (l_client->checkAuth(l_client->ACLFlags.value("MODCHAT"))) {
|
||||
if (l_client->checkPermission(ACLRole::MODCHAT)) {
|
||||
l_client->sendPacket(packet);
|
||||
}
|
||||
break;
|
||||
@ -324,7 +328,7 @@ void Server::broadcast(AOPacket packet, AOPacket other_packet, TARGET_TYPE targe
|
||||
switch (target) {
|
||||
case TARGET_TYPE::AUTHENTICATED:
|
||||
for (AOClient *l_client : qAsConst(m_clients)) {
|
||||
if (l_client->m_authenticated) {
|
||||
if (l_client->isAuthenticated()) {
|
||||
l_client->sendPacket(other_packet);
|
||||
}
|
||||
else {
|
||||
@ -454,6 +458,11 @@ DBManager *Server::getDatabaseManager()
|
||||
return db_manager;
|
||||
}
|
||||
|
||||
ACLRolesHandler *Server::getACLRolesHandler()
|
||||
{
|
||||
return acl_roles_handler;
|
||||
}
|
||||
|
||||
void Server::allowMessage()
|
||||
{
|
||||
m_can_send_ic_messages = true;
|
||||
@ -529,6 +538,7 @@ Server::~Server()
|
||||
server->deleteLater();
|
||||
proxy->deleteLater();
|
||||
discord->deleteLater();
|
||||
acl_roles_handler->deleteLater();
|
||||
|
||||
delete db_manager;
|
||||
}
|
||||
|
@ -2,4 +2,5 @@ TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
unittest_area \
|
||||
unittest_music_manager
|
||||
unittest_music_manager \
|
||||
unittest_acl_roles_handler
|
||||
|
@ -0,0 +1,193 @@
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QTest>
|
||||
|
||||
#include <include/acl_roles_handler.h>
|
||||
|
||||
namespace tests {
|
||||
namespace unittests {
|
||||
|
||||
/**
|
||||
* @brief Unit Tester class for ACL roles-related functions.
|
||||
*/
|
||||
class tst_ACLRolesHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ACLRolesHandler *m_handler;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Initialises every tests with creating a new ACLRolesHandler.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* @brief Tests the general state of read-only roles.
|
||||
*/
|
||||
void checkReadOnlyRoles();
|
||||
|
||||
/**
|
||||
* @brief Tests removal of read-only roles.
|
||||
*/
|
||||
void removeReadOnlyRoles();
|
||||
|
||||
/**
|
||||
* @brief Tests general modifications of read-only roles.
|
||||
*/
|
||||
void replaceReadOnlyRoles();
|
||||
|
||||
/**
|
||||
* @brief Tests general modifications of roles.
|
||||
*/
|
||||
void modifyRoles();
|
||||
|
||||
/**
|
||||
* @brief Tests clearance of roles.
|
||||
*/
|
||||
void clearAllRoles();
|
||||
};
|
||||
|
||||
void tst_ACLRolesHandler::init()
|
||||
{
|
||||
m_handler = new ACLRolesHandler;
|
||||
}
|
||||
|
||||
void tst_ACLRolesHandler::checkReadOnlyRoles()
|
||||
{
|
||||
{
|
||||
const QString l_role_name = ACLRolesHandler::NONE_ID;
|
||||
|
||||
// Checks if the role exists
|
||||
QCOMPARE(m_handler->roleExists(ACLRolesHandler::NONE_ID), true);
|
||||
|
||||
ACLRole l_role = m_handler->getRoleById(ACLRolesHandler::NONE_ID);
|
||||
// Checks every permissions
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::NONE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::KICK), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BAN), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BGLOCK), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MODIFY_USERS), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::CM), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::GLOBAL_TIMER), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::EVI_MOD), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MOTD), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::ANNOUNCE), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MODCHAT), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MUTE), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::UNCM), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SAVETEST), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::FORCE_CHARSELECT), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BYPASS_LOCKS), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::IGNORE_BGLIST), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SEND_NOTICE), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::JUKEBOX), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SUPER), false);
|
||||
}
|
||||
|
||||
{
|
||||
const QString l_role_name = ACLRolesHandler::SUPER_ID;
|
||||
|
||||
// Checks if the role exists
|
||||
QCOMPARE(m_handler->roleExists(l_role_name), true);
|
||||
|
||||
ACLRole l_role = m_handler->getRoleById(l_role_name);
|
||||
// Checks every permissions
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::NONE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::KICK), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BAN), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BGLOCK), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MODIFY_USERS), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::CM), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::GLOBAL_TIMER), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::EVI_MOD), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MOTD), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::ANNOUNCE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MODCHAT), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MUTE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::UNCM), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SAVETEST), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::FORCE_CHARSELECT), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::BYPASS_LOCKS), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::IGNORE_BGLIST), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SEND_NOTICE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::JUKEBOX), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SUPER), true);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_ACLRolesHandler::removeReadOnlyRoles()
|
||||
{
|
||||
{ // SUPER role
|
||||
// Removes the role. This should fail.
|
||||
QCOMPARE(m_handler->removeRole(ACLRolesHandler::SUPER_ID), false);
|
||||
|
||||
// Checks if the role exists.
|
||||
QCOMPARE(m_handler->roleExists(ACLRolesHandler::SUPER_ID), true);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_ACLRolesHandler::replaceReadOnlyRoles()
|
||||
{
|
||||
{
|
||||
// Attempts to overwrite a read-only role. This should fail.
|
||||
QCOMPARE(m_handler->insertRole(ACLRolesHandler::NONE_ID, ACLRole(ACLRole::NONE)), false);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_ACLRolesHandler::modifyRoles()
|
||||
{
|
||||
{
|
||||
const QString l_role_id = "new_role";
|
||||
|
||||
// Checks if a the role exists. This should fail.
|
||||
QCOMPARE(m_handler->roleExists(l_role_id), false);
|
||||
|
||||
// Inserts a role.
|
||||
QCOMPARE(m_handler->insertRole(l_role_id, ACLRole(ACLRole::KICK)), true);
|
||||
|
||||
// Inserts a role again.
|
||||
QCOMPARE(m_handler->insertRole(l_role_id, ACLRole(ACLRole::MODIFY_USERS)), true);
|
||||
|
||||
// Checks if the role exists.
|
||||
QCOMPARE(m_handler->roleExists(l_role_id), true);
|
||||
|
||||
const ACLRole l_role = m_handler->getRoleById(l_role_id);
|
||||
// Checks every permissions
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::NONE), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::KICK), false);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::MODIFY_USERS), true);
|
||||
QCOMPARE(l_role.checkPermission(ACLRole::SUPER), false);
|
||||
|
||||
// Removes the role.
|
||||
QCOMPARE(m_handler->removeRole(l_role_id), true);
|
||||
|
||||
// Removes the role again. This should fail.
|
||||
QCOMPARE(m_handler->removeRole(l_role_id), false);
|
||||
|
||||
// Checks if the role exists. This should fail.
|
||||
QCOMPARE(m_handler->roleExists(l_role_id), false);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_ACLRolesHandler::clearAllRoles()
|
||||
{
|
||||
{
|
||||
const QString l_role_id = "new_role";
|
||||
|
||||
// Inserts a role.
|
||||
QCOMPARE(m_handler->insertRole(l_role_id, ACLRole(ACLRole::KICK)), true);
|
||||
|
||||
m_handler->clearRoles();
|
||||
// Checks if a the role exists. This should fail.
|
||||
QCOMPARE(m_handler->roleExists(l_role_id), false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tests::unittests::tst_ACLRolesHandler)
|
||||
|
||||
#include "tst_unittest_acl_roles_handler.moc"
|
@ -0,0 +1,5 @@
|
||||
QT -= gui
|
||||
|
||||
include(../tests_common.pri)
|
||||
|
||||
SOURCES += tst_unittest_acl_roles_handler.cpp
|
Loading…
Reference in New Issue
Block a user