diff options
author | Philipp Sehmisch <mana@crushnet.org> | 2010-01-17 01:28:42 +0100 |
---|---|---|
committer | Philipp Sehmisch <mana@crushnet.org> | 2010-01-17 01:28:59 +0100 |
commit | c9c199007fb6b77f8cd13ffdb560cd18ff3c5af4 (patch) | |
tree | a6e4b3d0ab1ae7f26e3e0847ebc53b44c59a7efd /src | |
parent | 8bf0791932c8809fe5bd85d53859b8ce6197e4ed (diff) | |
download | manaserv-c9c199007fb6b77f8cd13ffdb560cd18ff3c5af4.tar.gz manaserv-c9c199007fb6b77f8cd13ffdb560cd18ff3c5af4.tar.bz2 manaserv-c9c199007fb6b77f8cd13ffdb560cd18ff3c5af4.tar.xz manaserv-c9c199007fb6b77f8cd13ffdb560cd18ff3c5af4.zip |
Added permission manager. Currently only used for @commands and doesn't support <deny> and <alias> yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/common/permissionmanager.cpp | 147 | ||||
-rw-r--r-- | src/common/permissionmanager.hpp | 54 | ||||
-rw-r--r-- | src/game-server/commandhandler.cpp | 141 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 3 |
4 files changed, 255 insertions, 90 deletions
diff --git a/src/common/permissionmanager.cpp b/src/common/permissionmanager.cpp new file mode 100644 index 00000000..1e97e02e --- /dev/null +++ b/src/common/permissionmanager.cpp @@ -0,0 +1,147 @@ +/* + * The Mana Server + * Copyright (C) 2010 The Mana World Development Team + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "common/permissionmanager.hpp" + +#include "game-server/character.hpp" +#include "game-server/resourcemanager.hpp" +#include "utils/logger.h" +#include "utils/xml.hpp" + + +static std::map<std::string, unsigned char> permissions; +static std::string permissionFile; + +void addPermission(std::string permission, char mask) +{ + + std::map<std::string, unsigned char>::iterator i = permissions.find(permission); + if (i == permissions.end()) + { + permissions.insert(std::make_pair<std::string, unsigned char>(permission, mask)); + } else { + i->second |= mask; + } +} + +void PermissionManager::initialize(const std::string & file) +{ + permissionFile = file; + reload(); +} + +void PermissionManager::reload() +{ + int size; + char *data = ResourceManager::loadFile(permissionFile, size); + + if (!data) { + LOG_ERROR("Permission Manager: Could not find " + << permissionFile << "!"); + free(data); + return; + } + + xmlDocPtr doc = xmlParseMemory(data, size); + free(data); + + if (!doc) + { + LOG_ERROR("Permission Manager: Error while parsing permission database (" + << permissionFile << ")!"); + return; + } + + xmlNodePtr node = xmlDocGetRootElement(doc); + if (!node || !xmlStrEqual(node->name, BAD_CAST "permissions")) + { + LOG_ERROR("Permission Manager: " << permissionFile + << " is not a valid database file!"); + xmlFreeDoc(doc); + return; + } + + LOG_INFO("Loading permission reference..."); + for (node = node->xmlChildrenNode; node != NULL; node = node->next) + { + unsigned char classmask = 0x01; + if (!xmlStrEqual(node->name, BAD_CAST "class")) + { + continue; + } + int level = XML::getProperty(node, "level", 0); + if (level < 1 || level > 8) + { + LOG_WARN("PermissionManager: Illegal class level " + <<level + <<" in " + <<permissionFile + <<" (allowed range: 1..8)"); + continue; + } + classmask = classmask << (level-1); + + + xmlNodePtr perNode; + for (perNode = node->xmlChildrenNode; perNode != NULL; perNode = perNode->next) + { + if (xmlStrEqual(perNode->name, BAD_CAST "allow")) + { + const char* permission = (const char*)perNode->xmlChildrenNode->content; + if (permission && strlen(permission) > 0) + { + addPermission(permission, classmask); + } + } else if (xmlStrEqual(perNode->name, BAD_CAST "deny")){ + const char* permission = (const char*)perNode->xmlChildrenNode->content; + // To be implemented + } else if (xmlStrEqual(perNode->name, BAD_CAST "alias")){ + const char* alias = (const char*)perNode->xmlChildrenNode->content; + // To be implemented + } + } + } + + LOG_INFO("Permission List:"); + for (std::map<std::string, unsigned char>::iterator i = permissions.begin(); + i != permissions.end(); + i++) + { + LOG_INFO(i->first<<" "<<(int)i->second); + } +} + + +PermissionManager::Result PermissionManager::checkPermission(const Character* character, std::string permission) +{ + std::map<std::string, unsigned char>::iterator iP = permissions.find(permission); + + if (iP == permissions.end()) + { + LOG_WARN("PermissionManager: Check for unknown permission \""<<permission<<"\" requested."); + return PMR_UNKNOWN; + } + if (character->getAccountLevel() & iP->second) + { + return PMR_ALLOWED; + } else { + return PMR_DENIED; + } +} diff --git a/src/common/permissionmanager.hpp b/src/common/permissionmanager.hpp new file mode 100644 index 00000000..4989d0ac --- /dev/null +++ b/src/common/permissionmanager.hpp @@ -0,0 +1,54 @@ +/* + * The Mana Server + * Copyright (C) 2010 The Mana World Development Team + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PERMISSIONMANAGER_HPP +#define PERMISSIONMANAGER_HPP + +#include <map> +#include <string> + +class Character; + +namespace PermissionManager +{ + enum Result + { + PMR_UNKNOWN, + PMR_DENIED, + PMR_ALLOWED + }; + /** + * Loads permission file. + */ + void initialize(const std::string &); + + /** + * Reloads permission file. + */ + void reload(); + + /** + * Returns if the characters account has the given permission + */ + Result checkPermission(const Character* character, std::string permission); + +} + +#endif diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 60f0905c..0dccd086 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -32,6 +32,7 @@ #include "game-server/monstermanager.hpp" #include "game-server/state.hpp" +#include "common/permissionmanager.hpp" #include "common/transaction.hpp" #include "utils/string.hpp" @@ -41,6 +42,7 @@ static void say(const std::string error, Character *player) GameState::sayTo(player, NULL, error); } +/* static bool checkPermission(Character *player, unsigned int permissions) { if (player->getAccountLevel() & permissions) @@ -51,7 +53,7 @@ static bool checkPermission(Character *player, unsigned int permissions) say("Invalid permissions", player); return false; -} +}*/ static std::string getArgument(std::string &args) { @@ -792,94 +794,53 @@ void CommandHandler::handleCommand(Character *player, std::string type(command, 1, pos == std::string::npos ? pos : pos - 1); std::string args(command, pos == std::string::npos ? command.size() : pos + 1); - // handle the command - if (type == "help") - { - if (checkPermission(player, AL_PLAYER)) - handleHelp(player, args); - } - else if (type == "where" || type == "location") - { - if (checkPermission(player, AL_PLAYER)) - handleWhere(player); - } - else if (type == "rights" || type == "right" || type == "permission") - { - if (checkPermission(player, AL_PLAYER)) - handleRights(player); - } - else if (type == "warp") - { - if (checkPermission(player, AL_TESTER)) - handleWarp(player, args); - } - else if (type == "item") - { - if (checkPermission(player, AL_DEV)) - handleItem(player, args); - } - else if (type == "drop") - { - if (checkPermission(player, AL_DEV)) - handleDrop(player, args); - } - else if (type == "money") - { - if (checkPermission(player, AL_DEV)) - handleMoney(player, args); - } - else if (type == "spawn") - { - if (checkPermission(player, AL_DEV)) - handleSpawn(player, args); - } - else if (type == "goto") - { - if (checkPermission(player, AL_TESTER)) - handleGoto(player, args); - } - else if (type == "recall") - { - if (checkPermission(player, AL_GM)) - handleRecall(player, args); - } - else if (type == "reload") - { - if (checkPermission(player, AL_ADMIN)) - handleReload(player); - } - else if (type == "ban") - { - if (checkPermission(player, AL_GM)) - handleBan(player, args); - } - else if (type == "setgroup") - { - if (checkPermission(player, AL_ADMIN)) - handleSetGroup(player, args); - } - else if (type == "attribute") - { - if (checkPermission(player, AL_DEV)) - handleAttribute(player, args); - } - else if (type == "report") - { - if (checkPermission(player, AL_PLAYER)) - handleReport(player, args); - } - else if (type == "announce") - { - if (checkPermission(player, AL_ADMIN)) - handleAnnounce(player, args); - } - else if (type == "history") - { - if (checkPermission(player, AL_ADMIN)) - handleHistory(player, args); - } - else - { - say("Command not found. Enter @help to view the list of available commands.", player); + PermissionManager::Result r = PermissionManager::checkPermission(player, "@"+type); + switch (r) + { + case PermissionManager::PMR_DENIED: + say("Permissions denied!", player); + break; + case PermissionManager::PMR_UNKNOWN: + say("Unknown command. Enter @help to view the list of available commands.", player); + break; + case PermissionManager::PMR_ALLOWED: + // handle the command + if (type == "help") handleHelp(player, args); + else if (type == "where" || type == "location") + handleWhere(player); + else if (type == "rights" || type == "right" || type == "permission") + handleRights(player); + else if (type == "warp") + handleWarp(player, args); + else if (type == "item") + handleItem(player, args); + else if (type == "drop") + handleDrop(player, args); + else if (type == "money") + handleMoney(player, args); + else if (type == "spawn") + handleSpawn(player, args); + else if (type == "goto") + handleGoto(player, args); + else if (type == "recall") + handleRecall(player, args); + else if (type == "reload") + handleReload(player); + else if (type == "ban") + handleBan(player, args); + else if (type == "setgroup") + handleSetGroup(player, args); + else if (type == "attribute") + handleAttribute(player, args); + else if (type == "report") + handleReport(player, args); + else if (type == "announce") + handleAnnounce(player, args); + else if (type == "history") + handleHistory(player, args); + else + say("Command not implemented.", player); + + break; } } diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index a35c9531..b49f46de 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -36,6 +36,7 @@ #endif #include "common/configuration.hpp" +#include "common/permissionmanager.hpp" #include "game-server/accountconnection.hpp" #include "game-server/gamehandler.hpp" #include "game-server/skillmanager.hpp" @@ -65,6 +66,7 @@ using utils::Logger; #define DEFAULT_MAPSDB_FILE "maps.xml" #define DEFAULT_MONSTERSDB_FILE "monsters.xml" #define DEFAULT_STATUSDB_FILE "mana-status-effect.xml" +#define DEFAULT_PERMISSION_FILE "permissions.xml" static int const WORLD_TICK_SKIP = 2; /** tolerance for lagging behind in world calculation) **/ @@ -169,6 +171,7 @@ void initialize() ItemManager::initialize(DEFAULT_ITEMSDB_FILE); MonsterManager::initialize(DEFAULT_MONSTERSDB_FILE); StatusManager::initialize(DEFAULT_STATUSDB_FILE); + PermissionManager::initialize(DEFAULT_PERMISSION_FILE); // --- Initialize the global handlers // FIXME: Make the global handlers global vars or part of a bigger |