TrinityCore
Loading...
Searching...
No Matches
RBAC.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "RBAC.h"
19#include "AccountMgr.h"
20#include "Common.h"
21#include "DatabaseEnv.h"
22#include "Log.h"
23#include <fmt/ranges.h>
24
25namespace rbac
26{
27
29{
30 return Trinity::StringFormat("{}", fmt::join(perms, ", "sv));
31}
32
33RBACPermission::RBACPermission(uint32 id, std::string const& name):
34 _id(id), _name(name), _perms()
35{
36}
37
39RBACPermission::RBACPermission(RBACPermission&& other) noexcept = default;
43
44RBACData::RBACData(uint32 id, std::string const& name, int32 realmId, uint8 secLevel):
45 _id(id), _name(name), _realmId(realmId), _secLevel(secLevel),
46 _grantedPerms(), _deniedPerms(), _globalPerms()
47{
48}
49
50RBACData::RBACData(RBACData const& other) = default;
51RBACData::RBACData(RBACData&& other) noexcept = default;
52RBACData& RBACData::operator=(RBACData const& right) = default;
53RBACData& RBACData::operator=(RBACData&& right) noexcept = default;
54RBACData::~RBACData() = default;
55
57{
58 // Check if permission Id exists
59 RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
60 if (!perm)
61 {
62 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission does not exists",
63 GetId(), GetName(), permissionId, realmId);
65 }
66
67 // Check if already added in denied list
68 if (HasDeniedPermission(permissionId))
69 {
70 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission in deny list",
71 GetId(), GetName(), permissionId, realmId);
73 }
74
75 // Already added?
76 if (HasGrantedPermission(permissionId))
77 {
78 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission already granted",
79 GetId(), GetName(), permissionId, realmId);
81 }
82
83 AddGrantedPermission(permissionId);
84
85 // Do not save to db when loading data from DB (realmId = 0)
86 if (realmId)
87 {
88 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
89 GetId(), GetName(), permissionId, realmId);
90 SavePermission(permissionId, true, realmId);
92 }
93 else
94 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
95 GetId(), GetName(), permissionId, realmId);
96
97 return RBAC_OK;
98}
99
101{
102 // Check if permission Id exists
103 RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
104 if (!perm)
105 {
106 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission does not exists",
107 GetId(), GetName(), permissionId, realmId);
109 }
110
111 // Check if already added in granted list
112 if (HasGrantedPermission(permissionId))
113 {
114 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission in grant list",
115 GetId(), GetName(), permissionId, realmId);
117 }
118
119 // Already added?
120 if (HasDeniedPermission(permissionId))
121 {
122 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission already denied",
123 GetId(), GetName(), permissionId, realmId);
125 }
126
127 AddDeniedPermission(permissionId);
128
129 // Do not save to db when loading data from DB (realmId = 0)
130 if (realmId)
131 {
132 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
133 GetId(), GetName(), permissionId, realmId);
134 SavePermission(permissionId, false, realmId);
136 }
137 else
138 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
139 GetId(), GetName(), permissionId, realmId);
140
141 return RBAC_OK;
142}
143
144void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
145{
147 stmt->setUInt32(0, GetId());
148 stmt->setUInt32(1, permission);
149 stmt->setBool(2, granted);
150 stmt->setInt32(3, realmId);
151 LoginDatabase.Execute(stmt);
152}
153
155{
156 // Check if it's present in any list
157 if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId))
158 {
159 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Not granted or revoked",
160 GetId(), GetName(), permissionId, realmId);
162 }
163
164 RemoveGrantedPermission(permissionId);
165 RemoveDeniedPermission(permissionId);
166
167 // Do not save to db when loading data from DB (realmId = 0)
168 if (realmId)
169 {
170 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
171 GetId(), GetName(), permissionId, realmId);
173 stmt->setUInt32(0, GetId());
174 stmt->setUInt32(1, permissionId);
175 stmt->setInt32(2, realmId);
176 LoginDatabase.Execute(stmt);
177
179 }
180 else
181 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
182 GetId(), GetName(), permissionId, realmId);
183
184 return RBAC_OK;
185}
186
188{
189 ClearData();
190
191 TC_LOG_DEBUG("rbac", "RBACData::LoadFromDB [Id: {} Name: {}]: Loading permissions", GetId(), GetName());
192 // Load account permissions (granted and denied) that affect current realm
194 stmt->setUInt32(0, GetId());
195 stmt->setInt32(1, GetRealmId());
196
198}
199
201{
202 ClearData();
203
204 TC_LOG_DEBUG("rbac", "RBACData::LoadFromDB [Id: {} Name: {}]: Loading permissions", GetId(), GetName());
205 // Load account permissions (granted and denied) that affect current realm
207 stmt->setUInt32(0, GetId());
208 stmt->setInt32(1, GetRealmId());
209
210 return LoginDatabase.AsyncQuery(stmt);
211}
212
214{
215 if (result)
216 {
217 do
218 {
219 Field* fields = result->Fetch();
220 if (fields[1].GetBool())
221 GrantPermission(fields[0].GetUInt32());
222 else
223 DenyPermission(fields[0].GetUInt32());
224 } while (result->NextRow());
225 }
226
227 // Add default permissions
228 RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel);
229 for (uint32 permission : permissions)
230 GrantPermission(permission);
231
232 // Force calculation of permissions
234}
235
237{
238 TC_LOG_TRACE("rbac", "RBACData::CalculateNewPermissions [Id: {} Name: {}]", GetId(), GetName());
239
240 // Get the list of granted permissions
244 ExpandPermissions(revoked);
246}
247
249{
250 for (uint32 permission : permsFrom)
251 permsTo.insert(permission);
252}
253
255{
256 for (uint32 permission: permsToRemove)
257 permsFrom.erase(permission);
258}
259
261{
262 RBACPermissionContainer toCheck = permissions;
263 permissions.clear();
264
265 while (!toCheck.empty())
266 {
267 // remove the permission from original list
268 uint32 permissionId = *toCheck.begin();
269 toCheck.erase(toCheck.begin());
270
271 RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId);
272 if (!permission)
273 continue;
274
275 // insert into the final list (expanded list)
276 permissions.insert(permissionId);
277
278 // add all linked permissions (that are not already expanded) to the list of permissions to be checked
279 RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions();
280 for (uint32 linkedPerm : linkedPerms)
281 if (permissions.find(linkedPerm) == permissions.end())
282 toCheck.insert(linkedPerm);
283 }
284
285 TC_LOG_DEBUG("rbac", "RBACData::ExpandPermissions: Expanded: {}", GetDebugPermissionString(permissions));
286}
287
289{
290 _grantedPerms.clear();
291 _deniedPerms.clear();
292 _globalPerms.clear();
293}
294
295}
#define sAccountMgr
Definition AccountMgr.h:104
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_TRACE(filterType__, message__,...)
Definition Log.h:178
@ LOGIN_DEL_RBAC_ACCOUNT_PERMISSION
@ LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS
@ LOGIN_INS_RBAC_ACCOUNT_PERMISSION
Role Based Access Control related classes definition.
Class used to access individual fields of database query result.
Definition Field.h:94
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setInt32(uint8 index, int32 value)
RBACPermissionContainer const & GetDeniedPermissions() const
Returns all the denied permissions.
Definition RBAC.h:852
RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId=0)
Definition RBAC.cpp:56
void AddDeniedPermission(uint32 permissionId)
Adds a new denied permission.
Definition RBAC.h:988
int32 GetRealmId() const
Definition RBAC.h:958
RBACPermissionContainer _grantedPerms
‍Account SecurityLevel
Definition RBAC.h:1018
void AddGrantedPermission(uint32 permissionId)
Adds a new granted permission.
Definition RBAC.h:976
void ExpandPermissions(RBACPermissionContainer &permissions)
Definition RBAC.cpp:260
bool HasDeniedPermission(uint32 permissionId) const
Checks if a permission is denied.
Definition RBAC.h:970
uint32 GetId() const
Gets the Id of the Object.
Definition RBAC.h:823
void AddPermissions(RBACPermissionContainer const &permsFrom, RBACPermissionContainer &permsTo)
Adds a list of permissions to another list.
Definition RBAC.cpp:248
void SavePermission(uint32 role, bool granted, int32 realm)
Saves a permission to DB, Granted or Denied.
Definition RBAC.cpp:144
QueryCallback LoadFromDBAsync()
Definition RBAC.cpp:200
RBACData(uint32 id, std::string const &name, int32 realmId, uint8 secLevel=255)
Definition RBAC.cpp:44
void ClearData()
Clears roles, groups and permissions - Used for reload.
Definition RBAC.cpp:288
RBACPermissionContainer _globalPerms
‍Denied permissions
Definition RBAC.h:1020
RBACPermissionContainer const & GetGrantedPermissions() const
Returns all the granted permissions.
Definition RBAC.h:850
RBACPermissionContainer _deniedPerms
‍Granted permissions
Definition RBAC.h:1019
void CalculateNewPermissions()
Definition RBAC.cpp:236
RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId=0)
Definition RBAC.cpp:100
bool HasGrantedPermission(uint32 permissionId) const
Checks if a permission is granted.
Definition RBAC.h:964
uint8 _secLevel
‍RealmId Affected
Definition RBAC.h:1017
RBACData & operator=(RBACData const &right)
std::string const & GetName() const
Gets the Name of the Object.
Definition RBAC.h:821
void RemoveDeniedPermission(uint32 permissionId)
Removes a denied permission.
Definition RBAC.h:994
void RemoveGrantedPermission(uint32 permissionId)
Removes a granted permission.
Definition RBAC.h:982
RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId=0)
Definition RBAC.cpp:154
void LoadFromDB()
Loads all permissions assigned to current account.
Definition RBAC.cpp:187
void RemovePermissions(RBACPermissionContainer &permsFrom, RBACPermissionContainer const &permsToRemove)
Removes a list of permissions from another list.
Definition RBAC.cpp:254
void LoadFromDBCallback(PreparedQueryResult result)
Definition RBAC.cpp:213
RBACPermissionContainer const & GetLinkedPermissions() const
Gets the Permissions linked to this permission.
Definition RBAC.h:787
RBACPermission(uint32 id=0, std::string const &name="")
Definition RBAC.cpp:33
RBACPermission & operator=(RBACPermission const &right)
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
std::string GetDebugPermissionString(RBACPermissionContainer const &perms)
Definition RBAC.cpp:28
RBACCommandResult
Definition RBAC.h:760
@ RBAC_OK
Definition RBAC.h:761
@ RBAC_CANT_ADD_ALREADY_ADDED
Definition RBAC.h:762
@ RBAC_IN_GRANTED_LIST
Definition RBAC.h:764
@ RBAC_ID_DOES_NOT_EXISTS
Definition RBAC.h:766
@ RBAC_IN_DENIED_LIST
Definition RBAC.h:765
@ RBAC_CANT_REVOKE_NOT_IN_LIST
Definition RBAC.h:763
std::set< uint32 > RBACPermissionContainer
Definition RBAC.h:769