ILIAS  release_8 Revision v8.24
class.ilRbacAdmin.php
Go to the documentation of this file.
1<?php
2
18declare(strict_types=1);
19
31{
32 protected ilDBInterface $db;
34 protected ilLogger $logger;
35
40 public function __construct()
41 {
42 global $DIC;
43
44 $this->db = $DIC->database();
45 $this->rbacreview = $DIC->rbac()->review();
46 $this->logger = $DIC->logger()->ac();
47 }
48
49 public function setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status): void
50 {
51 ilLoggerFactory::getLogger('crs')->logStack();
52 $query = 'UPDATE rbac_fa set blocked = ' . $this->db->quote($a_blocked_status, 'integer') . ' ' .
53 'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
54 'AND parent = ' . $this->db->quote($a_ref_id, 'integer');
55 $this->db->manipulate($query);
56 }
57
62 public function removeUser(int $a_usr_id): void
63 {
64 foreach ($this->rbacreview->assignedRoles($a_usr_id) as $role_id) {
65 $this->deassignUser($role_id, $a_usr_id);
66 }
67 $query = "DELETE FROM rbac_ua WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer');
68 $res = $this->db->manipulate($query);
69 }
70
74 public function deleteRole(int $a_rol_id, int $a_ref_id): void
75 {
76 if ($a_rol_id == SYSTEM_ROLE_ID) {
77 $this->logger->logStack(ilLogLevel::DEBUG);
78 throw new DomainException('System administrator role is not deletable.');
79 }
80
82 $mapping->deleteRole($a_rol_id);
83
84 // TODO: check assigned users before deletion
85 // This is done in ilObjRole. Should be better moved to this place?
86
87 // delete user assignements
88 $query = "DELETE FROM rbac_ua " .
89 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer');
90 $res = $this->db->manipulate($query);
91
92 // delete permission assignments
93 $query = "DELETE FROM rbac_pa " .
94 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
95 $res = $this->db->manipulate($query);
96
97 //delete rbac_templates and rbac_fa
98 $this->deleteLocalRole($a_rol_id);
99 }
100
104 public function deleteTemplate(int $a_obj_id): void
105 {
106 $query = 'DELETE FROM rbac_templates ' .
107 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
108 $res = $this->db->manipulate($query);
109
110 $query = 'DELETE FROM rbac_fa ' .
111 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
112 $res = $this->db->manipulate($query);
113 }
114
118 public function deleteLocalRole(int $a_rol_id, int $a_ref_id = 0): void
119 {
120 // exclude system role from rbac
121 if ($a_rol_id == SYSTEM_ROLE_ID) {
122 $this->logger->logStack(ilLogLevel::NOTICE);
123 $this->logger->notice('System administrator role is not deletable.');
124 return;
125 }
126
127 $clause = '';
128 if ($a_ref_id != 0) {
129 $clause = 'AND parent = ' . $this->db->quote($a_ref_id, 'integer') . ' ';
130 }
131
132 $query = 'DELETE FROM rbac_fa ' .
133 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
134 $clause;
135 $res = $this->db->manipulate($query);
136
137 $query = 'DELETE FROM rbac_templates ' .
138 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
139 $clause;
140 $res = $this->db->manipulate($query);
141 }
142
143 public function assignUserLimited(
144 int $a_role_id,
145 int $a_usr_id,
146 int $a_limit,
147 array $a_limited_roles = []
148 ): bool {
149 $ilDB = $this->db;
150 $ilAtomQuery = $this->db->buildAtomQuery();
151 $ilAtomQuery->addTableLock('rbac_ua');
152 $ilAtomQuery->addQueryCallable(
153 function (ilDBInterface $ilDB) use (&$ret, $a_role_id, $a_usr_id, $a_limit, $a_limited_roles): void {
154 $ret = true;
155 $limit_query = 'SELECT COUNT(*) num FROM rbac_ua ' .
156 'WHERE ' . $ilDB->in('rol_id', (array) $a_limited_roles, false, 'integer');
157 $res = $ilDB->query($limit_query);
158 $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
159 if ($row->num >= $a_limit) {
160 $ret = false;
161 return;
162 }
163
164 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
165 "VALUES (" .
166 $ilDB->quote($a_usr_id, 'integer') . "," . $ilDB->quote($a_role_id, 'integer') .
167 ")";
168 $res = $ilDB->manipulate($query);
169 }
170 );
171 $ilAtomQuery->run();
172
173 if (!$ret) {
174 return false;
175 }
176
177 $this->rbacreview->setAssignedCacheEntry($a_role_id, $a_usr_id, true);
179 $mapping->assign($a_role_id, $a_usr_id);
180
181 return true;
182 }
183
187 public function assignUser(int $a_rol_id, int $a_usr_id): void
188 {
189 // check if already assigned user id and role_id
190 $alreadyAssigned = $this->rbacreview->isAssigned($a_usr_id, $a_rol_id);
191
192 // enhanced: only if we haven't had this role for this user
193 if (!$alreadyAssigned) {
194 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
195 "VALUES (" . $this->db->quote($a_usr_id, 'integer') . "," . $this->db->quote(
196 $a_rol_id,
197 'integer'
198 ) . ")";
199 $res = $this->db->manipulate($query);
200
201 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, true);
202 }
203
205 $mapping->assign($a_rol_id, $a_usr_id);
206
207 $ref_id = $this->rbacreview->getObjectReferenceOfRole($a_rol_id);
209 $type = ilObject::_lookupType($obj_id);
210
211 if (!$alreadyAssigned) {
212 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event assign user');
213 $GLOBALS['DIC']['ilAppEventHandler']->raise(
214 'Services/AccessControl',
215 'assignUser',
216 array(
217 'obj_id' => $obj_id,
218 'usr_id' => $a_usr_id,
219 'role_id' => $a_rol_id,
220 'type' => $type
221 )
222 );
223 }
224 }
225
229 public function deassignUser(int $a_rol_id, int $a_usr_id): void
230 {
231 $query = "DELETE FROM rbac_ua " .
232 "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . " " .
233 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
234 $res = $this->db->manipulate($query);
235
236 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, false);
237
239 $mapping->deassign($a_rol_id, $a_usr_id);
240
241 if ($res) {
242 $ref_id = $GLOBALS['DIC']['rbacreview']->getObjectReferenceOfRole($a_rol_id);
244 $type = ilObject::_lookupType($obj_id);
245
246 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event deassign user');
247 $GLOBALS['DIC']['ilAppEventHandler']->raise('Services/AccessControl', 'deassignUser', array(
248 'obj_id' => $obj_id,
249 'usr_id' => $a_usr_id,
250 'role_id' => $a_rol_id,
251 'type' => $type,
252 ));
253 }
254 }
255
259 public function grantPermission(int $a_rol_id, array $a_ops, int $a_ref_id): void
260 {
261 // exclude system role from rbac
262 if ($a_rol_id == SYSTEM_ROLE_ID) {
263 $this->logger->logStack(ilLogLevel::DEBUG);
264 return;
265 }
266
267 // convert all values to integer
268 foreach ($a_ops as $key => $operation) {
269 $a_ops[$key] = (int) $operation;
270 }
271
272 $ops_ids = serialize($a_ops);
273
274 $query = 'DELETE FROM rbac_pa ' .
275 'WHERE rol_id = %s ' .
276 'AND ref_id = %s';
277 $res = $this->db->queryF(
278 $query,
279 array('integer', 'integer'),
280 array($a_rol_id, $a_ref_id)
281 );
282
283 if ($a_ops === []) {
284 return;
285 }
286
287 $query = "INSERT INTO rbac_pa (rol_id,ops_id,ref_id) " .
288 "VALUES " .
289 "(" . $this->db->quote($a_rol_id, 'integer') . "," . $this->db->quote(
290 $ops_ids,
291 'text'
292 ) . "," . $this->db->quote($a_ref_id, 'integer') . ")";
293 $res = $this->db->manipulate($query);
294 }
295
301 public function revokePermission(int $a_ref_id, int $a_rol_id = 0, bool $a_keep_protected = true): void
302 {
303 if ($a_rol_id == SYSTEM_ROLE_ID) {
304 $this->logger->logStack(ilLogLevel::DEBUG);
305 return;
306 }
307
308 // bypass protected status of roles
309 if ($a_keep_protected != true) {
310 if ($a_rol_id) {
311 $and1 = " AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
312 } else {
313 $and1 = "";
314 }
315
316 $query = "DELETE FROM rbac_pa " .
317 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') .
318 $and1;
319 $res = $this->db->manipulate($query);
320 return;
321 }
322
323 // consider protected status of roles
324
325 // in any case, get all roles in scope first
326 $roles_in_scope = $this->rbacreview->getParentRoleIds($a_ref_id);
327
328 if (!$a_rol_id) {
329 $role_ids = [];
330
331 foreach ($roles_in_scope as $role) {
332 if ($role['protected'] == true) {
333 continue;
334 }
335
336 $role_ids[] = $role['obj_id'];
337 }
338
339 // return if no role in array
340 if ($role_ids === []) {
341 return;
342 }
343
344 $query = 'DELETE FROM rbac_pa ' .
345 'WHERE ' . $this->db->in('rol_id', $role_ids, false, 'integer') . ' ' .
346 'AND ref_id = ' . $this->db->quote($a_ref_id, 'integer');
347 $res = $this->db->manipulate($query);
348 } else {
349 // exclude protected permission settings from revoking
350 if ($roles_in_scope[$a_rol_id]['protected'] == true) {
351 return;
352 }
353
354 $query = "DELETE FROM rbac_pa " .
355 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') . " " .
356 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
357 $res = $this->db->manipulate($query);
358 }
359 }
360
364 public function revokeSubtreePermissions(int $a_ref_id, int $a_role_id): void
365 {
366 $query = 'DELETE FROM rbac_pa ' .
367 'WHERE ref_id IN ' .
368 '( ' . $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, array('child')) . ' ) ' .
369 'AND rol_id = ' . $this->db->quote($a_role_id, 'integer');
370
371 $this->db->manipulate($query);
372 }
373
377 public function deleteSubtreeTemplates(int $a_ref_id, int $a_rol_id): void
378 {
379 $query = 'DELETE FROM rbac_templates ' .
380 'WHERE parent IN ( ' .
381 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, array('child')) . ' ) ' .
382 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
383
384 $this->db->manipulate($query);
385
386 $query = 'DELETE FROM rbac_fa ' .
387 'WHERE parent IN ( ' .
388 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, array('child')) . ' ) ' .
389 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
390
391 $this->db->manipulate($query);
392 }
393
397 public function revokePermissionList(array $a_ref_ids, int $a_rol_id): void
398 {
399 // exclude system role from rbac
400 if ($a_rol_id == SYSTEM_ROLE_ID) {
401 $this->logger->logStack(ilLogLevel::DEBUG);
402 return;
403 }
404 $query = "DELETE FROM rbac_pa " .
405 "WHERE " . $this->db->in('ref_id', $a_ref_ids, false, 'integer') . ' ' .
406 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer');
407 $res = $this->db->manipulate($query);
408 }
409
413 public function copyRolePermissions(
414 int $a_source_id,
415 int $a_source_parent,
416 int $a_dest_parent,
417 int $a_dest_id,
418 bool $a_consider_protected = true
419 ): void {
420 // Copy template permissions
421 $this->copyRoleTemplatePermissions(
422 $a_source_id,
423 $a_source_parent,
424 $a_dest_parent,
425 $a_dest_id,
426 $a_consider_protected
427 );
428 $ops = $this->rbacreview->getRoleOperationsOnObject($a_source_id, $a_source_parent);
429
430 $this->revokePermission($a_dest_parent, $a_dest_id);
431 $this->grantPermission($a_dest_id, $ops, $a_dest_parent);
432 }
433
439 int $a_source_id,
440 int $a_source_parent,
441 int $a_dest_parent,
442 int $a_dest_id,
443 bool $a_consider_protected = true
444 ): void {
445 // exclude system role from rbac
446 if ($a_dest_id == SYSTEM_ROLE_ID) {
447 $this->logger->logStack(ilLogLevel::DEBUG);
448 return;
449 }
450
451 // Read operations
452 $query = 'SELECT * FROM rbac_templates ' .
453 'WHERE rol_id = ' . $this->db->quote($a_source_id, 'integer') . ' ' .
454 'AND parent = ' . $this->db->quote($a_source_parent, 'integer');
455 $res = $this->db->query($query);
456 $operations = [];
457 $rownum = 0;
458 while ($row = $this->db->fetchObject($res)) {
459 $operations[$rownum]['type'] = $row->type;
460 $operations[$rownum]['ops_id'] = $row->ops_id;
461 $rownum++;
462 }
463
464 // Delete target permissions
465 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
466 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
467 $res = $this->db->manipulate($query);
468
469 foreach ($operations as $op) {
470 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
471 'VALUES (' .
472 $this->db->quote($a_dest_id, 'integer') . "," .
473 $this->db->quote($op['type'], 'text') . "," .
474 $this->db->quote($op['ops_id'], 'integer') . "," .
475 $this->db->quote($a_dest_parent, 'integer') . ")";
476 $this->db->manipulate($query);
477 }
478
479 // copy also protection status if applicable
480 if ($a_consider_protected == true) {
481 if ($this->rbacreview->isProtected($a_source_parent, $a_source_id)) {
482 $this->setProtected($a_dest_parent, $a_dest_id, 'y');
483 }
484 }
485 }
486
492 int $a_source1_id,
493 int $a_source1_parent,
494 int $a_source2_id,
495 int $a_source2_parent,
496 int $a_dest_parent,
497 int $a_dest_id
498 ): void {
499 // exclude system role from rbac
500 if ($a_dest_id == SYSTEM_ROLE_ID) {
501 $this->logger->logStack(ilLogLevel::DEBUG);
502 return;
503 }
504 $query = "SELECT s1.type, s1.ops_id " .
505 "FROM rbac_templates s1, rbac_templates s2 " .
506 "WHERE s1.rol_id = " . $this->db->quote($a_source1_id, 'integer') . " " .
507 "AND s1.parent = " . $this->db->quote($a_source1_parent, 'integer') . " " .
508 "AND s2.rol_id = " . $this->db->quote($a_source2_id, 'integer') . " " .
509 "AND s2.parent = " . $this->db->quote($a_source2_parent, 'integer') . " " .
510 "AND s1.type = s2.type " .
511 "AND s1.ops_id = s2.ops_id";
512
513 $res = $this->db->query($query);
514 $operations = [];
515 $rowNum = 0;
516 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
517 $operations[$rowNum]['type'] = $row->type;
518 $operations[$rowNum]['ops_id'] = $row->ops_id;
519
520 $rowNum++;
521 }
522
523 // Delete template permissions of target
524 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
525 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
526 $res = $this->db->manipulate($query);
527
528 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
529 'VALUES (?,?,?,?)';
530 $sta = $this->db->prepareManip($query, array('integer', 'text', 'integer', 'integer'));
531 foreach ($operations as $set) {
532 $this->db->execute($sta, array(
533 $a_dest_id,
534 $set['type'],
535 $set['ops_id'],
536 $a_dest_parent
537 ));
538 }
539 }
540
541 public function copyRolePermissionUnion(
542 int $a_source1_id,
543 int $a_source1_parent,
544 int $a_source2_id,
545 int $a_source2_parent,
546 int $a_dest_id,
547 int $a_dest_parent
548 ): void {
549
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
967 if ($rbac_log_active) {
968 $log_new = ilRbacLog::gatherFaPa($node_id, $role_ids);
969 $log = ilRbacLog::diffFaPa($log_old, $log_new);
971 }
972 }
973
977 $tree->useCache();
978
979 $this->applyMovedObjectDidacticTemplates($ref_id, $old_parent);
980 }
981}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
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.
const MOVE_OBJECT
static diffFaPa(array $a_old, array $a_new)
static add(int $a_action, int $a_ref_id, array $a_diff, bool $a_source_ref_id=false)
static gatherFaPa(int $a_ref_id, array $a_role_ids, bool $a_add_action=false)
static isActive()
class ilRbacReview Contains Review functions of core Rbac.
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
const SYSTEM_ROLE_ID
Definition: constants.php:29
const ROLE_FOLDER_ID
Definition: constants.php:34
global $DIC
Definition: feed.php:28
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:67
$res
Definition: ltiservices.php:69
string $key
Consumer key/client ID value.
Definition: System.php:193
$query
$type
$log
Definition: result.php:33