Files
TCPlayerbotCore/src/server/game/Accounts/RBAC.h
T

420 lines
16 KiB
C++

/*
* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
*
* This program 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 (at your
* option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file RBAC.h
* @brief Role Based Access Control related classes definition
*
* This file contains all the classes and enums used to implement
* Role Based Access Control
*
* RBAC Rules:
* - Pemission: Defines an autorization to perform certain operation.
* - Role: Set of permissions.
* - Group: Set of roles.
* - An Account can have multiple groups, roles and permissions.
* - Account Groups can only be granted or revoked
* - Account Roles and Permissions can be granted, denied or revoked
* - Grant: Assignment of the object (role/permission) and allow it
* - Deny: Assignment of the object (role/permission) and deny it
* - Revoke: Removal of the object (role/permission) no matter if it was granted or denied
* - Global Permissions are computed as:
* Group Grants + Role Grants + User Grans - Role Grants - User Grants
* - Groups, Roles and Permissions can be assigned by realm
*/
#ifndef _RBAC_H
#define _RBAC_H
#include "Define.h"
#include <string>
#include <bitset>
#include <set>
#include <map>
enum RBACPermissions
{
RBAC_PERM_INSTANT_LOGOUT = 1,
RBAC_PERM_SKIP_QUEUE = 2,
RBAC_PERM_JOIN_NORMAL_BG = 3,
RBAC_PERM_JOIN_RANDOM_BG = 4,
RBAC_PERM_JOIN_ARENAS = 5,
RBAC_PERM_JOIN_DUNGEON_FINDER = 6,
RBAC_PERM_PLAYER_COMMANDS = 7,
RBAC_PERM_MODERATOR_COMMANDS = 8,
RBAC_PERM_GAMEMASTER_COMMANDS = 9,
RBAC_PERM_ADMINISTRATOR_COMMANDS = 10,
RBAC_PERM_LOG_GM_TRADE = 11,
RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13,
RBAC_PERM_COMMANDS_SAVE_WITHOUT_DELAY = 30,
RBAC_PERM_COMMANDS_USE_UNSTUCK_WITH_ARGS = 31,
RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET = 32,
RBAC_PERM_COMMANDS_APPEAR_IN_GM_LIST = 34,
RBAC_PERM_CHAT_USE_STAFF_BADGE = 37,
RBAC_PERM_RESURRECT_WITH_FULL_HPS = 38,
RBAC_PERM_RECEIVE_GLOBAL_GM_TEXTMESSAGE = 44,
RBAC_PERM_MAX
};
enum RBACCommandResult
{
RBAC_OK,
RBAC_CANT_ADD_ALREADY_ADDED,
RBAC_CANT_REVOKE_NOT_IN_LIST,
RBAC_IN_GRANTED_LIST,
RBAC_IN_DENIED_LIST,
RBAC_ID_DOES_NOT_EXISTS
};
typedef std::bitset<RBAC_PERM_MAX> RBACPermissionContainer;
typedef std::set<uint32> RBACRoleContainer;
typedef std::set<uint32> RBACGroupContainer;
class RBACObject
{
public:
RBACObject(uint32 id = 0, std::string const& name = ""):
_id(id), _name(name) { }
/// Gets the Name of the Object
std::string const& GetName() const { return _name; }
/// Gets the Id of the Object
uint32 GetId() const { return _id; }
private:
uint32 _id; ///> id of the object
std::string _name; ///> name of the object
};
/// Permission: Defines an autorization to perform certain operation
class RBACPermission: public RBACObject
{
public:
RBACPermission(uint32 id = 0, std::string const& name = ""):
RBACObject(id, name) { }
};
/// Set of Permissions
class RBACRole: public RBACObject
{
public:
RBACRole(uint32 id = 0, std::string const& name = ""):
RBACObject(id, name) { }
/// Gets the Permissions assigned to this role
RBACPermissionContainer const& GetPermissions() const { return _perms; }
/// Grants a Permission (Adds)
void GrantPermission(uint32 id) { _perms.set(id); }
/// Revokes a Permission (Removes)
void RevokePermission(uint32 id) { _perms.reset(id); }
private:
RBACPermissionContainer _perms; ///> Set of permissions
};
/// Set of Roles
class RBACGroup: public RBACObject
{
public:
RBACGroup(uint32 id = 0, std::string const& name = ""):
RBACObject(id, name) { }
/// Gets the Roles assigned to this group
RBACRoleContainer const& GetRoles() const { return _roles; }
/// Grants a Role (Adds)
void GrantRole(uint32 role) { _roles.insert(role); }
/// Revokes a Role (Removes)
void RevokeRole(uint32 role) { _roles.erase(role); }
private:
RBACRoleContainer _roles; ///> Set of Roles
};
/**
* @name RBACData
* @brief Contains all needed information about the acccount
*
* This class contains all the data needed to calculate the account permissions.
* RBACDAta is formed by group permissions and user permissions through:
* - Granted Groups, which contains roles, which contains permissions: Set of granted permissions
* - Granted Roles, which contains permissions: Set of granted permissions
* - Denied Roles, which contains permissions: Set of denied permissions
* - Granted Permissions
* - Denied Permissions
*
* Calculation of current Permissions: Granted permissions - Denied permissions
* - Granted permissions: through groups, through roles and directly assigned
* - Denied permissions: through roles and directly assigned
*/
class RBACData: public RBACObject
{
public:
RBACData(uint32 id, std::string const& name, int32 realmId):
RBACObject(id, name), _realmId(realmId) { }
/**
* @name HasPermission
* @brief Checks if certain action is allowed
*
* Checks if certain action can be performed.
*
* @return grant or deny action
*
* Example Usage:
* @code
* bool Player::CanJoinArena(Battleground* bg)
* {
* return bg->isArena() && HasPermission(RBAC_PERM_JOIN_ARENA);
* }
* @endcode
*/
bool HasPermission(uint32 permission) { return _globalPerms.test(permission); }
// Functions enabled to be used by command system
/// Returns all the granted permissions (after computation)
RBACPermissionContainer const& GetPermissions() const { return _globalPerms; }
/// Returns all the granted permissions
RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; }
/// Returns all the denied permissions
RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; }
/// Returns all the granted roles
RBACRoleContainer const& GetGrantedRoles() const { return _grantedRoles; }
/// Returns all the denied roles
RBACRoleContainer const& GetDeniedRoles() const { return _deniedRoles; }
/// Returns all the granted groups
RBACGroupContainer const& GetGroups() const { return _groups; }
/**
* @name AddGroup
* @brief Adds new group
*
* Add a new group to the account. If realm is 0 or the group can not be added
* No save to db action will be performed.
*
* Fails if group Id does not exists or group already present
*
* @param groupId group to be added
* @param realmId realm affected
*
* @return Success or failure (with reason) to add the group
*
* Example Usage:
* @code
* // previously defined "RBACData* rbac" with proper initialization
* uint32 groupId = 2;
* if (rbac->AddGroup(groupId) == RBAC_OK)
* sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully added", groupId);
* @endcode
*/
RBACCommandResult AddGroup(uint32 groupId, int32 realmId = 0);
/**
* @name RemoveGroup
* @brief Removes a group
*
* Removes a group from the account. If realm is 0 or the group can not be removed
* No save to db action will be performed. Any delete operation will always affect
* "all realms (-1)" in addition to the realm specified
*
* Fails if group not present
*
* @param groupId group to be removed
* @param realmId realm affected
*
* @return Success or failure (with reason) to remove the group
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 groupId = 2;
* if (rbac->RemoveGroup(groupId) == RBAC_OK)
* sLog->outDebug(LOG_FILTER_PLAYER, "Group %u succesfully removed", groupId);
* @endcode
*/
RBACCommandResult RemoveGroup(uint32 groupId, int32 realmId = 0);
/**
* @name GrantRole
* @brief Grants a role
*
* Grants a role to the account. If realm is 0 or the role can not be added
* No save to db action will be performed.
*
* Fails if role Id does not exists or role already granted or denied
*
* @param roleId role to be granted
* @param realmId realm affected
*
* @return Success or failure (with reason) to grant the role
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 roleId = 2;
* if (rbac->GrantRole(roleId) == RBAC_IN_DENIED_LIST)
* sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant role %u, already denied", roleId);
* @endcode
*/
RBACCommandResult GrantRole(uint32 roleId, int32 realmId = 0);
/**
* @name DenyRole
* @brief Denies a role
*
* Denied a role to the account. If realm is 0 or the role can not be added
* No save to db action will be performed.
*
* Fails if role Id does not exists or role already granted or denied
*
* @param roleId role to be denied
* @param realmId realm affected
*
* @return Success or failure (with reason) to deny the role
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 roleId = 2;
* if (rbac->DenyRole(roleId) == RBAC_ID_DOES_NOT_EXISTS)
* sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", roleId);
* @endcode
*/
RBACCommandResult DenyRole(uint32 roleId, int32 realmId = 0);
/**
* @name RevokeRole
* @brief Removes a role
*
* Removes a role from the account. If realm is 0 or the role can not be removed
* No save to db action will be performed. Any delete operation will always affect
* "all realms (-1)" in addition to the realm specified
*
* Fails if role not present
*
* @param roleId role to be removed
* @param realmId realm affected
*
* @return Success or failure (with reason) to remove the role
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 roleId = 2;
* if (rbac->RevokeRole(roleId) == RBAC_OK)
* sLog->outDebug(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId);
* @endcode
*/
RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0);
/**
* @name GrantRole
* @brief Grants a permission
*
* Grants a permission to the account. If realm is 0 or the permission can not be added
* No save to db action will be performed.
*
* Fails if permission Id does not exists or permission already granted or denied
*
* @param permissionId permission to be granted
* @param realmId realm affected
*
* @return Success or failure (with reason) to grant the permission
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 permissionId = 2;
* if (rbac->GrantRole(permissionId) == RBAC_IN_DENIED_LIST)
* sLog->outDebug(LOG_FILTER_PLAYER, "Failed to grant permission %u, already denied", permissionId);
* @endcode
*/
RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId = 0);
/**
* @name DenyPermission
* @brief Denies a permission
*
* Denied a permission to the account. If realm is 0 or the permission can not be added
* No save to db action will be performed.
*
* Fails if permission Id does not exists or permission already granted or denied
*
* @param permissionId permission to be denied
* @param realmId realm affected
*
* @return Success or failure (with reason) to deny the permission
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 permissionId = 2;
* if (rbac->DenyRole(permissionId) == RBAC_ID_DOES_NOT_EXISTS)
* sLog->outDebug(LOG_FILTER_PLAYER, "Role Id %u does not exists", permissionId);
* @endcode
*/
RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId = 0);
/**
* @name RevokePermission
* @brief Removes a permission
*
* Removes a permission from the account. If realm is 0 or the permission can not be removed
* No save to db action will be performed. Any delete operation will always affect
* "all realms (-1)" in addition to the realm specified
*
* Fails if permission not present
*
* @param permissionId permission to be removed
* @param realmId realm affected
*
* @return Success or failure (with reason) to remove the permission
*
* Example Usage:
* // previously defined "RBACData* rbac" with proper initialization
* uint32 permissionId = 2;
* if (rbac->RevokeRole(permissionId) == RBAC_OK)
* sLog->outDebug(LOG_FILTER_PLAYER, "Permission %u succesfully removed", permissionId);
* @endcode
*/
RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0);
/// Loads all permissions, groups and roles assigned to current account
void LoadFromDB();
private:
/// Saves a role to DB, Granted or Denied
void SaveRole(uint32 role, bool granted, int32 realm);
/// Saves a permission to DB, Granted or Denied
void SavePermission(uint32 role, bool granted, int32 realm);
/**
* @name CalculateNewPermissions
* @brief Calculates new permissions
*
* Calculates new permissions after some change in groups, roles or permissions.
* The calculation is done Granted - Denied:
* - Granted permissions: through groups, through roles and directly assigned
* - Denied permissions: through roles and directly assigned
*/
void CalculateNewPermissions();
int32 GetRealmId() { return _realmId; }
int32 _realmId; ///> RealmId Affected
RBACGroupContainer _groups; ///> Granted groups
RBACRoleContainer _grantedRoles; ///> Granted roles
RBACRoleContainer _deniedRoles; ///> Denied roles
RBACPermissionContainer _grantedPerms; ///> Granted permissions
RBACPermissionContainer _deniedPerms; ///> Denied permissions
RBACPermissionContainer _globalPerms; ///> Calculated permissions
};
#endif