/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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 .
*/
/* ScriptData
Name: rbac_commandscript
%Complete: 100
Comment: All role based access control related commands (including account related)
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "AccountMgr.h"
#include "Chat.h"
#include "ChatCommand.h"
#include "Config.h"
#include "Language.h"
#include "Player.h"
#include "RealmList.h"
#include "World.h"
#include "WorldSession.h"
struct RBACCommandData
{
RBACCommandData(rbac::RBACData* rbac_, bool needDelete_) : rbac(rbac_), needDelete(needDelete_) { }
RBACCommandData(RBACCommandData const&) = delete;
~RBACCommandData()
{
if (needDelete)
delete rbac;
}
rbac::RBACData* rbac = nullptr;
bool needDelete = false;
};
using namespace Trinity::ChatCommands;
class rbac_commandscript : public CommandScript
{
public:
rbac_commandscript() : CommandScript("rbac_commandscript") { }
ChatCommandTable GetCommands() const override
{
static ChatCommandTable rbacAccountCommandTable =
{
{ "list", HandleRBACPermListCommand, rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, Console::Yes },
{ "grant", HandleRBACPermGrantCommand, rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, Console::Yes },
{ "deny", HandleRBACPermDenyCommand, rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, Console::Yes },
{ "revoke", HandleRBACPermRevokeCommand, rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, Console::Yes },
};
static ChatCommandTable rbacCommandTable =
{
{ "account", rbacAccountCommandTable },
{ "list", HandleRBACListPermissionsCommand, rbac::RBAC_PERM_COMMAND_RBAC_LIST, Console::Yes },
};
static ChatCommandTable commandTable =
{
{ "rbac", rbacCommandTable },
};
return commandTable;
}
static RBACCommandData GetRBACData(AccountIdentifier account)
{
if (account.IsConnected())
return { account.GetConnectedSession()->GetRBACData(), false };
uint32 realmId = sRealmList->GetCurrentRealmId().Realm;
rbac::RBACData* rbac = new rbac::RBACData(account.GetID(), account.GetName(), realmId, AccountMgr::GetSecurity(account.GetID(), realmId));
rbac->LoadFromDB();
return { rbac, true };
}
static bool HandleRBACPermGrantCommand(ChatHandler* handler, Optional account, uint32 permId, Optional realmId)
{
if (!account)
account = AccountIdentifier::FromTarget(handler);
if (!account)
return false;
if (handler->HasLowerSecurityAccount(nullptr, account->GetID(), true))
return false;
if (!realmId)
realmId = -1;
RBACCommandData data = GetRBACData(*account);
rbac::RBACCommandResult result = data.rbac->GrantPermission(permId, *realmId);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(permId);
switch (result)
{
case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_IN_DENIED_LIST:
handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, permId);
break;
default:
break;
}
return true;
}
static bool HandleRBACPermDenyCommand(ChatHandler* handler, Optional account, uint32 permId, Optional realmId)
{
if (!account)
account = AccountIdentifier::FromTarget(handler);
if (!account)
return false;
if (handler->HasLowerSecurityAccount(nullptr, account->GetID(), true))
return false;
if (!realmId)
realmId = -1;
RBACCommandData data = GetRBACData(*account);
rbac::RBACCommandResult result = data.rbac->DenyPermission(permId, *realmId);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(permId);
switch (result)
{
case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_IN_GRANTED_LIST:
handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, permId);
break;
default:
break;
}
return true;
}
static bool HandleRBACPermRevokeCommand(ChatHandler* handler, Optional account, uint32 permId, Optional realmId)
{
if (!account)
account = AccountIdentifier::FromTarget(handler);
if (!account)
return false;
if (handler->HasLowerSecurityAccount(nullptr, account->GetID(), true))
return false;
if (!realmId)
realmId = -1;
RBACCommandData data = GetRBACData(*account);
rbac::RBACCommandResult result = data.rbac->RevokePermission(permId, *realmId);
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(permId);
switch (result)
{
case rbac::RBAC_CANT_REVOKE_NOT_IN_LIST:
handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_OK:
handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, permId, permission->GetName(),
*realmId, account->GetID(), account->GetName());
break;
case rbac::RBAC_ID_DOES_NOT_EXISTS:
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, permId);
break;
default:
break;
}
return true;
}
static bool HandleRBACPermListCommand(ChatHandler* handler, Optional account)
{
if (!account)
account = AccountIdentifier::FromTarget(handler);
if (!account)
return false;
RBACCommandData data = GetRBACData(*account);
handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_GRANTED, data.rbac->GetId(), data.rbac->GetName());
rbac::RBACPermissionContainer const& granted = data.rbac->GetGrantedPermissions();
if (granted.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (uint32 grantedId : granted)
{
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(grantedId);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName());
}
}
handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_DENIED, data.rbac->GetId(), data.rbac->GetName());
rbac::RBACPermissionContainer const& denied = data.rbac->GetDeniedPermissions();
if (denied.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (uint32 deniedId : denied)
{
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(deniedId);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName());
}
}
handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_BY_SEC_LEVEL, data.rbac->GetId(), data.rbac->GetName(), data.rbac->GetSecurityLevel());
rbac::RBACPermissionContainer const& defaultPermissions = sAccountMgr->GetRBACDefaultPermissions(data.rbac->GetSecurityLevel());
if (defaultPermissions.empty())
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
else
{
for (uint32 defaultPermission : defaultPermissions)
{
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(defaultPermission);
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName());
}
}
return true;
}
static bool HandleRBACListPermissionsCommand(ChatHandler* handler, Optional permId)
{
if (!permId)
{
rbac::RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList();
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
for (auto const& [_, permission] : permissions)
{
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName());
}
}
else
{
rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*permId);
if (!permission)
{
handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, *permId);
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName());
handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMS_LINKED_HEADER));
for (uint32 linkedPerm : permission->GetLinkedPermissions())
if (rbac::RBACPermission const* rbacPermission = sAccountMgr->GetRBACPermission(linkedPerm))
handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, rbacPermission->GetId(), rbacPermission->GetName());
}
return true;
}
};
void AddSC_rbac_commandscript()
{
new rbac_commandscript();
}