ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilRbacAdmin.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
32{
33 protected ilDBInterface $db;
35 protected ilLogger $logger;
36
41 public function __construct()
42 {
43 global $DIC;
44
45 $this->db = $DIC->database();
46 $this->rbacreview = $DIC->rbac()->review();
47 $this->logger = $DIC->logger()->ac();
48 }
49
50 public function setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status): void
51 {
52 ilLoggerFactory::getLogger('crs')->logStack();
53 $query = 'UPDATE rbac_fa set blocked = ' . $this->db->quote($a_blocked_status, 'integer') . ' ' .
54 'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
55 'AND parent = ' . $this->db->quote($a_ref_id, 'integer');
56 $this->db->manipulate($query);
57 }
58
63 public function removeUser(int $a_usr_id): void
64 {
65 foreach ($this->rbacreview->assignedRoles($a_usr_id) as $role_id) {
66 $this->deassignUser($role_id, $a_usr_id);
67 }
68 $query = "DELETE FROM rbac_ua WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer');
69 $res = $this->db->manipulate($query);
70 }
71
75 public function deleteRole(int $a_rol_id, int $a_ref_id): void
76 {
77 if ($a_rol_id == SYSTEM_ROLE_ID) {
78 $this->logger->logStack(ilLogLevel::DEBUG);
79 throw new DomainException('System administrator role is not deletable.');
80 }
81
83 $mapping->deleteRole($a_rol_id);
84
85 // TODO: check assigned users before deletion
86 // This is done in ilObjRole. Should be better moved to this place?
87
88 // delete user assignements
89 $query = "DELETE FROM rbac_ua " .
90 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer');
91 $res = $this->db->manipulate($query);
92
93 // delete permission assignments
94 $query = "DELETE FROM rbac_pa " .
95 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
96 $res = $this->db->manipulate($query);
97
98 //delete rbac_templates and rbac_fa
99 $this->deleteLocalRole($a_rol_id);
100 }
101
105 public function deleteTemplate(int $a_obj_id): void
106 {
107 $query = 'DELETE FROM rbac_templates ' .
108 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
109 $res = $this->db->manipulate($query);
110
111 $query = 'DELETE FROM rbac_fa ' .
112 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
113 $res = $this->db->manipulate($query);
114 }
115
119 public function deleteLocalRole(int $a_rol_id, int $a_ref_id = 0): void
120 {
121 // exclude system role from rbac
122 if ($a_rol_id == SYSTEM_ROLE_ID) {
123 $this->logger->logStack(ilLogLevel::NOTICE);
124 $this->logger->notice('System administrator role is not deletable.');
125 return;
126 }
127
128 $clause = '';
129 if ($a_ref_id != 0) {
130 $clause = 'AND parent = ' . $this->db->quote($a_ref_id, 'integer') . ' ';
131 }
132
133 $query = 'DELETE FROM rbac_fa ' .
134 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
135 $clause;
136 $res = $this->db->manipulate($query);
137
138 $query = 'DELETE FROM rbac_templates ' .
139 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
140 $clause;
141 $res = $this->db->manipulate($query);
142 }
143
144 public function assignUserLimited(
145 int $a_role_id,
146 int $a_usr_id,
147 int $a_limit,
148 array $a_limited_roles = []
149 ): bool {
150 $ilDB = $this->db;
151 $ilAtomQuery = $this->db->buildAtomQuery();
152 $ilAtomQuery->addTableLock('rbac_ua');
153 $ilAtomQuery->addQueryCallable(
154 function (ilDBInterface $ilDB) use (&$ret, $a_role_id, $a_usr_id, $a_limit, $a_limited_roles): void {
155 $ret = true;
156 $limit_query = 'SELECT COUNT(*) num FROM rbac_ua ' .
157 'WHERE ' . $ilDB->in('rol_id', (array) $a_limited_roles, false, 'integer');
158 $res = $ilDB->query($limit_query);
159 $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
160 if ($row->num >= $a_limit) {
161 $ret = false;
162 return;
163 }
164
165 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
166 "VALUES (" .
167 $ilDB->quote($a_usr_id, 'integer') . "," . $ilDB->quote($a_role_id, 'integer') .
168 ")";
169 $res = $ilDB->manipulate($query);
170 }
171 );
172 $ilAtomQuery->run();
173
174 if (!$ret) {
175 return false;
176 }
177
178 $this->rbacreview->setAssignedCacheEntry($a_role_id, $a_usr_id, true);
180 $mapping->assign($a_role_id, $a_usr_id);
181
182 return true;
183 }
184
188 public function assignUser(int $a_rol_id, int $a_usr_id): void
189 {
190 // check if already assigned user id and role_id
191 $alreadyAssigned = $this->rbacreview->isAssigned($a_usr_id, $a_rol_id);
192
193 // enhanced: only if we haven't had this role for this user
194 if (!$alreadyAssigned) {
195 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
196 "VALUES (" . $this->db->quote($a_usr_id, 'integer') . "," . $this->db->quote(
197 $a_rol_id,
198 'integer'
199 ) . ")";
200 $res = $this->db->manipulate($query);
201
202 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, true);
203 }
204
206 $mapping->assign($a_rol_id, $a_usr_id);
207
208 $ref_id = $this->rbacreview->getObjectReferenceOfRole($a_rol_id);
210 $type = ilObject::_lookupType($obj_id);
211
212 if (!$alreadyAssigned) {
213 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event assign user');
214 $GLOBALS['DIC']['ilAppEventHandler']->raise(
215 'components/ILIAS/AccessControl',
216 'assignUser',
217 [
218 'obj_id' => $obj_id,
219 'usr_id' => $a_usr_id,
220 'role_id' => $a_rol_id,
221 'type' => $type
222 ]
223 );
224 }
225 }
226
230 public function deassignUser(int $a_rol_id, int $a_usr_id): void
231 {
232 $query = "DELETE FROM rbac_ua " .
233 "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . " " .
234 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
235 $res = $this->db->manipulate($query);
236
237 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, false);
238
240 $mapping->deassign($a_rol_id, $a_usr_id);
241
242 if ($res) {
243 $ref_id = $GLOBALS['DIC']['rbacreview']->getObjectReferenceOfRole($a_rol_id);
245 $type = ilObject::_lookupType($obj_id);
246
247 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event deassign user');
248 $GLOBALS['DIC']['ilAppEventHandler']->raise('components/ILIAS/AccessControl', 'deassignUser', [
249 'obj_id' => $obj_id,
250 'usr_id' => $a_usr_id,
251 'role_id' => $a_rol_id,
252 'type' => $type,
253 ]);
254 }
255 }
256
260 public function grantPermission(int $a_rol_id, array $a_ops, int $a_ref_id): void
261 {
262 // exclude system role from rbac
263 if ($a_rol_id == SYSTEM_ROLE_ID) {
264 $this->logger->logStack(ilLogLevel::DEBUG);
265 return;
266 }
267
268 // convert all values to integer
269 foreach ($a_ops as $key => $operation) {
270 $a_ops[$key] = (int) $operation;
271 }
272
273 $ops_ids = serialize($a_ops);
274
275 $query = 'DELETE FROM rbac_pa ' .
276 'WHERE rol_id = %s ' .
277 'AND ref_id = %s';
278 $res = $this->db->queryF(
279 $query,
280 ['integer', 'integer'],
281 [$a_rol_id, $a_ref_id]
282 );
283
284 if ($a_ops === []) {
285 return;
286 }
287
288 $query = "INSERT INTO rbac_pa (rol_id,ops_id,ref_id) " .
289 "VALUES " .
290 "(" . $this->db->quote($a_rol_id, 'integer') . "," . $this->db->quote(
291 $ops_ids,
292 'text'
293 ) . "," . $this->db->quote($a_ref_id, 'integer') . ")";
294 $res = $this->db->manipulate($query);
295 }
296
302 public function revokePermission(int $a_ref_id, int $a_rol_id = 0, bool $a_keep_protected = true): void
303 {
304 if ($a_rol_id == SYSTEM_ROLE_ID) {
305 $this->logger->logStack(ilLogLevel::DEBUG);
306 return;
307 }
308
309 // bypass protected status of roles
310 if ($a_keep_protected != true) {
311 if ($a_rol_id) {
312 $and1 = " AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
313 } else {
314 $and1 = "";
315 }
316
317 $query = "DELETE FROM rbac_pa " .
318 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') .
319 $and1;
320 $res = $this->db->manipulate($query);
321 return;
322 }
323
324 // consider protected status of roles
325
326 // in any case, get all roles in scope first
327 $roles_in_scope = $this->rbacreview->getParentRoleIds($a_ref_id);
328
329 if (!$a_rol_id) {
330 $role_ids = [];
331
332 foreach ($roles_in_scope as $role) {
333 if ($role['protected'] == true) {
334 continue;
335 }
336
337 $role_ids[] = $role['obj_id'];
338 }
339
340 // return if no role in array
341 if ($role_ids === []) {
342 return;
343 }
344
345 $query = 'DELETE FROM rbac_pa ' .
346 'WHERE ' . $this->db->in('rol_id', $role_ids, false, 'integer') . ' ' .
347 'AND ref_id = ' . $this->db->quote($a_ref_id, 'integer');
348 $res = $this->db->manipulate($query);
349 } else {
350 // exclude protected permission settings from revoking
351 if ($roles_in_scope[$a_rol_id]['protected'] == true) {
352 return;
353 }
354
355 $query = "DELETE FROM rbac_pa " .
356 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') . " " .
357 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
358 $res = $this->db->manipulate($query);
359 }
360 }
361
365 public function revokeSubtreePermissions(int $a_ref_id, int $a_role_id): void
366 {
367 $query = 'DELETE FROM rbac_pa ' .
368 'WHERE ref_id IN ' .
369 '( ' . $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
370 'AND rol_id = ' . $this->db->quote($a_role_id, 'integer');
371
372 $this->db->manipulate($query);
373 }
374
378 public function deleteSubtreeTemplates(int $a_ref_id, int $a_rol_id): void
379 {
380 $query = 'DELETE FROM rbac_templates ' .
381 'WHERE parent IN ( ' .
382 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
383 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
384
385 $this->db->manipulate($query);
386
387 $query = 'DELETE FROM rbac_fa ' .
388 'WHERE parent IN ( ' .
389 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
390 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
391
392 $this->db->manipulate($query);
393 }
394
398 public function revokePermissionList(array $a_ref_ids, int $a_rol_id): void
399 {
400 // exclude system role from rbac
401 if ($a_rol_id == SYSTEM_ROLE_ID) {
402 $this->logger->logStack(ilLogLevel::DEBUG);
403 return;
404 }
405 $query = "DELETE FROM rbac_pa " .
406 "WHERE " . $this->db->in('ref_id', $a_ref_ids, false, 'integer') . ' ' .
407 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer');
408 $res = $this->db->manipulate($query);
409 }
410
414 public function copyRolePermissions(
415 int $a_source_id,
416 int $a_source_parent,
417 int $a_dest_parent,
418 int $a_dest_id,
419 bool $a_consider_protected = true
420 ): void {
421 // Copy template permissions
422 $this->copyRoleTemplatePermissions(
423 $a_source_id,
424 $a_source_parent,
425 $a_dest_parent,
426 $a_dest_id,
427 $a_consider_protected
428 );
429 $ops = $this->rbacreview->getRoleOperationsOnObject($a_source_id, $a_source_parent);
430
431 $this->revokePermission($a_dest_parent, $a_dest_id);
432 $this->grantPermission($a_dest_id, $ops, $a_dest_parent);
433 }
434
440 int $a_source_id,
441 int $a_source_parent,
442 int $a_dest_parent,
443 int $a_dest_id,
444 bool $a_consider_protected = true
445 ): void {
446 // exclude system role from rbac
447 if ($a_dest_id == SYSTEM_ROLE_ID) {
448 $this->logger->logStack(ilLogLevel::DEBUG);
449 return;
450 }
451
452 // Read operations
453 $query = 'SELECT * FROM rbac_templates ' .
454 'WHERE rol_id = ' . $this->db->quote($a_source_id, 'integer') . ' ' .
455 'AND parent = ' . $this->db->quote($a_source_parent, 'integer');
456 $res = $this->db->query($query);
457 $operations = [];
458 $rownum = 0;
459 while ($row = $this->db->fetchObject($res)) {
460 $operations[$rownum]['type'] = $row->type;
461 $operations[$rownum]['ops_id'] = $row->ops_id;
462 $rownum++;
463 }
464
465 // Delete target permissions
466 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
467 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
468 $res = $this->db->manipulate($query);
469
470 foreach ($operations as $op) {
471 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
472 'VALUES (' .
473 $this->db->quote($a_dest_id, 'integer') . "," .
474 $this->db->quote($op['type'], 'text') . "," .
475 $this->db->quote($op['ops_id'], 'integer') . "," .
476 $this->db->quote($a_dest_parent, 'integer') . ")";
477 $this->db->manipulate($query);
478 }
479
480 // copy also protection status if applicable
481 if ($a_consider_protected == true) {
482 if ($this->rbacreview->isProtected($a_source_parent, $a_source_id)) {
483 $this->setProtected($a_dest_parent, $a_dest_id, 'y');
484 }
485 }
486 }
487
493 int $a_source1_id,
494 int $a_source1_parent,
495 int $a_source2_id,
496 int $a_source2_parent,
497 int $a_dest_parent,
498 int $a_dest_id
499 ): void {
500 // exclude system role from rbac
501 if ($a_dest_id == SYSTEM_ROLE_ID) {
502 $this->logger->logStack(ilLogLevel::DEBUG);
503 return;
504 }
505 $query = "SELECT s1.type, s1.ops_id " .
506 "FROM rbac_templates s1, rbac_templates s2 " .
507 "WHERE s1.rol_id = " . $this->db->quote($a_source1_id, 'integer') . " " .
508 "AND s1.parent = " . $this->db->quote($a_source1_parent, 'integer') . " " .
509 "AND s2.rol_id = " . $this->db->quote($a_source2_id, 'integer') . " " .
510 "AND s2.parent = " . $this->db->quote($a_source2_parent, 'integer') . " " .
511 "AND s1.type = s2.type " .
512 "AND s1.ops_id = s2.ops_id";
513
514 $res = $this->db->query($query);
515 $operations = [];
516 $rowNum = 0;
517 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
518 $operations[$rowNum]['type'] = $row->type;
519 $operations[$rowNum]['ops_id'] = $row->ops_id;
520
521 $rowNum++;
522 }
523
524 // Delete template permissions of target
525 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
526 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
527 $res = $this->db->manipulate($query);
528
529 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
530 'VALUES (?,?,?,?)';
531 $sta = $this->db->prepareManip($query, ['integer', 'text', 'integer', 'integer']);
532 foreach ($operations as $set) {
533 $this->db->execute($sta, [
534 $a_dest_id,
535 $set['type'],
536 $set['ops_id'],
537 $a_dest_parent
538 ]);
539 }
540 }
541
542 public function copyRolePermissionUnion(
543 int $a_source1_id,
544 int $a_source1_parent,
545 int $a_source2_id,
546 int $a_source2_parent,
547 int $a_dest_id,
548 int $a_dest_parent
549 ): void {
550 // exclude system role from rbac
551 if ($a_dest_id == SYSTEM_ROLE_ID) {
552 $this->logger->logStack(ilLogLevel::DEBUG);
553 return;
554 }
555 $s1_ops = $this->rbacreview->getAllOperationsOfRole($a_source1_id, $a_source1_parent);
556 $s2_ops = $this->rbacreview->getAllOperationsOfRole($a_source2_id, $a_source2_parent);
557 $this->deleteRolePermission($a_dest_id, $a_dest_parent);
558
559 foreach ($s1_ops as $type => $ops) {
560 foreach ($ops as $op) {
561 // insert all permission of source 1
562 // #15469
563 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
564 'VALUES( ' .
565 $this->db->quote($a_dest_id, 'integer') . ', ' .
566 $this->db->quote($type, 'text') . ', ' .
567 $this->db->quote($op, 'integer') . ', ' .
568 $this->db->quote($a_dest_parent, 'integer') . ' ' .
569 ')';
570 $this->db->manipulate($query);
571 }
572 }
573
574 // and the other direction...
575 foreach ($s2_ops as $type => $ops) {
576 foreach ($ops as $op) {
577 if (!isset($s1_ops[$type]) || !in_array($op, $s1_ops[$type])) {
578 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
579 'VALUES( ' .
580 $this->db->quote($a_dest_id, 'integer') . ', ' .
581 $this->db->quote($type, 'text') . ', ' .
582 $this->db->quote($op, 'integer') . ', ' .
583 $this->db->quote($a_dest_parent, 'integer') . ' ' .
584 ')';
585 $this->db->manipulate($query);
586 }
587 }
588 }
589 }
590
595 int $a_source_id,
596 int $a_source_parent,
597 int $a_dest_id,
598 int $a_dest_parent
599 ): void {
600 if ($a_dest_id == SYSTEM_ROLE_ID) {
601 $this->logger->logStack(ilLogLevel::DEBUG);
602 return;
603 }
604 $s1_ops = $this->rbacreview->getAllOperationsOfRole($a_source_id, $a_source_parent);
605 $d_ops = $this->rbacreview->getAllOperationsOfRole($a_dest_id, $a_dest_parent);
606
607 foreach ($s1_ops as $type => $ops) {
608 foreach ($ops as $op) {
609 if (isset($d_ops[$type]) && in_array($op, $d_ops[$type])) {
610 $query = 'DELETE FROM rbac_templates ' .
611 'WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
612 'AND type = ' . $this->db->quote($type, 'text') . ' ' .
613 'AND ops_id = ' . $this->db->quote($op, 'integer') . ' ' .
614 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
615 $this->db->manipulate($query);
616 }
617 }
618 }
619 }
620
626 public function deleteRolePermission(
627 int $a_rol_id,
628 int $a_ref_id,
629 ?string $a_type = null
630 ): void {
631 if ($a_rol_id == SYSTEM_ROLE_ID) {
632 $this->logger->logStack(ilLogLevel::DEBUG);
633 return;
634 }
635 $and_type = '';
636 if ($a_type !== null) {
637 $and_type = " AND type=" . $this->db->quote($a_type, 'text') . " ";
638 }
639 $query = 'DELETE FROM rbac_templates ' .
640 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
641 'AND parent = ' . $this->db->quote($a_ref_id, 'integer') . ' ' .
642 $and_type;
643 $res = $this->db->manipulate($query);
644 }
645
650 public function setRolePermission(int $a_rol_id, string $a_type, array $a_ops, int $a_ref_id): void
651 {
652 if ($a_rol_id == SYSTEM_ROLE_ID) {
653 $this->logger->logStack();
654 return;
655 }
656 foreach ($a_ops as $op) {
657 $this->db->replace(
658 'rbac_templates',
659 [
660 'rol_id' => ['integer', $a_rol_id],
661 'type' => ['text', $a_type],
662 'ops_id' => ['integer', $op],
663 'parent' => ['integer', $a_ref_id]
664 ],
665 []
666 );
667 }
668 }
669
677 public function assignRoleToFolder(
678 int $a_rol_id,
679 int $a_parent,
680 string $a_assign = "y"
681 ): void {
682 if ($a_rol_id == SYSTEM_ROLE_ID) {
683 // ignore system role
684 return;
685 }
686 // if a wrong value is passed, always set assign to "n"
687 if ($a_assign != "y") {
688 $a_assign = "n";
689 }
690
691 // check if already assigned
692 $query = 'SELECT rol_id FROM rbac_fa ' .
693 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
694 'AND parent = ' . $this->db->quote($a_parent, 'integer');
695 $res = $this->db->query($query);
696 if ($res->numRows()) {
697 return;
698 }
699 $query = sprintf(
700 'INSERT INTO rbac_fa (rol_id, parent, assign, protected) ' .
701 'VALUES (%s,%s,%s,%s)',
702 $this->db->quote($a_rol_id, 'integer'),
703 $this->db->quote($a_parent, 'integer'),
704 $this->db->quote($a_assign, 'text'),
705 $this->db->quote('n', 'text')
706 );
707 $res = $this->db->manipulate($query);
708 }
709
714 public function assignOperationToObject(int $a_type_id, int $a_ops_id): void
715 {
716 $query = "INSERT INTO rbac_ta (typ_id, ops_id) " .
717 "VALUES(" . $this->db->quote($a_type_id, 'integer') . "," . $this->db->quote($a_ops_id, 'integer') . ")";
718 $res = $this->db->manipulate($query);
719 }
720
725 public function deassignOperationFromObject(int $a_type_id, int $a_ops_id): void
726 {
727 $query = "DELETE FROM rbac_ta " .
728 "WHERE typ_id = " . $this->db->quote($a_type_id, 'integer') . " " .
729 "AND ops_id = " . $this->db->quote($a_ops_id, 'integer');
730 $res = $this->db->manipulate($query);
731 }
732
736 public function setProtected(int $a_ref_id, int $a_role_id, string $a_value): void
737 {
738 // ref_id not used yet. protected permission acts 'global' for each role,
739 // regardless of any broken inheritance before
740 $query = 'UPDATE rbac_fa ' .
741 'SET protected = ' . $this->db->quote($a_value, 'text') . ' ' .
742 'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer');
743 $res = $this->db->manipulate($query);
744 }
745
751 public function copyLocalRoles(int $a_source_id, int $a_target_id): void
752 {
753 $real_local = [];
754 foreach ($this->rbacreview->getRolesOfRoleFolder($a_source_id, false) as $role_data) {
755 $title = ilObject::_lookupTitle($role_data);
756 if (substr($title, 0, 3) == 'il_') {
757 continue;
758 }
759 $real_local[] = $role_data;
760 }
761 if ($real_local === []) {
762 return;
763 }
764 // Create role folder
765 foreach ($real_local as $role) {
766 $orig = new ilObjRole($role);
767 $orig->read();
768
769 $roleObj = new ilObjRole();
770 $roleObj->setTitle($orig->getTitle());
771 $roleObj->setDescription($orig->getDescription());
772 $roleObj->setImportId($orig->getImportId());
773 $roleObj->create();
774
775 $this->assignRoleToFolder($roleObj->getId(), $a_target_id, "y");
776 $this->copyRolePermissions($role, $a_source_id, $a_target_id, $roleObj->getId(), true);
777 }
778 }
779
781 int $a_ref_id,
782 int $a_role_id,
783 int $a_role_parent,
784 int $a_template_id,
785 int $a_template_parent
786 ): void {
787 if ($this->rbacreview->isProtected($a_role_parent, $a_role_id)) {
788 // Assign object permissions
789 $new_ops = $this->rbacreview->getOperationsOfRole(
790 $a_role_id,
791 ilObject::_lookupType($a_ref_id, true),
792 $a_role_parent
793 );
794
795 // set new permissions for object
796 $this->grantPermission(
797 $a_role_id,
798 (array) $new_ops,
799 $a_ref_id
800 );
801 return;
802 }
803 if (!$a_template_id) {
804 ilLoggerFactory::getLogger('ac')->info('No template id given. Aborting.');
805 return;
806 }
807 // create template permission intersection
808 $this->copyRolePermissionIntersection(
809 $a_template_id,
810 $a_template_parent,
811 $a_role_id,
812 $a_role_parent,
813 $a_ref_id,
814 $a_role_id
815 );
816
817 // assign role to folder
818 $this->assignRoleToFolder(
819 $a_role_id,
820 $a_ref_id,
821 'n'
822 );
823
824 // Assign object permissions
825 $new_ops = $this->rbacreview->getOperationsOfRole(
826 $a_role_id,
827 ilObject::_lookupType($a_ref_id, true),
828 $a_ref_id
829 );
830
831 // revoke existing permissions
832 $this->revokePermission($a_ref_id, $a_role_id);
833
834 // set new permissions for object
835 $this->grantPermission(
836 $a_role_id,
837 (array) $new_ops,
838 $a_ref_id
839 );
840 }
841
847 protected function applyMovedObjectDidacticTemplates(int $a_ref_id, int $a_old_parent): void
848 {
850 if (!$tpl_id) {
851 return;
852 }
853 foreach (ilDidacticTemplateActionFactory::getActionsByTemplateId($tpl_id) as $action) {
854 if ($action instanceof ilDidacticTemplateLocalRoleAction) {
855 continue;
856 }
857 $action->setRefId($a_ref_id);
858 $action->apply();
859 }
860 }
861
868 public function adjustMovedObjectPermissions(int $ref_id, int $old_parent): void
869 {
870 global $DIC;
871
872 $tree = $DIC['tree'];
873
874 $new_parent = $tree->getParentId($ref_id);
875 $old_context_roles = $this->rbacreview->getParentRoleIds($old_parent, false);
876 $new_context_roles = $this->rbacreview->getParentRoleIds($new_parent, false);
877
883 $tree->useCache(false);
884
885 $for_addition = $for_deletion = [];
886 foreach ($new_context_roles as $new_role_id => $new_role) {
887 if (!isset($old_context_roles[$new_role_id])) {
888 $for_addition[] = $new_role_id;
889 } elseif ($new_role['parent'] != $old_context_roles[$new_role_id]['parent']) {
890 // handle stopped inheritance
891 $for_deletion[] = $new_role_id;
892 $for_addition[] = $new_role_id;
893 }
894 }
895 foreach ($old_context_roles as $old_role_id => $old_role) {
896 if (!isset($new_context_roles[$old_role_id])) {
897 $for_deletion[] = $old_role_id;
898 }
899 }
900 if ($for_deletion === [] && $for_addition === []) {
901 $this->applyMovedObjectDidacticTemplates($ref_id, $old_parent);
902 return;
903 }
904
905 $rbac_log_active = ilRbacLog::isActive();
906 if ($rbac_log_active) {
907 $role_ids = array_unique(array_merge(array_keys($for_deletion), array_keys($for_addition)));
908 }
909
910 foreach ($tree->getSubTree($tree->getNodeData($ref_id), true) as $node_data) {
911 $node_id = (int) $node_data['child'];
912 if ($rbac_log_active) {
913 $log_old = ilRbacLog::gatherFaPa($node_id, $role_ids);
914 }
915
916 // If $node_data['type'] is not set, this means there is a tree entry without
917 // object_reference and/or object_data entry
918 // Continue in this case
919 if (!($node_data['type'] ?? false)) {
920 continue;
921 }
922 if (!$node_id) {
923 continue;
924 }
925
926 foreach ($for_deletion as $role_id) {
927 $this->deleteLocalRole($role_id, $node_id);
928 $this->revokePermission($node_id, $role_id, false);
929 }
930 foreach ($for_addition as $role_id) {
931 $role_parent_id = $this->rbacreview->getParentOfRole($role_id, $ref_id);
932 switch ($node_data['type']) {
933 case 'grp':
934 $tpl_id = ilObjGroup::lookupGroupStatusTemplateId((int) $node_data['obj_id']);
935
936 $this->initIntersectionPermissions(
937 $node_id,
938 $role_id,
939 $role_parent_id,
940 $tpl_id,
942 );
943 break;
944
945 case 'crs':
947 $this->initIntersectionPermissions(
948 $node_id,
949 $role_id,
950 $role_parent_id,
951 $tpl_id,
953 );
954 break;
955
956 default:
957 $this->grantPermission(
958 $role_id,
959 $this->rbacreview->getOperationsOfRole($role_id, $node_data['type'], $role_parent_id),
960 $node_id
961 );
962 break;
963 }
964 }
965
966 if ($rbac_log_active) {
967 $log_new = ilRbacLog::gatherFaPa($node_id, $role_ids);
968 $log = ilRbacLog::diffFaPa($log_old, $log_new);
970 }
971 }
972
976 $tree->useCache();
977
978 $this->applyMovedObjectDidacticTemplates($ref_id, $old_parent);
979 }
980}
static getActionsByTemplateId(int $a_tpl_id)
Get actions of one template.
represents a creation of local roles action
static _getInstance()
Get singleton instance of this class.
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static lookupCourseNonMemberTemplatesId()
static lookupGroupStatusTemplateId(int $a_obj_id)
Class ilObjRole.
static _lookupType(int $id, bool $reference=false)
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
Class ilRbacAdmin Core functions for role based access control.
setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status)
removeUser(int $a_usr_id)
deletes a user from rbac_ua all user <-> role relations are deleted
copyRolePermissionUnion(int $a_source1_id, int $a_source1_parent, int $a_source2_id, int $a_source2_parent, int $a_dest_id, int $a_dest_parent)
assignOperationToObject(int $a_type_id, int $a_ops_id)
Assign an existing operation to an object Update of rbac_ta.
applyMovedObjectDidacticTemplates(int $a_ref_id, int $a_old_parent)
Apply didactic templates after object movement.
__construct()
Constructor @access public.
adjustMovedObjectPermissions(int $ref_id, int $old_parent)
Adjust permissions of moved objects.
setProtected(int $a_ref_id, int $a_role_id, string $a_value)
Set protected.
deassignOperationFromObject(int $a_type_id, int $a_ops_id)
Deassign an existing operation from an object Update of rbac_ta.
deassignUser(int $a_rol_id, int $a_usr_id)
Deassigns a user from a role.
deleteSubtreeTemplates(int $a_ref_id, int $a_rol_id)
Delete all template permissions of subtree nodes.
copyRolePermissionSubtract(int $a_source_id, int $a_source_parent, int $a_dest_id, int $a_dest_parent)
Subtract role permissions.
assignRoleToFolder(int $a_rol_id, int $a_parent, string $a_assign="y")
Assigns a role to a role folder A role folder is an object to store roles.
deleteRolePermission(int $a_rol_id, int $a_ref_id, ?string $a_type=null)
Deletes all entries of a template.
deleteLocalRole(int $a_rol_id, int $a_ref_id=0)
Deletes a local role and entries in rbac_fa and rbac_templates.
revokeSubtreePermissions(int $a_ref_id, int $a_role_id)
Revoke subtree permissions.
initIntersectionPermissions(int $a_ref_id, int $a_role_id, int $a_role_parent, int $a_template_id, int $a_template_parent)
copyRolePermissionIntersection(int $a_source1_id, int $a_source1_parent, int $a_source2_id, int $a_source2_parent, int $a_dest_parent, int $a_dest_id)
Copies the intersection of the template permissions of two roles to a third role.
ilRbacReview $rbacreview
copyLocalRoles(int $a_source_id, int $a_target_id)
Copy local roles This method creates a copy of all local role.
ilDBInterface $db
revokePermissionList(array $a_ref_ids, int $a_rol_id)
Revokes permissions of a LIST of objects of ONE role.
deleteRole(int $a_rol_id, int $a_ref_id)
Deletes a role and deletes entries in rbac_pa, rbac_templates, rbac_ua, rbac_fa.
revokePermission(int $a_ref_id, int $a_rol_id=0, bool $a_keep_protected=true)
Revokes permissions of an object of one role.
copyRoleTemplatePermissions(int $a_source_id, int $a_source_parent, int $a_dest_parent, int $a_dest_id, bool $a_consider_protected=true)
Copies template permissions of one role to another.
setRolePermission(int $a_rol_id, string $a_type, array $a_ops, int $a_ref_id)
Inserts template permissions in rbac_templates for an specific object type.
deleteTemplate(int $a_obj_id)
Deletes a template from role folder and deletes all entries in rbac_templates, rbac_fa.
copyRolePermissions(int $a_source_id, int $a_source_parent, int $a_dest_parent, int $a_dest_id, bool $a_consider_protected=true)
Copies template permissions and permission of one role to another.
grantPermission(int $a_rol_id, array $a_ops, int $a_ref_id)
Grants a permission to an object and a specific role.
assignUserLimited(int $a_role_id, int $a_usr_id, int $a_limit, array $a_limited_roles=[])
assignUser(int $a_rol_id, int $a_usr_id)
Assigns an user to a role.
static add(int $action, int $ref_id, array $diff, bool $source_ref_id=false)
const MOVE_OBJECT
static gatherFaPa(int $ref_id, array $role_ids, bool $add_action=false)
static diffFaPa(array $old, array $new)
static isActive()
class ilRbacReview Contains Review functions of core Rbac.
const SYSTEM_ROLE_ID
Definition: constants.php:29
const ROLE_FOLDER_ID
Definition: constants.php:34
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:66
$log
Definition: ltiresult.php:34
$res
Definition: ltiservices.php:69
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$GLOBALS["DIC"]
Definition: wac.php:54