19declare(strict_types=1);
71 if (self::$instance !==
null) {
76 return self::$instance =
$DIC[
'rbacsystem'];
78 throw new \LogicException(
79 'ilRbacSystem::getInstance() requires a bootstrapped $DIC[\'rbacsystem\']; '
80 .
'register a mock via $DIC[\'rbacsystem\'] in tests.'
89 self::$user_role_cache = [];
91 self::$_checkAccessOfUserCache = [];
111 public function checkAccess(
string $a_operations,
int $a_ref_id,
string $a_type =
""): bool
116 public function checkAccessOfUser(
int $a_user_id,
string $a_operations,
int $a_ref_id,
string $a_type =
""): bool
119 $cacheKey = $a_user_id .
':' . $a_operations .
':' . $a_ref_id .
':' . $a_type;
122 if (!is_array(self::$_checkAccessOfUserCache)) {
123 self::$_checkAccessOfUserCache = [];
126 if (array_key_exists($cacheKey, self::$_checkAccessOfUserCache)) {
127 return self::$_checkAccessOfUserCache[$cacheKey];
137 if (count(self::$_checkAccessOfUserCache) < self::MAX_CACHE_ENTRIES) {
138 self::$_checkAccessOfUserCache[$cacheKey] =
true;
150 if (count(self::$_checkAccessOfUserCache) < self::MAX_CACHE_ENTRIES) {
151 self::$_checkAccessOfUserCache[$cacheKey] =
true;
157 $paCacheKey = $a_user_id .
':' . $a_ref_id;
158 if (!is_array(self::$_paCache)) {
159 self::$_paCache = [];
162 if (array_key_exists($paCacheKey, self::$_paCache)) {
164 $ops = self::$_paCache[$paCacheKey];
167 $q =
"SELECT * FROM rbac_pa " .
168 "WHERE ref_id = " . $this->db->quote($a_ref_id,
'integer');
170 $r = $this->db->query($q);
174 if ($row->ops_id ===
':') {
177 if (in_array((
int) $row->rol_id, $roles)) {
178 $ops = array_merge($ops, unserialize(stripslashes($row->ops_id)));
182 if (count(self::$_paCache) < self::MAX_CACHE_ENTRIES) {
183 self::$_paCache[$paCacheKey] = $ops;
187 $operations = explode(
",", $a_operations);
188 foreach ($operations as $operation) {
189 if ($operation ==
"create") {
190 if (empty($a_type)) {
191 throw new DomainException(
192 'checkAccess(): ' .
"Expect a type definition for checking a 'create' permission"
199 if (!in_array($ops_id, (array) $ops)) {
200 if (count(self::$_checkAccessOfUserCache) < self::MAX_CACHE_ENTRIES) {
201 self::$_checkAccessOfUserCache[$cacheKey] =
false;
209 if (count(self::$_checkAccessOfUserCache) < self::MAX_CACHE_ENTRIES) {
211 self::$_checkAccessOfUserCache[$cacheKey] =
true;
220 foreach ($a_ref_ids as $ref_id) {
221 if (!isset(self::$_paCache[$a_user_id .
":" . $ref_id])) {
224 $ref_ids[] = $ref_id;
228 if ($ref_ids !== []) {
230 $q =
"SELECT * FROM rbac_pa " .
231 "WHERE " . $this->db->in(
"ref_id", $ref_ids,
false,
"integer");
233 $r = $this->db->query($q);
236 if ($row->ops_id ===
':') {
239 if (in_array($row->rol_id, $roles[(
int) $row->ref_id])) {
240 $ops[(
int) $row->ref_id] = array_merge(
241 $ops[(
int) $row->ref_id],
242 unserialize($row->ops_id)
246 foreach ($a_ref_ids as $ref_id) {
248 if (!isset(self::$_paCache[$a_user_id .
":" . $ref_id])) {
249 self::$_paCache[$a_user_id .
":" . $ref_id] = $ops[$ref_id];
258 public function checkPermission(
int $a_ref_id,
int $a_rol_id,
string $a_operation): bool
261 $query_rbac_operations =
'SELECT ops_id FROM rbac_operations ' .
262 'WHERE operation = ' . $this->db->quote($a_operation,
'text');
263 $res_rbac_operations = $this->db->query($query_rbac_operations);
265 while ($row = $this->db->fetchObject($res_rbac_operations)) {
266 $ops_id = (
int) $row->ops_id;
269 $query_rbac_pa =
"SELECT * FROM rbac_pa " .
270 "WHERE rol_id = " . $this->db->quote($a_rol_id,
'integer') .
" " .
271 "AND ref_id = " . $this->db->quote($a_ref_id,
'integer') .
" ";
272 $res_rbac_pa = $this->db->query($query_rbac_pa);
274 while ($row = $this->db->fetchObject($res_rbac_pa)) {
275 if ($row->ops_id ===
':') {
278 $ops = array_merge($ops, unserialize($row->ops_id));
280 return in_array($ops_id, $ops);
286 if (($this->mem_view[
'active'] ??
null) and $a_user_id == $this->
user->getId()) {
287 if (in_array($a_ref_id, $this->mem_view[
'items'])) {
288 return $a_operations;
292 if ($a_user_id != $this->
objectDataCache->lookupOwner($this->objectDataCache->lookupObjId($a_ref_id))) {
293 return $a_operations;
297 foreach (explode(
",", $a_operations) as $operation) {
298 if ($operation !=
'cat_administrate_users' &&
299 $operation !=
'edit_permission' &&
300 $operation !=
'edit_learning_progress' &&
301 $operation !=
'read_learning_progress' &&
302 !preg_match(
'/^create/', $operation) &&
303 $operation !=
'read_outcomes'
307 if (!strlen($new_ops)) {
308 $new_ops = $operation;
310 $new_ops .= (
',' . $operation);
323 if (isset($this->mem_view[
'active']) && $this->mem_view[
'active'] && $a_usr_id == $this->
user->getId()) {
325 if (in_array($a_ref_id, $this->mem_view[
'items']) && $this->mem_view[
'role']) {
327 return [$this->mem_view[
'role']];
331 if (isset(self::$user_role_cache[$a_usr_id]) and is_array(self::$user_role_cache)) {
332 return self::$user_role_cache[$a_usr_id];
334 return self::$user_role_cache[$a_usr_id] = $this->review->assignedRoles($a_usr_id);
340 $member_view_activation =
null;
341 if ($this->
http->wrapper()->query()->has(
'mv')) {
342 $member_view_activation = $this->
http->wrapper()->query()->retrieve(
348 if ($this->
http->wrapper()->query()->has(
'ref_id')) {
349 $ref_id = $this->
http->wrapper()->query()->retrieve(
354 if ($member_view_activation ===
true) {
356 $settings->toggleActivation($ref_id,
true);
360 if ($member_view_activation ===
false) {
361 $settings->toggleActivation($ref_id,
false);
364 $this->mem_view[
'active'] =
false;
365 $this->mem_view[
'items'] = [];
366 $this->mem_view[
'role'] = 0;
368 $this->mem_view[
'active'] =
true;
369 $this->mem_view[
'items'] = $this->tree->getSubTreeIds(
$settings->getContainer());
370 $this->mem_view[
'items'] = array_merge($this->mem_view[
'items'], [
$settings->getContainer()]);
377 if (!in_array($a_role_id, self::$user_role_cache[$a_usr_id])) {
378 self::$user_role_cache[$a_usr_id][] = $a_role_id;
384 $paCacheKey = $a_usr_id .
':' . $a_ref_id;
385 unset(self::$_paCache[$paCacheKey]);
403 $result = $this->db->queryF(
407 JOIN rbac_pa pa ON pa.ref_id = t.child
408 JOIN rbac_ua ua ON ua.rol_id = pa.rol_id AND ua.usr_id = %s
416 if ($row->ops_id !==
':') {
417 $ops = unserialize(stripslashes($row->ops_id));
418 if (in_array($read_id, $ops)) {
static getDefaultMemberRole(int $a_ref_id)
class ilRbacReview Contains Review functions of core Rbac.
static _getOperationIdByName(string $a_operation)
get operation id by name of operation
class ilRbacSystem system function like checkAccess, addActiveRole ... Supporting system functions ar...
__construct(private UserIdProviderProxy $user, private Connection $db, private ilRbacReview $review, private RepositoryTreeAccessProxy $tree, private GlobalHttpState $http, private Factory $refinery, private ObjectDataAccessProxy $objectDataCache)
Constructor.
addTemporaryRole(int $a_usr_id, int $a_role_id)
checkAccess(string $a_operations, int $a_ref_id, string $a_type="")
checkAccess represents the main method of the RBAC-system in ILIAS3 developers want to use With this ...
fetchAssignedRoles(int $a_usr_id, int $a_ref_id)
Fetch assigned roles This method caches the assigned roles per user.
static resetCaches()
Reset internal caches.
static array $user_role_cache
checkAccessOfUser(int $a_user_id, string $a_operations, int $a_ref_id, string $a_type="")
preloadRbacPaCache(array $a_ref_ids, int $a_user_id)
static array $_checkAccessOfUserCache
resetPACache(int $a_usr_id, int $a_ref_id)
hasAnyAdminReadPermission()
Check if the current user has read permission to any sub node of the system folder This is used by th...
static ilRbacSystem $instance
checkPermission(int $a_ref_id, int $a_rol_id, string $a_operation)
check if a specific role has the permission '$a_operation' of an object
filterOwnerPermissions(int $a_user_id, string $a_operations, int $a_ref_id)
Wrapper for the Setup to work, as they require a namespace.
Interface GlobalHttpState.
readonly HttpService $http
static http()
Fetches the global http state from ILIAS.
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.