Core/RBAC: Simplify RBAC implementation

- Drop groups (roles than can have inherited roles) and roles (set of
  permissions)
- Permissions can now have inherited permissions (those act as roles)

RBAC DB structure is now limited to four tables
- rbac_permissions: Contains permissions and roles
- rbac_linked_permissions: Contains the relation between permissions and
  linked permissions (those permissions that have linked permissions are
  called roles)
- rbac_default_permissions: Contains the list of permissions to be granted
  to each security level [Added to maintain compatibility in an easy way]
- rbac_account_permissions: Contains the list of permissions granted or
  denied for a particular account.

NOTE: IF YOU ARE USING CUSTOM PERMISSIONS, ROLES OR GROUPS CHECK THE SQL
BEFORE APPLYING...
This commit is contained in:
Spp
2013-09-29 13:08:46 +02:00
parent a1fa7bf525
commit ea2fe0217d
10 changed files with 386 additions and 1105 deletions

View File

@@ -0,0 +1,99 @@
-- Update command permissions with wrong name
UPDATE `rbac_permissions` SET `name` = CONCAT('Command: ', `name`) WHERE `name` NOT LIKE 'Command: %' AND id BETWEEN 230 AND 774;
-- Reorder some permissions and delete obsolete permissions
SET FOREIGN_KEY_CHECKS = 0;
DELETE FROM `rbac_account_permissions` WHERE `permissionId` IN (202, 203, 204, 205, 206, 207, 208, 214, 215, 216);
DELETE FROM `rbac_role_permissions` WHERE `permissionId` IN (202, 203, 204, 205, 206, 207, 208, 214, 215, 216);
DELETE FROM `rbac_permissions` WHERE `id` IN (202, 203, 204, 205, 206, 207, 208, 214, 215, 216);
UPDATE `rbac_account_permissions` SET `permissionId` = `permissionId` - 7 WHERE `permissionId` BETWEEN 209 AND 213;
UPDATE `rbac_role_permissions` SET `permissionId` = `permissionId` - 7 WHERE `permissionId` BETWEEN 209 AND 213;
UPDATE `rbac_permissions` SET `id` = `id` - 7 WHERE `id` BETWEEN 209 AND 213;
SET FOREIGN_KEY_CHECKS = 1;
-- Create new table for permissions inherited from other permissions (roles)
DROP TABLE IF EXISTS `rbac_linked_permissions`;
CREATE TABLE `rbac_linked_permissions` (
`id` int(10) unsigned NOT NULL COMMENT 'Permission id',
`linkedId` int(10) unsigned NOT NULL COMMENT 'Linked Permission id',
PRIMARY KEY (`id`,`linkedId`),
KEY `fk__rbac_linked_permissions__rbac_permissions1` (`id`),
KEY `fk__rbac_linked_permissions__rbac_permissions2` (`linkedId`),
CONSTRAINT `fk__rbac_linked_permissions__rbac_permissions1` FOREIGN KEY (`id`) REFERENCES `rbac_permissions` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk__rbac_linked_permissions__rbac_permissions2` FOREIGN KEY (`linkedId`) REFERENCES `rbac_permissions` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Permission - Linked Permission relation';
-- Create new table for permissions inherited by security level
DROP TABLE IF EXISTS `rbac_default_permissions`;
CREATE TABLE `rbac_default_permissions` (
`secId` int(10) unsigned NOT NULL COMMENT 'Security Level id',
`permissionId` int(10) unsigned NOT NULL COMMENT 'permission id',
PRIMARY KEY (`secId`,`permissionId`),
KEY `fk__rbac_default_permissions__rbac_permissions` (`permissionId`),
CONSTRAINT `fk__rbac_default_permissions__rbac_permissions` FOREIGN KEY (`permissionId`) REFERENCES `rbac_permissions` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Default permission to assign to different account security levels';
DELETE FROM `rbac_permissions` WHERE `id` BETWEEN 192 AND 199;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
(199, 'Role: Player Commands'),
(198, 'Role: Moderator Commands'),
(197, 'Role: Gamemaster Commands'),
(196, 'Role: Administrator Commands'),
(195, 'Role: Sec Level Player'),
(194, 'Role: Sec Level Moderator'),
(193, 'Role: Sec Level Gamemaster'),
(192, 'Role: Sec Level Administrator');
INSERT INTO `rbac_default_permissions` (secId, `permissionId`) VALUES
(0, 195),
(1, 194),
(2, 193),
(3, 192);
-- Delete duplicate role assignment
DELETE FROM `rbac_group_roles` WHERE `roleId` = 39 AND `groupId` > 3;
DELETE FROM `rbac_group_roles` WHERE `roleId` = 40 AND `groupId` > 1;
DELETE FROM `rbac_group_roles` WHERE `roleId` IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 32, 33, 35, 36, 37, 38) AND `groupId` > 2;
DELETE FROM `rbac_role_permissions` WHERE `permissionId` = 263 AND `roleId` > 1;
-- Add All linked permissions
TRUNCATE `rbac_linked_permissions`;
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
(192, 193), -- Administrator has granted all permissions from Gamemaster
(192, 196), -- Grant Admin commands to Administrators
(193, 194), -- Gamemaster has granted all permissions from Moderator
(193, 197), -- Grant Gamemaster commands to Gamemasters
(194, 195), -- Moderator has granted all permissions from Player
(194, 198), -- Grant Moderator commands to Moderators
(195, 199); -- Grant Player commands to Players
-- Add all permissions to the Role "Sec Level XXX"
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`)
SELECT (196 - g.id), p.id
FROM `rbac_groups` g
JOIN `rbac_group_roles` gr ON g.id = gr.groupId
JOIN `rbac_roles` r ON gr.roleId = r.id
JOIN `rbac_role_permissions` rp ON r.id = rp.roleId
JOIN `rbac_permissions` p ON rp.permissionId = p.id
WHERE r.id > 4;
-- Add all permissions to the Role "XXX Commands"
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`)
SELECT (200 - r.id), p.id
FROM `rbac_roles` r
JOIN `rbac_role_permissions` rp ON r.id = rp.roleId
JOIN `rbac_permissions` p ON rp.permissionId = p.id
WHERE r.id BETWEEN 1 and 4;
-- Delete obsolete tables
DROP TABLE IF EXISTS `rbac_account_roles`;
DROP TABLE IF EXISTS `rbac_account_groups`;
DROP TABLE IF EXISTS `rbac_security_level_groups`;
DROP TABLE IF EXISTS `rbac_group_roles`;
DROP TABLE IF EXISTS `rbac_role_permissions`;
DROP TABLE IF EXISTS `rbac_groups`;
DROP TABLE IF EXISTS `rbac_roles`;

View File

@@ -0,0 +1,18 @@
DELETE FROM `trinity_string` WHERE `entry` IN (65, 66, 67, 68, 69, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 93, 94);
UPDATE `trinity_string` SET `entry` = 65 WHERE `entry` = 90;
UPDATE `trinity_string` SET `entry` = 66 WHERE `entry` = 91;
UPDATE `trinity_string` SET `entry` = 68 WHERE `entry` = 95;
UPDATE `trinity_string` SET `entry` = `entry` - 10 WHERE `entry` BETWEEN 82 AND 89;
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
(67, 'Account %u (%s) inherited permissions by sec level %u:'),
(69, 'Linked permissions:');
DELETE FROM `command` WHERE `permission` BETWEEN 200 AND 213;
INSERT INTO `command` (`name`, `permission`, `help`) VALUES
('.rbac account list', 202, 'Syntax: rbac account list [$account]\n\nView permissions of selected player or given account\nNote: Only those that affect current realm'),
('.rbac account grant', 203, 'Syntax: rbac account grant [$account] #id [#realmId]\n\nGrant a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'),
('.rbac account deny', 204, 'Syntax: rbac account deny [$account] #id [#realmId]\n\nDeny a permission to selected player or given account.\n\n#reamID may be -1 for all realms.'),
('.rbac account revoke', 205, 'Syntax: rbac account revoke [$account] #id\n\nRemove a permission from an account\n\nNote: Removes the permission from granted or denied permissions'),
('.rbac list', 206, 'Syntax: rbac list [$id]\n\nView list of all permissions. If $id is given will show only info for that permission.');

View File

@@ -415,102 +415,69 @@ void AccountMgr::LoadRBAC()
} }
while (result->NextRow()); while (result->NextRow());
TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading roles"); TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading linked permissions");
result = LoginDatabase.Query("SELECT id, name FROM rbac_roles"); result = LoginDatabase.Query("SELECT id, linkedId FROM rbac_linked_permissions ORDER BY id ASC");
if (!result) if (!result)
{ {
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account role definitions. DB table `rbac_roles` is empty."); TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 linked permissions. DB table `rbac_linked_permissions` is empty.");
return; return;
} }
uint32 permissionId = 0;
rbac::RBACPermission* permission = NULL;
do do
{ {
Field* field = result->Fetch(); Field* field = result->Fetch();
uint32 id = field[0].GetUInt32(); uint32 newId = field[0].GetUInt32();
_roles[id] = new rbac::RBACRole(id, field[1].GetString()); if (permissionId != newId)
{
permissionId = newId;
permission = _permissions[newId];
}
uint32 linkedPermissionId = field[1].GetUInt32();
if (linkedPermissionId == permissionId)
{
TC_LOG_ERROR(LOG_FILTER_SQL, "RBAC Permission %u has itself as linked permission. Ignored", permissionId);
continue;
}
permission->AddLinkedPermission(linkedPermissionId);
++count2; ++count2;
} }
while (result->NextRow()); while (result->NextRow());
TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading role permissions"); TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading default permissions");
result = LoginDatabase.Query("SELECT roleId, permissionId FROM rbac_role_permissions"); result = LoginDatabase.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
if (!result) if (!result)
{ {
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account role-permission definitions. DB table `rbac_role_permissions` is empty."); TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
return; return;
} }
uint8 secId = 255;
rbac::RBACPermissionContainer* permissions;
do do
{ {
Field* field = result->Fetch(); Field* field = result->Fetch();
uint32 id = field[0].GetUInt32(); uint32 newId = field[0].GetUInt32();
rbac::RBACRole* role = _roles[id]; if (secId != newId)
role->GrantPermission(field[1].GetUInt32()); {
} secId = newId;
while (result->NextRow()); permissions = &_defaultPermissions[secId];
}
TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading groups");
result = LoginDatabase.Query("SELECT id, name FROM rbac_groups"); permissions->insert(field[1].GetUInt32());
if (!result)
{
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account group definitions. DB table `rbac_groups` is empty.");
return;
}
do
{
Field* field = result->Fetch();
uint32 id = field[0].GetUInt32();
_groups[id] = new rbac::RBACGroup(id, field[1].GetString());
++count3; ++count3;
} }
while (result->NextRow()); while (result->NextRow());
TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading group roles"); TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u linked permissions and %u default permissions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime));
result = LoginDatabase.Query("SELECT groupId, roleId FROM rbac_group_roles");
if (!result)
{
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account group-role definitions. DB table `rbac_group_roles` is empty.");
return;
}
do
{
Field* field = result->Fetch();
uint32 id = field[0].GetUInt32();
rbac::RBACGroup* group = _groups[id];
group->GrantRole(field[1].GetUInt32());
}
while (result->NextRow());
TC_LOG_DEBUG(LOG_FILTER_RBAC, "AccountMgr::LoadRBAC: Loading security level groups");
result = LoginDatabase.Query("SELECT secId, groupId FROM rbac_security_level_groups ORDER by secId ASC");
if (!result)
{
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 account default groups for security levels definitions. DB table `rbac_security_level_groups` is empty.");
return;
}
uint8 lastSecId = 255;
rbac::RBACGroupContainer* groups = NULL;
do
{
Field* field = result->Fetch();
uint8 secId = field[0].GetUInt8();
if (lastSecId != secId)
groups = &_defaultSecGroups[secId];
groups->insert(field[1].GetUInt32());
}
while (result->NextRow());
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u permission definitions, %u role definitions and %u group definitions in %u ms", count1, count2, count3, GetMSTimeDiffToNow(oldMSTime));
} }
void AccountMgr::UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId) void AccountMgr::UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId)
{ {
if (rbac) if (rbac && securityLevel == rbac->GetSecurityLevel())
rbac->SetSecurityLevel(securityLevel); rbac->SetSecurityLevel(securityLevel);
// Delete old security level from DB // Delete old security level from DB
@@ -539,29 +506,9 @@ void AccountMgr::UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uin
} }
} }
rbac::RBACGroup const* AccountMgr::GetRBACGroup(uint32 groupId) const
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACGroup: groupId: %u", groupId);
rbac::RBACGroupsContainer::const_iterator it = _groups.find(groupId);
if (it != _groups.end())
return it->second;
return NULL;
}
rbac::RBACRole const* AccountMgr::GetRBACRole(uint32 roleId) const
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACRole: roleId: %u", roleId);
rbac::RBACRolesContainer::const_iterator it = _roles.find(roleId);
if (it != _roles.end())
return it->second;
return NULL;
}
rbac::RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const rbac::RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) const
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: roleId: %u", permissionId); TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACPermission: %u", permissionId);
rbac::RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId); rbac::RBACPermissionsContainer::const_iterator it = _permissions.find(permissionId);
if (it != _permissions.end()) if (it != _permissions.end())
return it->second; return it->second;
@@ -591,14 +538,12 @@ void AccountMgr::ClearRBAC()
for (rbac::RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr) for (rbac::RBACPermissionsContainer::iterator itr = _permissions.begin(); itr != _permissions.end(); ++itr)
delete itr->second; delete itr->second;
for (rbac::RBACRolesContainer::iterator itr = _roles.begin(); itr != _roles.end(); ++itr)
delete itr->second;
for (rbac::RBACGroupsContainer::iterator itr = _groups.begin(); itr != _groups.end(); ++itr)
delete itr->second;
_permissions.clear(); _permissions.clear();
_roles.clear(); _defaultPermissions.clear();
_groups.clear(); }
_defaultSecGroups.clear();
rbac::RBACPermissionContainer const& AccountMgr::GetRBACDefaultPermissions(uint8 secLevel)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "AccountMgr::GetRBACDefaultPermissions: secLevel %u - size: %u", secLevel, _defaultPermissions[secLevel].size());
return _defaultPermissions[secLevel];
} }

View File

@@ -46,9 +46,7 @@ enum PasswordChangeSecurity
namespace rbac namespace rbac
{ {
typedef std::map<uint32, rbac::RBACPermission*> RBACPermissionsContainer; typedef std::map<uint32, rbac::RBACPermission*> RBACPermissionsContainer;
typedef std::map<uint32, rbac::RBACRole*> RBACRolesContainer; typedef std::map<uint8, rbac::RBACPermissionContainer> RBACDefaultPermissionsContainer;
typedef std::map<uint32, rbac::RBACGroup*> RBACGroupsContainer;
typedef std::map<uint32, rbac::RBACGroupContainer> RBACDefaultSecurityGroupContainer;
} }
class AccountMgr class AccountMgr
@@ -86,21 +84,15 @@ class AccountMgr
void UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId); void UpdateAccountAccess(rbac::RBACData* rbac, uint32 accountId, uint8 securityLevel, int32 realmId);
void LoadRBAC(); void LoadRBAC();
rbac::RBACGroup const* GetRBACGroup(uint32 group) const;
rbac::RBACRole const* GetRBACRole(uint32 role) const;
rbac::RBACPermission const* GetRBACPermission(uint32 permission) const; rbac::RBACPermission const* GetRBACPermission(uint32 permission) const;
rbac::RBACGroupsContainer const& GetRBACGroupList() const { return _groups; }
rbac::RBACRolesContainer const& GetRBACRoleList() const { return _roles; }
rbac::RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; } rbac::RBACPermissionsContainer const& GetRBACPermissionList() const { return _permissions; }
rbac::RBACGroupContainer const& GetRBACDefaultGroups(uint8 secLevel) { return _defaultSecGroups[secLevel]; } rbac::RBACPermissionContainer const& GetRBACDefaultPermissions(uint8 secLevel);
private: private:
void ClearRBAC(); void ClearRBAC();
rbac::RBACPermissionsContainer _permissions; rbac::RBACPermissionsContainer _permissions;
rbac::RBACRolesContainer _roles; rbac::RBACDefaultPermissionsContainer _defaultPermissions;
rbac::RBACGroupsContainer _groups;
rbac::RBACDefaultSecurityGroupContainer _defaultSecGroups;
}; };
#define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance() #define sAccountMgr ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance()

View File

@@ -23,238 +23,20 @@
namespace rbac namespace rbac
{ {
void RBACRole::GrantPermission(uint32 permissionId) std::string GetDebugPermissionString(RBACPermissionContainer const& perms)
{ {
if (permissionId < RBAC_PERM_MAX) std::string str = "";
if (!perms.empty())
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), permissionId); std::ostringstream o;
_perms.set(permissionId); RBACPermissionContainer::const_iterator itr = perms.begin();
} o << (*itr);
else for (++itr; itr != perms.end(); ++itr)
TC_LOG_ERROR(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Permission not lower than %u", o << ", " << uint32(*itr);
GetId(), permissionId, RBAC_PERM_MAX); str = o.str();
}
void RBACRole::RevokePermission(uint32 permissionId)
{
if (permissionId < RBAC_PERM_MAX)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Ok", GetId(), permissionId);
_perms.reset(permissionId);
}
else
TC_LOG_ERROR(LOG_FILTER_RBAC, "RBACRole::RevokePermission (Role %u, Permission %u). Permission not lower than %u",
GetId(), permissionId, RBAC_PERM_MAX);
}
void RBACGroup::GrantRole(uint32 roleId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
_roles.insert(roleId);
}
void RBACGroup::RevokeRole(uint32 roleId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACRole::GrantPermission (Role %u, Permission %u). Ok", GetId(), roleId);
_roles.erase(roleId);
}
RBACCommandResult RBACData::AddGroup(uint32 groupId, int32 realmId /* = 0 */)
{
// Check if group Id exists
RBACGroup const* group = sAccountMgr->GetRBACGroup(groupId);
if (!group)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group does not exists",
GetId(), GetName().c_str(), groupId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
} }
// Already added? return str;
std::pair<std::set<uint32>::iterator, bool> ret = _groups.insert(groupId);
if (!ret.second)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group Already added",
GetId(), GetName().c_str(), groupId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
}
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added and DB updated",
GetId(), GetName().c_str(), groupId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, groupId);
stmt->setInt32(2, realmId);
LoginDatabase.Execute(stmt);
CalculateNewPermissions();
}
else
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::AddGroup [Id: %u Name: %s] (Group %u, RealmId %d). Added",
GetId(), GetName().c_str(), groupId, realmId);
return RBAC_OK;
}
RBACCommandResult RBACData::RemoveGroup(uint32 groupId, int32 realmId /* = 0 */)
{
// could remove it?
if (!_groups.erase(groupId))
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Group not in list",
GetId(), GetName().c_str(), groupId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST;
}
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed and DB updated",
GetId(), GetName().c_str(), groupId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, groupId);
stmt->setInt32(2, realmId);
LoginDatabase.Execute(stmt);
CalculateNewPermissions();
}
else
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RemoveGroup [Id: %u Name: %s] (Group %u, RealmId %d). Removed",
GetId(), GetName().c_str(), groupId, realmId);
return RBAC_OK;
}
RBACCommandResult RBACData::GrantRole(uint32 roleId, int32 realmId /* = 0*/)
{
// Check if role Id exists
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
if (!role)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
}
// Check if already added in denied list
if (_deniedRoles.find(roleId) != _deniedRoles.end())
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in deny list",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_IN_DENIED_LIST;
}
// Already added?
std::pair<std::set<uint32>::iterator, bool> ret = _grantedRoles.insert(roleId);
if (!ret.second)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already granted",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
}
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
GetId(), GetName().c_str(), roleId, realmId);
SaveRole(roleId, true, realmId);
CalculateNewPermissions();
}
else
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
}
RBACCommandResult RBACData::DenyRole(uint32 roleId, int32 realmId /* = 0*/)
{
// Check if role Id exists
RBACRole const* role = sAccountMgr->GetRBACRole(roleId);
if (!role)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role does not exists",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_ID_DOES_NOT_EXISTS;
}
// Check if already added in granted list
if (_grantedRoles.find(roleId) != _grantedRoles.end())
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role in grant list",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_IN_GRANTED_LIST;
}
// Already added?
std::pair<std::set<uint32>::iterator, bool> ret = _deniedRoles.insert(roleId);
if (!ret.second)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Role already denied",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED;
}
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
GetId(), GetName().c_str(), roleId, realmId);
SaveRole(roleId, false, realmId);
CalculateNewPermissions();
}
else
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
}
void RBACData::SaveRole(uint32 roleId, bool granted, int32 realmId)
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, roleId);
stmt->setBool(2, granted);
stmt->setInt32(3, realmId);
LoginDatabase.Execute(stmt);
}
RBACCommandResult RBACData::RevokeRole(uint32 roleId, int32 realmId /* = 0*/)
{
uint8 revoked = _grantedRoles.erase(roleId) + _deniedRoles.erase(roleId);
// could remove it?
if (!revoked)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Not granted or revoked",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST;
}
// Do not save to db when loading data from DB (realmId = 0)
if (realmId)
{
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok and DB updated",
GetId(), GetName().c_str(), roleId, realmId);
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE);
stmt->setUInt32(0, GetId());
stmt->setUInt32(1, roleId);
stmt->setInt32(2, realmId);
LoginDatabase.Execute(stmt);
CalculateNewPermissions();
}
else
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokeRole [Id: %u Name: %s] (Role %u, RealmId %d). Ok",
GetId(), GetName().c_str(), roleId, realmId);
return RBAC_OK;
} }
RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/) RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/)
@@ -269,7 +51,7 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /
} }
// Check if already added in denied list // Check if already added in denied list
if (_deniedPerms.test(permissionId)) if (HasDeniedPermission(permissionId))
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list", TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list",
GetId(), GetName().c_str(), permissionId, realmId); GetId(), GetName().c_str(), permissionId, realmId);
@@ -277,14 +59,14 @@ RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /
} }
// Already added? // Already added?
if (_grantedPerms.test(permissionId)) if (HasGrantedPermission(permissionId))
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted", TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted",
GetId(), GetName().c_str(), permissionId, realmId); GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED; return RBAC_CANT_ADD_ALREADY_ADDED;
} }
_grantedPerms.set(permissionId); AddGrantedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0) // Do not save to db when loading data from DB (realmId = 0)
if (realmId) if (realmId)
@@ -313,7 +95,7 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /*
} }
// Check if already added in granted list // Check if already added in granted list
if (_grantedPerms.test(permissionId)) if (HasGrantedPermission(permissionId))
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list", TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list",
GetId(), GetName().c_str(), permissionId, realmId); GetId(), GetName().c_str(), permissionId, realmId);
@@ -321,14 +103,14 @@ RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /*
} }
// Already added? // Already added?
if (_deniedPerms.test(permissionId)) if (HasDeniedPermission(permissionId))
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied", TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied",
GetId(), GetName().c_str(), permissionId, realmId); GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_ADD_ALREADY_ADDED; return RBAC_CANT_ADD_ALREADY_ADDED;
} }
_deniedPerms.set(permissionId); AddDeniedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0) // Do not save to db when loading data from DB (realmId = 0)
if (realmId) if (realmId)
@@ -358,15 +140,15 @@ void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/) RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/)
{ {
// Check if it's present in any list // Check if it's present in any list
if (!_grantedPerms.test(permissionId) && !_deniedPerms.test(permissionId)) if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId))
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked", TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked",
GetId(), GetName().c_str(), permissionId, realmId); GetId(), GetName().c_str(), permissionId, realmId);
return RBAC_CANT_REVOKE_NOT_IN_LIST; return RBAC_CANT_REVOKE_NOT_IN_LIST;
} }
_grantedPerms.reset(permissionId); RemoveGrantedPermission(permissionId);
_deniedPerms.reset(permissionId); RemoveDeniedPermission(permissionId);
// Do not save to db when loading data from DB (realmId = 0) // Do not save to db when loading data from DB (realmId = 0)
if (realmId) if (realmId)
@@ -392,52 +174,13 @@ void RBACData::LoadFromDB()
{ {
ClearData(); ClearData();
TC_LOG_INFO(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]", GetId(), GetName().c_str());
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading groups", GetId(), GetName().c_str());
// Load account group that affect current realm
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS);
stmt->setUInt32(0, GetId());
stmt->setInt32(1, GetRealmId());
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
{
do
{
Field* fields = result->Fetch();
AddGroup(fields[0].GetUInt32());
}
while (result->NextRow());
}
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading roles", GetId(), GetName().c_str());
// Load account roles (granted and denied) that affect current realm
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES);
stmt->setUInt32(0, GetId());
stmt->setInt32(1, GetRealmId());
result = LoginDatabase.Query(stmt);
if (result)
{
do
{
Field* fields = result->Fetch();
if (fields[1].GetBool())
GrantRole(fields[0].GetUInt32());
else
DenyRole(fields[0].GetUInt32());
}
while (result->NextRow());
}
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str()); TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str());
// Load account permissions (granted and denied) that affect current realm // Load account permissions (granted and denied) that affect current realm
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
stmt->setUInt32(0, GetId()); stmt->setUInt32(0, GetId());
stmt->setInt32(1, GetRealmId()); stmt->setInt32(1, GetRealmId());
result = LoginDatabase.Query(stmt); PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result) if (result)
{ {
do do
@@ -451,61 +194,72 @@ void RBACData::LoadFromDB()
while (result->NextRow()); while (result->NextRow());
} }
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Adding default groups", GetId(), GetName().c_str()); // Add default permissions
// Add default groups RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel);
RBACGroupContainer const& groups = sAccountMgr->GetRBACDefaultGroups(GetSecurityLevel()); for (RBACPermissionContainer::const_iterator itr = permissions.begin(); itr != permissions.end(); ++itr)
for (RBACGroupContainer::const_iterator itr = groups.begin(); itr != groups.end(); ++itr) GrantPermission(*itr);
AddGroup(*itr);
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str()); // Force calculation of permissions
// Force calculation of permissions, it wasn't performed at load time
// while adding groups, roles and permissions
CalculateNewPermissions(); CalculateNewPermissions();
} }
void RBACData::CalculateNewPermissions() void RBACData::CalculateNewPermissions()
{ {
TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::LoadFromDB [Id: %u Name: %s]: Calculating global permissions", GetId(), GetName().c_str()); TC_LOG_TRACE(LOG_FILTER_RBAC, "RBACData::CalculateNewPermissions [Id: %u Name: %s]", GetId(), GetName().c_str());
// Get the list of directly granted roles
RBACRoleContainer tempGrantedRoles = GetGrantedRoles();
// Add those roles inherited from groups
for (RBACGroupContainer::const_iterator itGroup = _groups.begin(); itGroup != _groups.end(); ++itGroup)
{
RBACGroup const* group = sAccountMgr->GetRBACGroup(*itGroup);
if (!group) // Should never happen due to foreign keys in DB
continue;
RBACRoleContainer const& roles = group->GetRoles();
for (RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
tempGrantedRoles.insert(*it);
}
// Get the list of granted permissions // Get the list of granted permissions
_globalPerms = GetGrantedPermissions(); _globalPerms = GetGrantedPermissions();
ExpandPermissions(_globalPerms);
RBACPermissionContainer revoked = GetDeniedPermissions();
ExpandPermissions(revoked);
RemovePermissions(_globalPerms, revoked);
}
// Add those permissions inherited from roles granted void RBACData::AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
for (RBACRoleContainer::const_iterator it = tempGrantedRoles.begin(); it != tempGrantedRoles.end(); ++it) {
if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
_globalPerms |= role->GetPermissions(); permsTo.insert(*itr);
}
// Remove denied permissions from the list void RBACData::RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
_globalPerms &= ~GetDeniedPermissions(); {
for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
permsTo.erase(*itr);
}
// Remove those permissions inherited from denied roles void RBACData::ExpandPermissions(RBACPermissionContainer& permissions)
for (RBACRoleContainer::const_iterator it = _deniedRoles.begin(); it != _deniedRoles.end(); ++it) {
if (RBACRole const* role = sAccountMgr->GetRBACRole(*it)) RBACPermissionContainer toCheck = permissions;
_globalPerms &= ~role->GetPermissions(); permissions.clear();
while (!toCheck.empty())
{
// remove the permission from original list
uint32 permissionId = *toCheck.begin();
toCheck.erase(toCheck.begin());
RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId);
if (!permission)
continue;
// insert into the final list (expanded list)
permissions.insert(permissionId);
// add all linked permissions (that are not already expanded) to the list of permissions to be checked
RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions();
for (RBACPermissionContainer::const_iterator itr = linkedPerms.begin(); itr != linkedPerms.end(); ++itr)
if (permissions.find(*itr) == permissions.end())
toCheck.insert(*itr);
}
TC_LOG_DEBUG(LOG_FILTER_RBAC, "RBACData::ExpandPermissions: Expanded: %s", GetDebugPermissionString(permissions).c_str());
} }
void RBACData::ClearData() void RBACData::ClearData()
{ {
_groups.clear(); _grantedPerms.clear();
_grantedRoles.clear(); _deniedPerms.clear();
_deniedRoles.clear(); _globalPerms.clear();
_grantedPerms.reset();
_deniedPerms.reset();
_globalPerms.reset();
} }
} }

View File

@@ -42,7 +42,6 @@
#include "Define.h" #include "Define.h"
#include <string> #include <string>
#include <bitset>
#include <set> #include <set>
#include <map> #include <map>
@@ -101,25 +100,26 @@ enum RBACPermissions
RBAC_PERM_COMMANDS_PINFO_CHECK_PERSONAL_DATA = 48, RBAC_PERM_COMMANDS_PINFO_CHECK_PERSONAL_DATA = 48,
RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE = 49, RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE = 49,
RBAC_PERM_MAY_CHECK_OWN_EMAIL = 50, RBAC_PERM_MAY_CHECK_OWN_EMAIL = 50,
// Leave some space for core permissions
// Free space for core permissions (till 149)
// Roles (Permissions with delegated permissions) use 199 and descending
RBAC_PERM_COMMAND_RBAC = 200, RBAC_PERM_COMMAND_RBAC = 200,
RBAC_PERM_COMMAND_RBAC_ACC = 201, RBAC_PERM_COMMAND_RBAC_ACC = 201,
RBAC_PERM_COMMAND_RBAC_ACC_GROUP = 202, RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST = 202,
RBAC_PERM_COMMAND_RBAC_ACC_GROUP_ADD = 203, RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT = 203,
RBAC_PERM_COMMAND_RBAC_ACC_GROUP_DEL = 204, RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY = 204,
RBAC_PERM_COMMAND_RBAC_ACC_ROLE = 205, RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE = 205,
RBAC_PERM_COMMAND_RBAC_ACC_ROLE_GRANT = 206, RBAC_PERM_COMMAND_RBAC_LIST = 206,
RBAC_PERM_COMMAND_RBAC_ACC_ROLE_DENY = 207, // 207 - reuse
RBAC_PERM_COMMAND_RBAC_ACC_ROLE_REVOKE = 208, // 208 - reuse
RBAC_PERM_COMMAND_RBAC_ACC_PERM = 209, // 209 - reuse
RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT = 210, // 210 - reuse
RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY = 211, // 211 - reuse
RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE = 212, // 212 - reuse
RBAC_PERM_COMMAND_RBAC_LIST = 213, // 213 - reuse
RBAC_PERM_COMMAND_RBAC_LIST_GROUPS = 214, // 214 - reuse
RBAC_PERM_COMMAND_RBAC_LIST_ROLES = 215, // 215 - reuse
RBAC_PERM_COMMAND_RBAC_LIST_PERMS = 216, // 216 - reuse
RBAC_PERM_COMMAND_ACCOUNT = 217, RBAC_PERM_COMMAND_ACCOUNT = 217,
RBAC_PERM_COMMAND_ACCOUNT_ADDON = 218, RBAC_PERM_COMMAND_ACCOUNT_ADDON = 218,
RBAC_PERM_COMMAND_ACCOUNT_CREATE = 219, RBAC_PERM_COMMAND_ACCOUNT_CREATE = 219,
@@ -678,8 +678,6 @@ enum RBACPermissions
RBAC_PERM_COMMAND_WP_UNLOAD = 772, RBAC_PERM_COMMAND_WP_UNLOAD = 772,
RBAC_PERM_COMMAND_WP_RELOAD = 773, RBAC_PERM_COMMAND_WP_RELOAD = 773,
RBAC_PERM_COMMAND_WP_SHOW = 774, RBAC_PERM_COMMAND_WP_SHOW = 774,
RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4
RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // Only 4.3.4
// custom permissions 1000+ // custom permissions 1000+
RBAC_PERM_MAX RBAC_PERM_MAX
@@ -695,93 +693,53 @@ enum RBACCommandResult
RBAC_ID_DOES_NOT_EXISTS RBAC_ID_DOES_NOT_EXISTS
}; };
typedef std::bitset<RBAC_PERM_MAX> RBACPermissionContainer; typedef std::set<uint32> RBACPermissionContainer;
typedef std::set<uint32> RBACRoleContainer;
typedef std::set<uint32> RBACGroupContainer;
class RBACObject class RBACPermission
{ {
public: public:
RBACObject(uint32 id = 0, std::string const& name = ""): RBACPermission(uint32 id = 0, std::string const& name = ""):
_id(id), _name(name) { } _id(id), _name(name) { }
virtual ~RBACObject() { }
/// Gets the Name of the Object /// Gets the Name of the Object
std::string const& GetName() const { return _name; } std::string const& GetName() const { return _name; }
/// Gets the Id of the Object /// Gets the Id of the Object
uint32 GetId() const { return _id; } uint32 GetId() const { return _id; }
/// Gets the Permissions linked to this permission
RBACPermissionContainer const& GetLinkedPermissions() const { return _perms; }
/// Adds a new linked Permission
void AddLinkedPermission(uint32 id) { _perms.insert(id); }
/// Removes a linked Permission
void RemoveLinkedPermission(uint32 id) { _perms.erase(id); }
private: private:
uint32 _id; ///> id of the object uint32 _id; ///> id of the object
std::string _name; ///> name 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);
/// Revokes a Permission (Removes)
void RevokePermission(uint32 id);
private:
RBACPermissionContainer _perms; ///> Set of permissions 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);
/// Revokes a Role (Removes)
void RevokeRole(uint32 role);
private:
RBACRoleContainer _roles; ///> Set of Roles
};
/** /**
* @name RBACData * @name RBACData
* @brief Contains all needed information about the acccount * @brief Contains all needed information about the acccount
* *
* This class contains all the data needed to calculate the account permissions. * This class contains all the data needed to calculate the account permissions.
* RBACDAta is formed by group permissions and user permissions through: * RBACDAta is formed by granted and denied permissions and all the inherited permissions
* - 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 * Calculation of current Permissions: Granted permissions - Denied permissions
* - Granted permissions: through groups, through roles and directly assigned * - Granted permissions: through linked permissions and directly assigned
* - Denied permissions: through roles and directly assigned * - Denied permissions: through linked permissions and directly assigned
*/ */
class RBACData: public RBACObject class RBACData
{ {
public: public:
RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel = 0): RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel = 255):
RBACObject(id, name), _realmId(realmId), _secLevel(secLevel) { } _id(id), _name(name), _realmId(realmId), _secLevel(secLevel) { }
/// Gets the Name of the Object
std::string const& GetName() const { return _name; }
/// Gets the Id of the Object
uint32 GetId() const { return _id; }
/** /**
* @name HasPermission * @name HasPermission
@@ -799,7 +757,10 @@ class RBACData: public RBACObject
* } * }
* @endcode * @endcode
*/ */
bool HasPermission(uint32 permission) const { return _globalPerms.test(permission); } bool HasPermission(uint32 permission) const
{
return _globalPerms.find(permission) != _globalPerms.end();
}
// Functions enabled to be used by command system // Functions enabled to be used by command system
/// Returns all the granted permissions (after computation) /// Returns all the granted permissions (after computation)
@@ -808,130 +769,6 @@ class RBACData: public RBACObject
RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; } RBACPermissionContainer const& GetGrantedPermissions() const { return _grantedPerms; }
/// Returns all the denied permissions /// Returns all the denied permissions
RBACPermissionContainer const& GetDeniedPermissions() const { return _deniedPerms; } 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)
* TC_LOG_DEBUG(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)
* TC_LOG_DEBUG(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)
* TC_LOG_DEBUG(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)
* TC_LOG_DEBUG(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)
* TC_LOG_DEBUG(LOG_FILTER_PLAYER, "Role %u succesfully removed", roleId);
* @endcode
*/
RBACCommandResult RevokeRole(uint32 roleId, int32 realmId = 0);
/** /**
* @name GrantRole * @name GrantRole
@@ -1003,7 +840,7 @@ class RBACData: public RBACObject
*/ */
RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0); RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId = 0);
/// Loads all permissions, groups and roles assigned to current account /// Loads all permissions assigned to current account
void LoadFromDB(); void LoadFromDB();
/// Sets security level /// Sets security level
@@ -1016,8 +853,6 @@ class RBACData: public RBACObject
/// Returns the security level assigned /// Returns the security level assigned
uint8 GetSecurityLevel() const { return _secLevel; } uint8 GetSecurityLevel() const { return _secLevel; }
private: 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 /// Saves a permission to DB, Granted or Denied
void SavePermission(uint32 role, bool granted, int32 realm); void SavePermission(uint32 role, bool granted, int32 realm);
/// Clears roles, groups and permissions - Used for reload /// Clears roles, groups and permissions - Used for reload
@@ -1027,20 +862,76 @@ class RBACData: public RBACObject
* @name CalculateNewPermissions * @name CalculateNewPermissions
* @brief Calculates new permissions * @brief Calculates new permissions
* *
* Calculates new permissions after some change in groups, roles or permissions. * Calculates new permissions after some change
* The calculation is done Granted - Denied: * The calculation is done Granted - Denied:
* - Granted permissions: through groups, through roles and directly assigned * - Granted permissions: through linked permissions and directly assigned
* - Denied permissions: through roles and directly assigned * - Denied permissions: through linked permissions and directly assigned
*/ */
void CalculateNewPermissions(); void CalculateNewPermissions();
int32 GetRealmId() { return _realmId; } int32 GetRealmId() { return _realmId; }
// Auxiliar private functions - defined to allow to maintain same code even
// if internal structure changes.
/// Checks if a permission is granted
bool HasGrantedPermission(uint32 permissionId) const
{
return _grantedPerms.find(permissionId) != _grantedPerms.end();
}
/// Checks if a permission is denied
bool HasDeniedPermission(uint32 permissionId) const
{
return _deniedPerms.find(permissionId) != _deniedPerms.end();
}
/// Adds a new granted permission
void AddGrantedPermission(uint32 permissionId)
{
_grantedPerms.insert(permissionId);
}
/// Removes a granted permission
void RemoveGrantedPermission(uint32 permissionId)
{
_grantedPerms.erase(permissionId);
}
/// Adds a new denied permission
void AddDeniedPermission(uint32 permissionId)
{
_deniedPerms.insert(permissionId);
}
/// Removes a denied permission
void RemoveDeniedPermission(uint32 permissionId)
{
_deniedPerms.erase(permissionId);
}
/// Adds a list of permissions to another list
void AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo);
/// Removes a list of permissions to another list
void RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo);
/**
* @name ExpandPermissions
* @brief Adds the list of linked permissions to the original list
*
* Given a list of permissions, gets all the inherited permissions
* @param permissions The list of permissions to expand
*
* @return new list of permissions containing original permissions and
* all other pemissions that are linked to the original ones
*/
void ExpandPermissions(RBACPermissionContainer& permissions);
uint32 _id; ///> Account id
std::string _name; ///> Account name
int32 _realmId; ///> RealmId Affected int32 _realmId; ///> RealmId Affected
uint8 _secLevel; ///> Account SecurityLevel uint8 _secLevel; ///> Account SecurityLevel
RBACGroupContainer _groups; ///> Granted groups
RBACRoleContainer _grantedRoles; ///> Granted roles
RBACRoleContainer _deniedRoles; ///> Denied roles
RBACPermissionContainer _grantedPerms; ///> Granted permissions RBACPermissionContainer _grantedPerms; ///> Granted permissions
RBACPermissionContainer _deniedPerms; ///> Denied permissions RBACPermissionContainer _deniedPerms; ///> Denied permissions
RBACPermissionContainer _globalPerms; ///> Calculated permissions RBACPermissionContainer _globalPerms; ///> Calculated permissions

View File

@@ -88,37 +88,24 @@ enum TrinityStrings
LANG_IMPROPER_VALUE = 62, LANG_IMPROPER_VALUE = 62,
LANG_RBAC_WRONG_PARAMETER_ID = 63, LANG_RBAC_WRONG_PARAMETER_ID = 63,
LANG_RBAC_WRONG_PARAMETER_REALM = 64, LANG_RBAC_WRONG_PARAMETER_REALM = 64,
LANG_RBAC_GROUP_IN_LIST = 65, LANG_RBAC_LIST_HEADER_GRANTED = 65,
LANG_RBAC_GROUP_NOT_IN_LIST = 66, LANG_RBAC_LIST_HEADER_DENIED = 66,
LANG_RBAC_GROUP_ADDED = 67, LANG_RBAC_LIST_HEADER_BY_SEC_LEVEL = 67,
LANG_RBAC_GROUP_REMOVED = 68, LANG_RBAC_LIST_PERMISSIONS_HEADER = 68,
LANG_RBAC_GROUP_LIST_HEADER = 69, LANG_RBAC_LIST_PERMS_LINKED_HEADER = 69,
LANG_RBAC_LIST_EMPTY = 70, LANG_RBAC_LIST_EMPTY = 70,
LANG_RBAC_LIST_ELEMENT = 71, LANG_RBAC_LIST_ELEMENT = 71,
LANG_RBAC_ROLE_GRANTED_IN_LIST = 72, LANG_RBAC_PERM_GRANTED_IN_LIST = 72,
LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST = 73, LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 73,
LANG_RBAC_ROLE_GRANTED = 74, LANG_RBAC_PERM_GRANTED = 74,
LANG_RBAC_ROLE_DENIED_IN_LIST = 75, LANG_RBAC_PERM_DENIED_IN_LIST = 75,
LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST = 76, LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 76,
LANG_RBAC_ROLE_DENIED = 77, LANG_RBAC_PERM_DENIED = 77,
LANG_RBAC_ROLE_REVOKED = 78, LANG_RBAC_PERM_REVOKED = 78,
LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST = 79, LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 79,
LANG_RBAC_ROLE_LIST_HEADER_GRANTED = 80, // Free 80 - 95
LANG_RBAC_ROLE_LIST_HEADER_DENIED = 81,
LANG_RBAC_PERM_GRANTED_IN_LIST = 82,
LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST = 83,
LANG_RBAC_PERM_GRANTED = 84,
LANG_RBAC_PERM_DENIED_IN_LIST = 85,
LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST = 86,
LANG_RBAC_PERM_DENIED = 87,
LANG_RBAC_PERM_REVOKED = 88,
LANG_RBAC_PERM_REVOKED_NOT_IN_LIST = 89,
LANG_RBAC_PERM_LIST_HEADER_GRANTED = 90,
LANG_RBAC_PERM_LIST_HEADER_DENIED = 91,
LANG_RBAC_PERM_LIST_GLOBAL = 92,
LANG_RBAC_LIST_GROUPS_HEADER = 93,
LANG_RBAC_LIST_ROLES_HEADER = 94,
LANG_RBAC_LIST_PERMISSIONS_HEADER = 95,
LANG_GUILD_RENAME_ALREADY_EXISTS = 96, LANG_GUILD_RENAME_ALREADY_EXISTS = 96,
LANG_GUILD_RENAME_DONE = 97, LANG_GUILD_RENAME_DONE = 97,
LANG_RENAME_PLAYER_ALREADY_EXISTS = 98, LANG_RENAME_PLAYER_ALREADY_EXISTS = 98,

View File

@@ -51,53 +51,19 @@ public:
ChatCommand* GetCommands() const ChatCommand* GetCommands() const
{ {
static ChatCommand rbacGroupsCommandTable[] = static ChatCommand rbacAccountCommandTable[] =
{
{ "add", rbac::RBAC_PERM_COMMAND_RBAC_ACC_GROUP_ADD, true, &HandleRBACGroupAddCommand, "", NULL },
{ "remove", rbac::RBAC_PERM_COMMAND_RBAC_ACC_GROUP_DEL, true, &HandleRBACGroupRemoveCommand, "", NULL },
{ "", rbac::RBAC_PERM_COMMAND_RBAC_ACC_GROUP, true, &HandleRBACGroupListCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand rbacRolesCommandTable[] =
{
{ "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_ROLE_GRANT, true, &HandleRBACRoleGrantCommand, "", NULL },
{ "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_ROLE_DENY, true, &HandleRBACRoleDenyCommand, "", NULL },
{ "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_ROLE_REVOKE, true, &HandleRBACRoleRevokeCommand, "", NULL },
{ "", rbac::RBAC_PERM_COMMAND_RBAC_ACC_ROLE, true, &HandleRBACRoleListCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand rbacPermsCommandTable[] =
{ {
{ "list", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, true, &HandleRBACPermListCommand, "", NULL },
{ "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "", NULL }, { "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "", NULL },
{ "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "", NULL }, { "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "", NULL },
{ "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "", NULL }, { "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "", NULL },
{ "", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM, true, &HandleRBACPermListCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand rbacListCommandTable[] =
{
{ "groups", rbac::RBAC_PERM_COMMAND_RBAC_LIST_GROUPS, true, &HandleRBACListGroupsCommand, "", NULL },
{ "roles", rbac::RBAC_PERM_COMMAND_RBAC_LIST_ROLES, true, &HandleRBACListRolesCommand, "", NULL },
{ "permissions", rbac::RBAC_PERM_COMMAND_RBAC_LIST_PERMS, true, &HandleRBACListPermissionsCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand rbacAccountCommandTable[] =
{
{ "group", rbac::RBAC_PERM_COMMAND_RBAC_ACC_GROUP, true, NULL, "", rbacGroupsCommandTable },
{ "role", rbac::RBAC_PERM_COMMAND_RBAC_ACC_ROLE, true, NULL, "", rbacRolesCommandTable },
{ "permission", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM, true, NULL, "", rbacPermsCommandTable },
{ "", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, &HandleRBACAccountPermissionCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
}; };
static ChatCommand rbacCommandTable[] = static ChatCommand rbacCommandTable[] =
{ {
{ "account", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, NULL, "", rbacAccountCommandTable }, { "account", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, NULL, "", rbacAccountCommandTable },
{ "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, NULL, "", rbacListCommandTable }, { "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, &HandleRBACListPermissionsCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
}; };
@@ -194,7 +160,7 @@ public:
if (!rdata) if (!rdata)
{ {
data->rbac = new rbac::RBACData(accountId, accountName, realmID); data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
data->rbac->LoadFromDB(); data->rbac->LoadFromDB();
data->needDelete = true; data->needDelete = true;
} }
@@ -206,258 +172,6 @@ public:
return data; return data;
} }
static bool HandleRBACGroupAddCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
rbac::RBACCommandResult result = command->rbac->AddGroup(command->id, command->realmId);
rbac::RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id);
switch (result)
{
case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
handler->PSendSysMessage(LANG_RBAC_GROUP_IN_LIST, command->id, group->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_GROUP_ADDED, command->id, group->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
break;
default:
break;
}
delete command;
return true;
}
static bool HandleRBACGroupRemoveCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
rbac::RBACCommandResult result = command->rbac->RemoveGroup(command->id, command->realmId);
rbac::RBACGroup const* group = sAccountMgr->GetRBACGroup(command->id);
switch (result)
{
case rbac::RBAC_CANT_REVOKE_NOT_IN_LIST:
handler->PSendSysMessage(LANG_RBAC_GROUP_NOT_IN_LIST, command->id, group->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_GROUP_REMOVED, command->id, group->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
break;
default:
break;
}
delete command;
return true;
}
static bool HandleRBACGroupListCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args, false);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage(LANG_RBAC_GROUP_LIST_HEADER, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACGroupContainer const& groups = command->rbac->GetGroups();
if (groups.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (rbac::RBACGroupContainer::const_iterator it = groups.begin(); it != groups.end(); ++it)
{
rbac::RBACGroup const* group = sAccountMgr->GetRBACGroup(*it);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
}
}
delete command;
return true;
}
static bool HandleRBACRoleGrantCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
rbac::RBACCommandResult result = command->rbac->GrantRole(command->id, command->realmId);
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
switch (result)
{
case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_LIST, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_IN_DENIED_LIST:
handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED_IN_DENIED_LIST, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_ROLE_GRANTED, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
break;
default:
break;
}
delete command;
return true;
}
static bool HandleRBACRoleDenyCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
rbac::RBACCommandResult result = command->rbac->DenyRole(command->id, command->realmId);
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
switch (result)
{
case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_LIST, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_IN_GRANTED_LIST:
handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED_IN_GRANTED_LIST, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_ROLE_DENIED, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
break;
default:
break;
}
delete command;
return true;
}
static bool HandleRBACRoleRevokeCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
rbac::RBACCommandResult result = command->rbac->RevokeRole(command->id, command->realmId);
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(command->id);
switch (result)
{
case rbac::RBAC_CANT_REVOKE_NOT_IN_LIST:
handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED_NOT_IN_LIST, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_ROLE_REVOKED, command->id, role->GetName().c_str(),
command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
break;
default:
break;
}
delete command;
return true;
}
static bool HandleRBACRoleListCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args, false);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACGroupContainer const& granted = command->rbac->GetGrantedRoles();
if (granted.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (rbac::RBACRoleContainer::const_iterator it = granted.begin(); it != granted.end(); ++it)
{
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(*it);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
}
}
handler->PSendSysMessage(LANG_RBAC_ROLE_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACGroupContainer const& denied = command->rbac->GetDeniedRoles();
if (denied.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (rbac::RBACRoleContainer::const_iterator it = denied.begin(); it != denied.end(); ++it)
{
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(*it);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
}
}
delete command;
return true;
}
static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args) static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args)
{ {
RBACCommandData* command = ReadParams(handler, args); RBACCommandData* command = ReadParams(handler, args);
@@ -581,61 +295,42 @@ public:
return false; return false;
} }
handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions(); rbac::RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions();
if (!granted.any()) if (granted.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else else
{ {
for (uint32 i = 0; i < rbac::RBAC_PERM_MAX; ++i) for (rbac::RBACPermissionContainer::const_iterator itr = granted.begin(); itr != granted.end(); ++itr)
if (granted.test(i)) {
{ rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); }
}
} }
handler->PSendSysMessage(LANG_RBAC_PERM_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions(); rbac::RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions();
if (!denied.any()) if (denied.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else else
{ {
for (uint32 i = 0; i < rbac::RBAC_PERM_MAX; ++i) for (rbac::RBACPermissionContainer::const_iterator itr = denied.begin(); itr != denied.end(); ++itr)
if (denied.test(i)) {
{ rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); }
}
} }
handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
delete command; rbac::RBACPermissionContainer const& default = sAccountMgr->GetRBACDefaultPermissions(command->rbac->GetSecurityLevel());
if (default.empty())
return true;
}
static bool HandleRBACAccountPermissionCommand(ChatHandler* handler, char const* args)
{
RBACCommandData* command = ReadParams(handler, args, false);
if (!command)
{
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage(LANG_RBAC_PERM_LIST_GLOBAL, command->rbac->GetId(), command->rbac->GetName().c_str());
rbac::RBACPermissionContainer const& permissions = command->rbac->GetPermissions();
if (!permissions.any())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else else
{ {
for (uint32 i = 0; i < rbac::RBAC_PERM_MAX; ++i) for (rbac::RBACPermissionContainer::const_iterator itr = default.begin(); itr != default.end(); ++itr)
if (permissions.test(i)) {
{ rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(i); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); }
}
} }
delete command; delete command;
@@ -643,97 +338,6 @@ public:
return true; return true;
} }
static bool HandleRBACListGroupsCommand(ChatHandler* handler, char const* args)
{
uint32 id = 0;
if (char* param1 = strtok((char*)args, " "))
id = atoi(param1);
if (!id)
{
rbac::RBACGroupsContainer const& groups = sAccountMgr->GetRBACGroupList();
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER));
for (rbac::RBACGroupsContainer::const_iterator it = groups.begin(); it != groups.end(); ++it)
{
rbac::RBACGroup const* group = it->second;
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
}
}
else
{
rbac::RBACGroup const* group = sAccountMgr->GetRBACGroup(id);
if (!group)
{
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_GROUPS_HEADER));
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, group->GetId(), group->GetName().c_str());
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
rbac::RBACRoleContainer const& roles = group->GetRoles();
if (roles.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (rbac::RBACRoleContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
{
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(*it);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
}
}
}
return true;
}
static bool HandleRBACListRolesCommand(ChatHandler* handler, char const* args)
{
uint32 id = 0;
if (char* param1 = strtok((char*)args, " "))
id = atoi(param1);
if (!id)
{
rbac::RBACRolesContainer const& roles = sAccountMgr->GetRBACRoleList();
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
for (rbac::RBACRolesContainer::const_iterator it = roles.begin(); it != roles.end(); ++it)
{
rbac::RBACRole const* role = it->second;
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
}
}
else
{
rbac::RBACRole const* role = sAccountMgr->GetRBACRole(id);
if (!role)
{
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_ROLES_HEADER));
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, role->GetId(), role->GetName().c_str());
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
rbac::RBACPermissionContainer const& permissions = role->GetPermissions();
if (!permissions.any())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (uint32 i = 0; i < rbac::RBAC_PERM_MAX; ++i)
if (permissions.test(i))
{
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(i);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
}
}
}
return true;
}
static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args) static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args)
{ {
uint32 id = 0; uint32 id = 0;
@@ -762,6 +366,11 @@ public:
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMS_LINKED_HEADER));
rbac::RBACPermissionContainer const& permissions = permission->GetLinkedPermissions();
for (rbac::RBACPermissionContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it)
if (rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*it))
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
} }
return true; return true;

View File

@@ -98,14 +98,6 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_GROUPS, "SELECT groupId FROM rbac_account_groups WHERE accountId = ? AND (realmId = ? OR realmId = -1) GROUP BY groupId", CONNECTION_SYNCH);
PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_GROUP, "INSERT INTO rbac_account_groups (accountId, groupId, realmId) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_GROUP, "DELETE FROM rbac_account_groups WHERE accountId = ? AND groupId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_ROLES, "SELECT roleId, granted FROM rbac_account_roles WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY roleId, realmId", CONNECTION_SYNCH);
PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_ROLE, "INSERT INTO rbac_account_roles (accountId, roleId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_ROLE, "DELETE FROM rbac_account_roles WHERE accountId = ? AND roleId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH);
PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC);

View File

@@ -117,12 +117,6 @@ enum LoginDatabaseStatements
LOGIN_GET_EMAIL_BY_ID, LOGIN_GET_EMAIL_BY_ID,
LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, LOGIN_SEL_ACCOUNT_ACCESS_BY_ID,
LOGIN_SEL_RBAC_ACCOUNT_GROUPS,
LOGIN_INS_RBAC_ACCOUNT_GROUP,
LOGIN_DEL_RBAC_ACCOUNT_GROUP,
LOGIN_SEL_RBAC_ACCOUNT_ROLES,
LOGIN_INS_RBAC_ACCOUNT_ROLE,
LOGIN_DEL_RBAC_ACCOUNT_ROLE,
LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS,
LOGIN_INS_RBAC_ACCOUNT_PERMISSION, LOGIN_INS_RBAC_ACCOUNT_PERMISSION,
LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, LOGIN_DEL_RBAC_ACCOUNT_PERMISSION,