TrinityCore
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 "DatabaseEnv.h"
21#include "Log.h"
22#include <sstream>
23
24namespace rbac
25{
26
28{
29 std::string str = "";
30 if (!perms.empty())
31 {
32 std::ostringstream o;
33 RBACPermissionContainer::const_iterator itr = perms.begin();
34 o << (*itr);
35 for (++itr; itr != perms.end(); ++itr)
36 o << ", " << uint32(*itr);
37 str = o.str();
38 }
39
40 return str;
41}
42
44{
45 // Check if permission Id exists
46 RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
47 if (!perm)
48 {
49 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission does not exists",
50 GetId(), GetName(), permissionId, realmId);
52 }
53
54 // Check if already added in denied list
55 if (HasDeniedPermission(permissionId))
56 {
57 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission in deny list",
58 GetId(), GetName(), permissionId, realmId);
60 }
61
62 // Already added?
63 if (HasGrantedPermission(permissionId))
64 {
65 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission already granted",
66 GetId(), GetName(), permissionId, realmId);
68 }
69
70 AddGrantedPermission(permissionId);
71
72 // Do not save to db when loading data from DB (realmId = 0)
73 if (realmId)
74 {
75 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
76 GetId(), GetName(), permissionId, realmId);
77 SavePermission(permissionId, true, realmId);
79 }
80 else
81 TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
82 GetId(), GetName(), permissionId, realmId);
83
84 return RBAC_OK;
85}
86
88{
89 // Check if permission Id exists
90 RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
91 if (!perm)
92 {
93 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission does not exists",
94 GetId(), GetName(), permissionId, realmId);
96 }
97
98 // Check if already added in granted list
99 if (HasGrantedPermission(permissionId))
100 {
101 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission in grant list",
102 GetId(), GetName(), permissionId, realmId);
104 }
105
106 // Already added?
107 if (HasDeniedPermission(permissionId))
108 {
109 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Permission already denied",
110 GetId(), GetName(), permissionId, realmId);
112 }
113
114 AddDeniedPermission(permissionId);
115
116 // Do not save to db when loading data from DB (realmId = 0)
117 if (realmId)
118 {
119 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
120 GetId(), GetName(), permissionId, realmId);
121 SavePermission(permissionId, false, realmId);
123 }
124 else
125 TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
126 GetId(), GetName(), permissionId, realmId);
127
128 return RBAC_OK;
129}
130
131void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
132{
134 stmt->setUInt32(0, GetId());
135 stmt->setUInt32(1, permission);
136 stmt->setBool(2, granted);
137 stmt->setInt32(3, realmId);
138 LoginDatabase.Execute(stmt);
139}
140
142{
143 // Check if it's present in any list
144 if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId))
145 {
146 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Not granted or revoked",
147 GetId(), GetName(), permissionId, realmId);
149 }
150
151 RemoveGrantedPermission(permissionId);
152 RemoveDeniedPermission(permissionId);
153
154 // Do not save to db when loading data from DB (realmId = 0)
155 if (realmId)
156 {
157 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok and DB updated",
158 GetId(), GetName(), permissionId, realmId);
160 stmt->setUInt32(0, GetId());
161 stmt->setUInt32(1, permissionId);
162 stmt->setInt32(2, realmId);
163 LoginDatabase.Execute(stmt);
164
166 }
167 else
168 TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: {} Name: {}] (Permission {}, RealmId {}). Ok",
169 GetId(), GetName(), permissionId, realmId);
170
171 return RBAC_OK;
172}
173
175{
176 ClearData();
177
178 TC_LOG_DEBUG("rbac", "RBACData::LoadFromDB [Id: {} Name: {}]: Loading permissions", GetId(), GetName());
179 // Load account permissions (granted and denied) that affect current realm
181 stmt->setUInt32(0, GetId());
182 stmt->setInt32(1, GetRealmId());
183
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
197 return LoginDatabase.AsyncQuery(stmt);
198}
199
201{
202 if (result)
203 {
204 do
205 {
206 Field* fields = result->Fetch();
207 if (fields[1].GetBool())
208 GrantPermission(fields[0].GetUInt32());
209 else
210 DenyPermission(fields[0].GetUInt32());
211 } while (result->NextRow());
212 }
213
214 // Add default permissions
215 RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel);
216 for (uint32 permission : permissions)
217 GrantPermission(permission);
218
219 // Force calculation of permissions
221}
222
224{
225 TC_LOG_TRACE("rbac", "RBACData::CalculateNewPermissions [Id: {} Name: {}]", GetId(), GetName());
226
227 // Get the list of granted permissions
231 ExpandPermissions(revoked);
233}
234
236{
237 for (uint32 permission : permsFrom)
238 permsTo.insert(permission);
239}
240
242{
243 for (uint32 permission: permsToRemove)
244 permsFrom.erase(permission);
245}
246
248{
249 RBACPermissionContainer toCheck = permissions;
250 permissions.clear();
251
252 while (!toCheck.empty())
253 {
254 // remove the permission from original list
255 uint32 permissionId = *toCheck.begin();
256 toCheck.erase(toCheck.begin());
257
258 RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId);
259 if (!permission)
260 continue;
261
262 // insert into the final list (expanded list)
263 permissions.insert(permissionId);
264
265 // add all linked permissions (that are not already expanded) to the list of permissions to be checked
266 RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions();
267 for (uint32 linkedPerm : linkedPerms)
268 if (permissions.find(linkedPerm) == permissions.end())
269 toCheck.insert(linkedPerm);
270 }
271
272 TC_LOG_DEBUG("rbac", "RBACData::ExpandPermissions: Expanded: {}", GetDebugPermissionString(permissions));
273}
274
276{
277 _grantedPerms.clear();
278 _deniedPerms.clear();
279 _globalPerms.clear();
280}
281
282}
#define sAccountMgr
Definition: AccountMgr.h:98
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:153
@ 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:90
void setInt32(const uint8 index, const int32 value)
void setBool(const uint8 index, const bool value)
void setUInt32(const uint8 index, const uint32 value)
RBACPermissionContainer const & GetDeniedPermissions() const
Returns all the denied permissions.
Definition: RBAC.h:845
RBACCommandResult GrantPermission(uint32 permissionId, int32 realmId=0)
Definition: RBAC.cpp:43
void AddDeniedPermission(uint32 permissionId)
Adds a new denied permission.
Definition: RBAC.h:981
int32 GetRealmId() const
Definition: RBAC.h:951
RBACPermissionContainer _grantedPerms
‍Account SecurityLevel
Definition: RBAC.h:1011
void AddGrantedPermission(uint32 permissionId)
Adds a new granted permission.
Definition: RBAC.h:969
void ExpandPermissions(RBACPermissionContainer &permissions)
Definition: RBAC.cpp:247
bool HasDeniedPermission(uint32 permissionId) const
Checks if a permission is denied.
Definition: RBAC.h:963
uint32 GetId() const
Gets the Id of the Object.
Definition: RBAC.h:816
void AddPermissions(RBACPermissionContainer const &permsFrom, RBACPermissionContainer &permsTo)
Adds a list of permissions to another list.
Definition: RBAC.cpp:235
void SavePermission(uint32 role, bool granted, int32 realm)
Saves a permission to DB, Granted or Denied.
Definition: RBAC.cpp:131
QueryCallback LoadFromDBAsync()
Definition: RBAC.cpp:187
void ClearData()
Clears roles, groups and permissions - Used for reload.
Definition: RBAC.cpp:275
RBACPermissionContainer _globalPerms
‍Denied permissions
Definition: RBAC.h:1013
RBACPermissionContainer const & GetGrantedPermissions() const
Returns all the granted permissions.
Definition: RBAC.h:843
RBACPermissionContainer _deniedPerms
‍Granted permissions
Definition: RBAC.h:1012
void CalculateNewPermissions()
Definition: RBAC.cpp:223
RBACCommandResult DenyPermission(uint32 permissionId, int32 realmId=0)
Definition: RBAC.cpp:87
bool HasGrantedPermission(uint32 permissionId) const
Checks if a permission is granted.
Definition: RBAC.h:957
uint8 _secLevel
‍RealmId Affected
Definition: RBAC.h:1010
std::string const & GetName() const
Gets the Name of the Object.
Definition: RBAC.h:814
void RemoveDeniedPermission(uint32 permissionId)
Removes a denied permission.
Definition: RBAC.h:987
void RemoveGrantedPermission(uint32 permissionId)
Removes a granted permission.
Definition: RBAC.h:975
RBACCommandResult RevokePermission(uint32 permissionId, int32 realmId=0)
Definition: RBAC.cpp:141
void LoadFromDB()
Loads all permissions assigned to current account.
Definition: RBAC.cpp:174
void RemovePermissions(RBACPermissionContainer &permsFrom, RBACPermissionContainer const &permsToRemove)
Removes a list of permissions from another list.
Definition: RBAC.cpp:241
void LoadFromDBCallback(PreparedQueryResult result)
Definition: RBAC.cpp:200
RBACPermissionContainer const & GetLinkedPermissions() const
Gets the Permissions linked to this permission.
Definition: RBAC.h:783
std::string GetDebugPermissionString(RBACPermissionContainer const &perms)
Definition: RBAC.cpp:27
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