ILIAS  trunk Revision v13.0_alpha-52-g21c366bbdd4
class.ilRbacAdmin.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
34{
39 public function __construct(
40 protected ilDBInterface $db,
41 protected ilRbacReview $rbacreview,
42 protected LoggerInterface $logger
43 ) {
44 }
45
46 public function setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status): void
47 {
48 ilLoggerFactory::getLogger('crs')->logStack();
49 $query = 'UPDATE rbac_fa set blocked = ' . $this->db->quote($a_blocked_status, 'integer') . ' ' .
50 'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer') . ' ' .
51 'AND parent = ' . $this->db->quote($a_ref_id, 'integer');
52 $this->db->manipulate($query);
53 }
54
59 public function removeUser(int $a_usr_id): void
60 {
61 foreach ($this->rbacreview->assignedRoles($a_usr_id) as $role_id) {
62 $this->deassignUser($role_id, $a_usr_id);
63 }
64 $query = "DELETE FROM rbac_ua WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer');
65 $res = $this->db->manipulate($query);
66 }
67
71 public function deleteRole(int $a_rol_id, int $a_ref_id): void
72 {
73 if ($a_rol_id == SYSTEM_ROLE_ID) {
74 $this->logger->logStack(ilLogLevel::DEBUG);
75 throw new DomainException('System administrator role is not deletable.');
76 }
77
79 $mapping->deleteRole($a_rol_id);
80
81 // TODO: check assigned users before deletion
82 // This is done in ilObjRole. Should be better moved to this place?
83
84 // delete user assignements
85 $query = "DELETE FROM rbac_ua " .
86 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer');
87 $res = $this->db->manipulate($query);
88
89 // delete permission assignments
90 $query = "DELETE FROM rbac_pa " .
91 "WHERE rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
92 $res = $this->db->manipulate($query);
93
94 //delete rbac_templates and rbac_fa
95 $this->deleteLocalRole($a_rol_id);
96 }
97
101 public function deleteTemplate(int $a_obj_id): void
102 {
103 $query = 'DELETE FROM rbac_templates ' .
104 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
105 $res = $this->db->manipulate($query);
106
107 $query = 'DELETE FROM rbac_fa ' .
108 'WHERE rol_id = ' . $this->db->quote($a_obj_id, 'integer');
109 $res = $this->db->manipulate($query);
110 }
111
115 public function deleteLocalRole(int $a_rol_id, int $a_ref_id = 0): void
116 {
117 // exclude system role from rbac
118 if ($a_rol_id == SYSTEM_ROLE_ID) {
119 $this->logger->logStack(ilLogLevel::NOTICE);
120 $this->logger->notice('System administrator role is not deletable.');
121 return;
122 }
123
124 $clause = '';
125 if ($a_ref_id != 0) {
126 $clause = 'AND parent = ' . $this->db->quote($a_ref_id, 'integer') . ' ';
127 }
128
129 $query = 'DELETE FROM rbac_fa ' .
130 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
131 $clause;
132 $res = $this->db->manipulate($query);
133
134 $query = 'DELETE FROM rbac_templates ' .
135 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
136 $clause;
137 $res = $this->db->manipulate($query);
138 }
139
140 public function assignUserLimited(
141 int $a_role_id,
142 int $a_usr_id,
143 int $a_limit,
144 array $a_limited_roles = []
145 ): bool {
146 $ilDB = $this->db;
147 $ilAtomQuery = $this->db->buildAtomQuery();
148 $ilAtomQuery->addTableLock('rbac_ua');
149 $ilAtomQuery->addQueryCallable(
150 function (ilDBInterface $ilDB) use (&$ret, $a_role_id, $a_usr_id, $a_limit, $a_limited_roles): void {
151 $ret = true;
152 $limit_query = 'SELECT COUNT(*) num FROM rbac_ua ' .
153 'WHERE ' . $ilDB->in('rol_id', (array) $a_limited_roles, false, 'integer');
154 $res = $ilDB->query($limit_query);
155 $row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
156 if ($row->num >= $a_limit) {
157 $ret = false;
158 return;
159 }
160
161 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
162 "VALUES (" .
163 $ilDB->quote($a_usr_id, 'integer') . "," . $ilDB->quote($a_role_id, 'integer') .
164 ")";
165 $res = $ilDB->manipulate($query);
166 }
167 );
168 $ilAtomQuery->run();
169
170 if (!$ret) {
171 return false;
172 }
173
174 $this->rbacreview->setAssignedCacheEntry($a_role_id, $a_usr_id, true);
176 $mapping->assign($a_role_id, $a_usr_id);
177
178 return true;
179 }
180
184 public function assignUser(int $a_rol_id, int $a_usr_id): void
185 {
186 // check if already assigned user id and role_id
187 $alreadyAssigned = $this->rbacreview->isAssigned($a_usr_id, $a_rol_id);
188
189 // enhanced: only if we haven't had this role for this user
190 if (!$alreadyAssigned) {
191 $query = "INSERT INTO rbac_ua (usr_id, rol_id) " .
192 "VALUES (" . $this->db->quote($a_usr_id, 'integer') . "," . $this->db->quote(
193 $a_rol_id,
194 'integer'
195 ) . ")";
196 $res = $this->db->manipulate($query);
197
198 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, true);
199 }
200
202 $mapping->assign($a_rol_id, $a_usr_id);
203
204 $ref_id = $this->rbacreview->getObjectReferenceOfRole($a_rol_id);
205 $obj_id = ilObject::_lookupObjId($ref_id);
206 $type = ilObject::_lookupType($obj_id);
207
208 if (!$alreadyAssigned) {
209 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event assign user');
210 $GLOBALS['DIC']['ilAppEventHandler']->raise(
211 'components/ILIAS/AccessControl',
212 'assignUser',
213 [
214 'obj_id' => $obj_id,
215 'usr_id' => $a_usr_id,
216 'role_id' => $a_rol_id,
217 'type' => $type
218 ]
219 );
220 }
221 }
222
226 public function deassignUser(int $a_rol_id, int $a_usr_id): void
227 {
228 $query = "DELETE FROM rbac_ua " .
229 "WHERE usr_id = " . $this->db->quote($a_usr_id, 'integer') . " " .
230 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
231 $res = $this->db->manipulate($query);
232
233 $this->rbacreview->setAssignedCacheEntry($a_rol_id, $a_usr_id, false);
234
236 $mapping->deassign($a_rol_id, $a_usr_id);
237
238 if ($res) {
239 $ref_id = $GLOBALS['DIC']['rbacreview']->getObjectReferenceOfRole($a_rol_id);
240 $obj_id = ilObject::_lookupObjId($ref_id);
241 $type = ilObject::_lookupType($obj_id);
242
243 ilLoggerFactory::getInstance()->getLogger('ac')->debug('Raise event deassign user');
244 $GLOBALS['DIC']['ilAppEventHandler']->raise('components/ILIAS/AccessControl', 'deassignUser', [
245 'obj_id' => $obj_id,
246 'usr_id' => $a_usr_id,
247 'role_id' => $a_rol_id,
248 'type' => $type,
249 ]);
250 }
251 }
252
256 public function grantPermission(int $a_rol_id, array $a_ops, int $a_ref_id): void
257 {
258 // exclude system role from rbac
259 if ($a_rol_id == SYSTEM_ROLE_ID) {
260 $this->logger->logStack(ilLogLevel::DEBUG);
261 return;
262 }
263
264 // convert all values to integer
265 foreach ($a_ops as $key => $operation) {
266 $a_ops[$key] = (int) $operation;
267 }
268
269 $ops_ids = serialize($a_ops);
270
271 $query = 'DELETE FROM rbac_pa ' .
272 'WHERE rol_id = %s ' .
273 'AND ref_id = %s';
274 $res = $this->db->queryF(
275 $query,
276 ['integer', 'integer'],
277 [$a_rol_id, $a_ref_id]
278 );
279
280 if ($a_ops === []) {
281 return;
282 }
283
284 $query = "INSERT INTO rbac_pa (rol_id,ops_id,ref_id) " .
285 "VALUES " .
286 "(" . $this->db->quote($a_rol_id, 'integer') . "," . $this->db->quote(
287 $ops_ids,
288 'text'
289 ) . "," . $this->db->quote($a_ref_id, 'integer') . ")";
290 $res = $this->db->manipulate($query);
291 }
292
298 public function revokePermission(int $a_ref_id, int $a_rol_id = 0, bool $a_keep_protected = true): void
299 {
300 if ($a_rol_id == SYSTEM_ROLE_ID) {
301 $this->logger->logStack(ilLogLevel::DEBUG);
302 return;
303 }
304
305 // bypass protected status of roles
306 if ($a_keep_protected != true) {
307 if ($a_rol_id) {
308 $and1 = " AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
309 } else {
310 $and1 = "";
311 }
312
313 $query = "DELETE FROM rbac_pa " .
314 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') .
315 $and1;
316 $res = $this->db->manipulate($query);
317 return;
318 }
319
320 // consider protected status of roles
321
322 // in any case, get all roles in scope first
323 $roles_in_scope = $this->rbacreview->getParentRoleIds($a_ref_id);
324
325 if (!$a_rol_id) {
326 $role_ids = [];
327
328 foreach ($roles_in_scope as $role) {
329 if ($role['protected'] == true) {
330 continue;
331 }
332
333 $role_ids[] = $role['obj_id'];
334 }
335
336 // return if no role in array
337 if ($role_ids === []) {
338 return;
339 }
340
341 $query = 'DELETE FROM rbac_pa ' .
342 'WHERE ' . $this->db->in('rol_id', $role_ids, false, 'integer') . ' ' .
343 'AND ref_id = ' . $this->db->quote($a_ref_id, 'integer');
344 $res = $this->db->manipulate($query);
345 } else {
346 // exclude protected permission settings from revoking
347 if ($roles_in_scope[$a_rol_id]['protected'] == true) {
348 return;
349 }
350
351 $query = "DELETE FROM rbac_pa " .
352 "WHERE ref_id = " . $this->db->quote($a_ref_id, 'integer') . " " .
353 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer') . " ";
354 $res = $this->db->manipulate($query);
355 }
356 }
357
361 public function revokeSubtreePermissions(int $a_ref_id, int $a_role_id): void
362 {
363 $query = 'DELETE FROM rbac_pa ' .
364 'WHERE ref_id IN ' .
365 '( ' . $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
366 'AND rol_id = ' . $this->db->quote($a_role_id, 'integer');
367
368 $this->db->manipulate($query);
369 }
370
374 public function deleteSubtreeTemplates(int $a_ref_id, int $a_rol_id): void
375 {
376 $query = 'DELETE FROM rbac_templates ' .
377 'WHERE parent IN ( ' .
378 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
379 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
380
381 $this->db->manipulate($query);
382
383 $query = 'DELETE FROM rbac_fa ' .
384 'WHERE parent IN ( ' .
385 $GLOBALS['DIC']['tree']->getSubTreeQuery($a_ref_id, ['child']) . ' ) ' .
386 'AND rol_id = ' . $this->db->quote($a_rol_id, 'integer');
387
388 $this->db->manipulate($query);
389 }
390
394 public function revokePermissionList(array $a_ref_ids, int $a_rol_id): void
395 {
396 // exclude system role from rbac
397 if ($a_rol_id == SYSTEM_ROLE_ID) {
398 $this->logger->logStack(ilLogLevel::DEBUG);
399 return;
400 }
401 $query = "DELETE FROM rbac_pa " .
402 "WHERE " . $this->db->in('ref_id', $a_ref_ids, false, 'integer') . ' ' .
403 "AND rol_id = " . $this->db->quote($a_rol_id, 'integer');
404 $res = $this->db->manipulate($query);
405 }
406
410 public function copyRolePermissions(
411 int $a_source_id,
412 int $a_source_parent,
413 int $a_dest_parent,
414 int $a_dest_id,
415 bool $a_consider_protected = true
416 ): void {
417 // Copy template permissions
418 $this->copyRoleTemplatePermissions(
419 $a_source_id,
420 $a_source_parent,
421 $a_dest_parent,
422 $a_dest_id,
423 $a_consider_protected
424 );
425 $ops = $this->rbacreview->getRoleOperationsOnObject($a_source_id, $a_source_parent);
426
427 $this->revokePermission($a_dest_parent, $a_dest_id);
428 $this->grantPermission($a_dest_id, $ops, $a_dest_parent);
429 }
430
436 int $a_source_id,
437 int $a_source_parent,
438 int $a_dest_parent,
439 int $a_dest_id,
440 bool $a_consider_protected = true
441 ): void {
442 // exclude system role from rbac
443 if ($a_dest_id == SYSTEM_ROLE_ID) {
444 $this->logger->logStack(ilLogLevel::DEBUG);
445 return;
446 }
447
448 // Read operations
449 $query = 'SELECT * FROM rbac_templates ' .
450 'WHERE rol_id = ' . $this->db->quote($a_source_id, 'integer') . ' ' .
451 'AND parent = ' . $this->db->quote($a_source_parent, 'integer');
452 $res = $this->db->query($query);
453 $operations = [];
454 $rownum = 0;
455 while ($row = $this->db->fetchObject($res)) {
456 $operations[$rownum]['type'] = $row->type;
457 $operations[$rownum]['ops_id'] = $row->ops_id;
458 $rownum++;
459 }
460
461 // Delete target permissions
462 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
463 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
464 $res = $this->db->manipulate($query);
465
466 foreach ($operations as $op) {
467 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
468 'VALUES (' .
469 $this->db->quote($a_dest_id, 'integer') . "," .
470 $this->db->quote($op['type'], 'text') . "," .
471 $this->db->quote($op['ops_id'], 'integer') . "," .
472 $this->db->quote($a_dest_parent, 'integer') . ")";
473 $this->db->manipulate($query);
474 }
475
476 // copy also protection status if applicable
477 if ($a_consider_protected == true) {
478 if ($this->rbacreview->isProtected($a_source_parent, $a_source_id)) {
479 $this->setProtected($a_dest_parent, $a_dest_id, 'y');
480 }
481 }
482 }
483
489 int $a_source1_id,
490 int $a_source1_parent,
491 int $a_source2_id,
492 int $a_source2_parent,
493 int $a_dest_parent,
494 int $a_dest_id
495 ): void {
496 // exclude system role from rbac
497 if ($a_dest_id == SYSTEM_ROLE_ID) {
498 $this->logger->logStack(ilLogLevel::DEBUG);
499 return;
500 }
501 $query = "SELECT s1.type, s1.ops_id " .
502 "FROM rbac_templates s1, rbac_templates s2 " .
503 "WHERE s1.rol_id = " . $this->db->quote($a_source1_id, 'integer') . " " .
504 "AND s1.parent = " . $this->db->quote($a_source1_parent, 'integer') . " " .
505 "AND s2.rol_id = " . $this->db->quote($a_source2_id, 'integer') . " " .
506 "AND s2.parent = " . $this->db->quote($a_source2_parent, 'integer') . " " .
507 "AND s1.type = s2.type " .
508 "AND s1.ops_id = s2.ops_id";
509
510 $res = $this->db->query($query);
511 $operations = [];
512 $rowNum = 0;
513 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
514 $operations[$rowNum]['type'] = $row->type;
515 $operations[$rowNum]['ops_id'] = $row->ops_id;
516
517 $rowNum++;
518 }
519
520 // Delete template permissions of target
521 $query = 'DELETE FROM rbac_templates WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
522 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
523 $res = $this->db->manipulate($query);
524
525 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
526 'VALUES (?,?,?,?)';
527 $sta = $this->db->prepareManip($query, ['integer', 'text', 'integer', 'integer']);
528 foreach ($operations as $set) {
529 $this->db->execute($sta, [
530 $a_dest_id,
531 $set['type'],
532 $set['ops_id'],
533 $a_dest_parent
534 ]);
535 }
536 }
537
538 public function copyRolePermissionUnion(
539 int $a_source1_id,
540 int $a_source1_parent,
541 int $a_source2_id,
542 int $a_source2_parent,
543 int $a_dest_id,
544 int $a_dest_parent
545 ): void {
546 // exclude system role from rbac
547 if ($a_dest_id == SYSTEM_ROLE_ID) {
548 $this->logger->logStack(ilLogLevel::DEBUG);
549 return;
550 }
551 $s1_ops = $this->rbacreview->getAllOperationsOfRole($a_source1_id, $a_source1_parent);
552 $s2_ops = $this->rbacreview->getAllOperationsOfRole($a_source2_id, $a_source2_parent);
553 $this->deleteRolePermission($a_dest_id, $a_dest_parent);
554
555 foreach ($s1_ops as $type => $ops) {
556 foreach ($ops as $op) {
557 // insert all permission of source 1
558 // #15469
559 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
560 'VALUES( ' .
561 $this->db->quote($a_dest_id, 'integer') . ', ' .
562 $this->db->quote($type, 'text') . ', ' .
563 $this->db->quote($op, 'integer') . ', ' .
564 $this->db->quote($a_dest_parent, 'integer') . ' ' .
565 ')';
566 $this->db->manipulate($query);
567 }
568 }
569
570 // and the other direction...
571 foreach ($s2_ops as $type => $ops) {
572 foreach ($ops as $op) {
573 if (!isset($s1_ops[$type]) || !in_array($op, $s1_ops[$type])) {
574 $query = 'INSERT INTO rbac_templates (rol_id,type,ops_id,parent) ' .
575 'VALUES( ' .
576 $this->db->quote($a_dest_id, 'integer') . ', ' .
577 $this->db->quote($type, 'text') . ', ' .
578 $this->db->quote($op, 'integer') . ', ' .
579 $this->db->quote($a_dest_parent, 'integer') . ' ' .
580 ')';
581 $this->db->manipulate($query);
582 }
583 }
584 }
585 }
586
591 int $a_source_id,
592 int $a_source_parent,
593 int $a_dest_id,
594 int $a_dest_parent
595 ): void {
596 if ($a_dest_id == SYSTEM_ROLE_ID) {
597 $this->logger->logStack(ilLogLevel::DEBUG);
598 return;
599 }
600 $s1_ops = $this->rbacreview->getAllOperationsOfRole($a_source_id, $a_source_parent);
601 $d_ops = $this->rbacreview->getAllOperationsOfRole($a_dest_id, $a_dest_parent);
602
603 foreach ($s1_ops as $type => $ops) {
604 foreach ($ops as $op) {
605 if (isset($d_ops[$type]) && in_array($op, $d_ops[$type])) {
606 $query = 'DELETE FROM rbac_templates ' .
607 'WHERE rol_id = ' . $this->db->quote($a_dest_id, 'integer') . ' ' .
608 'AND type = ' . $this->db->quote($type, 'text') . ' ' .
609 'AND ops_id = ' . $this->db->quote($op, 'integer') . ' ' .
610 'AND parent = ' . $this->db->quote($a_dest_parent, 'integer');
611 $this->db->manipulate($query);
612 }
613 }
614 }
615 }
616
622 public function deleteRolePermission(
623 int $a_rol_id,
624 int $a_ref_id,
625 ?string $a_type = null
626 ): void {
627 if ($a_rol_id == SYSTEM_ROLE_ID) {
628 $this->logger->logStack(ilLogLevel::DEBUG);
629 return;
630 }
631 $and_type = '';
632 if ($a_type !== null) {
633 $and_type = " AND type=" . $this->db->quote($a_type, 'text') . " ";
634 }
635 $query = 'DELETE FROM rbac_templates ' .
636 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
637 'AND parent = ' . $this->db->quote($a_ref_id, 'integer') . ' ' .
638 $and_type;
639 $res = $this->db->manipulate($query);
640 }
641
646 public function setRolePermission(int $a_rol_id, string $a_type, array $a_ops, int $a_ref_id): void
647 {
648 if ($a_rol_id == SYSTEM_ROLE_ID) {
649 $this->logger->logStack();
650 return;
651 }
652 foreach ($a_ops as $op) {
653 $this->db->replace(
654 'rbac_templates',
655 [
656 'rol_id' => ['integer', $a_rol_id],
657 'type' => ['text', $a_type],
658 'ops_id' => ['integer', $op],
659 'parent' => ['integer', $a_ref_id]
660 ],
661 []
662 );
663 }
664 }
665
673 public function assignRoleToFolder(
674 int $a_rol_id,
675 int $a_parent,
676 string $a_assign = "y"
677 ): void {
678 if ($a_rol_id == SYSTEM_ROLE_ID) {
679 // ignore system role
680 return;
681 }
682 // if a wrong value is passed, always set assign to "n"
683 if ($a_assign != "y") {
684 $a_assign = "n";
685 }
686
687 // check if already assigned
688 $query = 'SELECT rol_id FROM rbac_fa ' .
689 'WHERE rol_id = ' . $this->db->quote($a_rol_id, 'integer') . ' ' .
690 'AND parent = ' . $this->db->quote($a_parent, 'integer');
691 $res = $this->db->query($query);
692 if ($res->numRows()) {
693 return;
694 }
695 $query = sprintf(
696 'INSERT INTO rbac_fa (rol_id, parent, assign, protected) ' .
697 'VALUES (%s,%s,%s,%s)',
698 $this->db->quote($a_rol_id, 'integer'),
699 $this->db->quote($a_parent, 'integer'),
700 $this->db->quote($a_assign, 'text'),
701 $this->db->quote('n', 'text')
702 );
703 $res = $this->db->manipulate($query);
704 }
705
710 public function assignOperationToObject(int $a_type_id, int $a_ops_id): void
711 {
712 $query = "INSERT INTO rbac_ta (typ_id, ops_id) " .
713 "VALUES(" . $this->db->quote($a_type_id, 'integer') . "," . $this->db->quote($a_ops_id, 'integer') . ")";
714 $res = $this->db->manipulate($query);
715 }
716
721 public function deassignOperationFromObject(int $a_type_id, int $a_ops_id): void
722 {
723 $query = "DELETE FROM rbac_ta " .
724 "WHERE typ_id = " . $this->db->quote($a_type_id, 'integer') . " " .
725 "AND ops_id = " . $this->db->quote($a_ops_id, 'integer');
726 $res = $this->db->manipulate($query);
727 }
728
732 public function setProtected(int $a_ref_id, int $a_role_id, string $a_value): void
733 {
734 // ref_id not used yet. protected permission acts 'global' for each role,
735 // regardless of any broken inheritance before
736 $query = 'UPDATE rbac_fa ' .
737 'SET protected = ' . $this->db->quote($a_value, 'text') . ' ' .
738 'WHERE rol_id = ' . $this->db->quote($a_role_id, 'integer');
739 $res = $this->db->manipulate($query);
740 }
741
747 public function copyLocalRoles(int $a_source_id, int $a_target_id): void
748 {
749 $real_local = [];
750 foreach ($this->rbacreview->getRolesOfRoleFolder($a_source_id, false) as $role_data) {
751 $title = ilObject::_lookupTitle($role_data);
752 if (substr($title, 0, 3) == 'il_') {
753 continue;
754 }
755 $real_local[] = $role_data;
756 }
757 if ($real_local === []) {
758 return;
759 }
760 // Create role folder
761 foreach ($real_local as $role) {
762 $orig = new ilObjRole($role);
763 $orig->read();
764
765 $roleObj = new ilObjRole();
766 $roleObj->setTitle($orig->getTitle());
767 $roleObj->setDescription($orig->getDescription());
768 $roleObj->setImportId($orig->getImportId());
769 $roleObj->create();
770
771 $this->assignRoleToFolder($roleObj->getId(), $a_target_id, "y");
772 $this->copyRolePermissions($role, $a_source_id, $a_target_id, $roleObj->getId(), true);
773 }
774 }
775
777 int $a_ref_id,
778 int $a_role_id,
779 int $a_role_parent,
780 int $a_template_id,
781 int $a_template_parent
782 ): void {
783 if ($this->rbacreview->isProtected($a_role_parent, $a_role_id)) {
784 // Assign object permissions
785 $new_ops = $this->rbacreview->getOperationsOfRole(
786 $a_role_id,
787 ilObject::_lookupType($a_ref_id, true),
788 $a_role_parent
789 );
790
791 // set new permissions for object
792 $this->grantPermission(
793 $a_role_id,
794 (array) $new_ops,
795 $a_ref_id
796 );
797 return;
798 }
799 if (!$a_template_id) {
800 ilLoggerFactory::getLogger('ac')->info('No template id given. Aborting.');
801 return;
802 }
803 // create template permission intersection
804 $this->copyRolePermissionIntersection(
805 $a_template_id,
806 $a_template_parent,
807 $a_role_id,
808 $a_role_parent,
809 $a_ref_id,
810 $a_role_id
811 );
812
813 // assign role to folder
814 $this->assignRoleToFolder(
815 $a_role_id,
816 $a_ref_id,
817 'n'
818 );
819
820 // Assign object permissions
821 $new_ops = $this->rbacreview->getOperationsOfRole(
822 $a_role_id,
823 ilObject::_lookupType($a_ref_id, true),
824 $a_ref_id
825 );
826
827 // revoke existing permissions
828 $this->revokePermission($a_ref_id, $a_role_id);
829
830 // set new permissions for object
831 $this->grantPermission(
832 $a_role_id,
833 (array) $new_ops,
834 $a_ref_id
835 );
836 }
837
843 protected function applyMovedObjectDidacticTemplates(int $a_ref_id, int $a_old_parent): void
844 {
846 if (!$tpl_id) {
847 return;
848 }
849 foreach (ilDidacticTemplateActionFactory::getActionsByTemplateId($tpl_id) as $action) {
850 if ($action instanceof ilDidacticTemplateLocalRoleAction) {
851 continue;
852 }
853 $action->setRefId($a_ref_id);
854 $action->apply();
855 }
856 }
857
864 public function adjustMovedObjectPermissions(int $ref_id, int $old_parent): void
865 {
866 global $DIC;
867
868 $tree = $DIC['tree'];
869
870 $new_parent = $tree->getParentId($ref_id);
871 $old_context_roles = $this->rbacreview->getParentRoleIds($old_parent, false);
872 $new_context_roles = $this->rbacreview->getParentRoleIds($new_parent, false);
873
879 $tree->useCache(false);
880
881 $for_addition = $for_deletion = [];
882 foreach ($new_context_roles as $new_role_id => $new_role) {
883 if (!isset($old_context_roles[$new_role_id])) {
884 $for_addition[] = $new_role_id;
885 } elseif ($new_role['parent'] != $old_context_roles[$new_role_id]['parent']) {
886 // handle stopped inheritance
887 $for_deletion[] = $new_role_id;
888 $for_addition[] = $new_role_id;
889 }
890 }
891 foreach ($old_context_roles as $old_role_id => $old_role) {
892 if (!isset($new_context_roles[$old_role_id])) {
893 $for_deletion[] = $old_role_id;
894 }
895 }
896 if ($for_deletion === [] && $for_addition === []) {
897 $this->applyMovedObjectDidacticTemplates($ref_id, $old_parent);
898 return;
899 }
900
901 $rbac_log_active = ilRbacLog::isActive();
902 if ($rbac_log_active) {
903 $role_ids = array_unique(array_merge(array_keys($for_deletion), array_keys($for_addition)));
904 }
905
906 foreach ($tree->getSubTree($tree->getNodeData($ref_id), true) as $node_data) {
907 $node_id = (int) $node_data['child'];
908 if ($rbac_log_active) {
909 $log_old = ilRbacLog::gatherFaPa($node_id, $role_ids);
910 }
911
912 // If $node_data['type'] is not set, this means there is a tree entry without
913 // object_reference and/or object_data entry
914 // Continue in this case
915 if (!($node_data['type'] ?? false)) {
916 continue;
917 }
918 if (!$node_id) {
919 continue;
920 }
921
922 foreach ($for_deletion as $role_id) {
923 $this->deleteLocalRole($role_id, $node_id);
924 $this->revokePermission($node_id, $role_id, false);
925 }
926 foreach ($for_addition as $role_id) {
927 $role_parent_id = $this->rbacreview->getParentOfRole($role_id, $ref_id);
928 switch ($node_data['type']) {
929 case 'grp':
930 $tpl_id = ilObjGroup::lookupGroupStatusTemplateId((int) $node_data['obj_id']);
931
932 $this->initIntersectionPermissions(
933 $node_id,
934 $role_id,
935 $role_parent_id,
936 $tpl_id,
938 );
939 break;
940
941 case 'crs':
943 $this->initIntersectionPermissions(
944 $node_id,
945 $role_id,
946 $role_parent_id,
947 $tpl_id,
949 );
950 break;
951
952 default:
953 $this->grantPermission(
954 $role_id,
955 $this->rbacreview->getOperationsOfRole($role_id, $node_data['type'], $role_parent_id),
956 $node_id
957 );
958 break;
959 }
960 }
961
962 if ($rbac_log_active) {
963 $log_new = ilRbacLog::gatherFaPa($node_id, $role_ids);
964 $log = ilRbacLog::diffFaPa($log_old, $log_new);
966 }
967 }
968
972 $tree->useCache();
973
974 $this->applyMovedObjectDidacticTemplates($ref_id, $old_parent);
975 }
976}
const FETCHMODE_OBJECT
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.
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(protected ilDBInterface $db, protected ilRbacReview $rbacreview, protected LoggerInterface $logger)
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.
copyLocalRoles(int $a_source_id, int $a_target_id)
Copy local roles This method creates a copy of all local role.
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.
$log
Definition: ltiauth.php:50
foreach($_POST as $key=> $value) $res
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$GLOBALS["DIC"]
Definition: wac.php:66