ILIAS  release_8 Revision v8.23
class.ilRbacAdmin.php
Go to the documentation of this file.
1 <?php
2 
18 declare(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);
208  $obj_id = ilObject::_lookupObjId($ref_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);
243  $obj_id = ilObject::_lookupObjId($ref_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
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 
594  public function copyRolePermissionSubtract(
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
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 
937  $node_id,
938  $role_id,
939  $role_parent_id,
940  $tpl_id,
942  );
943  break;
944 
945  case 'crs':
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 }
removeUser(int $a_usr_id)
deletes a user from rbac_ua all user <-> role relations are deleted
Class ilObjRole.
static gatherFaPa(int $a_ref_id, array $a_role_ids, bool $a_add_action=false)
$res
Definition: ltiservices.php:69
grantPermission(int $a_rol_id, array $a_ops, int $a_ref_id)
Grants a permission to an object and a specific role.
adjustMovedObjectPermissions(int $ref_id, int $old_parent)
Adjust permissions of moved objects.
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.
deleteRolePermission(int $a_rol_id, int $a_ref_id, ?string $a_type=null)
Deletes all entries of a template.
deleteSubtreeTemplates(int $a_ref_id, int $a_rol_id)
Delete all template permissions of subtree nodes.
static getLogger(string $a_component_id)
Get component logger.
deassignOperationFromObject(int $a_type_id, int $a_ops_id)
Deassign an existing operation from an object Update of rbac_ta.
$type
applyMovedObjectDidacticTemplates(int $a_ref_id, int $a_old_parent)
Apply didactic templates after object movement.
static lookupCourseNonMemberTemplatesId()
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.
const SYSTEM_ROLE_ID
Definition: constants.php:29
revokePermissionList(array $a_ref_ids, int $a_rol_id)
Revokes permissions of a LIST of objects of ONE role.
assignUser(int $a_rol_id, int $a_usr_id)
Assigns an user to a role.
quote($value, string $type)
static isActive()
revokePermission(int $a_ref_id, int $a_rol_id=0, bool $a_keep_protected=true)
Revokes permissions of an object of one role.
revokeSubtreePermissions(int $a_ref_id, int $a_role_id)
Revoke subtree permissions.
static lookupGroupStatusTemplateId(int $a_obj_id)
static diffFaPa(array $a_old, array $a_new)
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.
static _lookupObjId(int $ref_id)
global $DIC
Definition: feed.php:28
static _getInstance()
Get singleton instance of this class.
$ref_id
Definition: ltiauth.php:67
static add(int $a_action, int $a_ref_id, array $a_diff, bool $a_source_ref_id=false)
static _lookupTitle(int $obj_id)
deleteTemplate(int $a_obj_id)
Deletes a template from role folder and deletes all entries in rbac_templates, rbac_fa.
$log
Definition: result.php:33
initIntersectionPermissions(int $a_ref_id, int $a_role_id, int $a_role_parent, int $a_template_id, int $a_template_parent)
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
string $key
Consumer key/client ID value.
Definition: System.php:193
copyLocalRoles(int $a_source_id, int $a_target_id)
Copy local roles This method creates a copy of all local role.
ilDBInterface $db
query(string $query)
Run a (read-only) Query on the database.
$query
const ROLE_FOLDER_ID
Definition: constants.php:34
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. ...
__construct()
Constructor public.
setProtected(int $a_ref_id, int $a_role_id, string $a_value)
Set protected.
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.
in(string $field, array $values, bool $negate=false, string $type="")
deleteLocalRole(int $a_rol_id, int $a_ref_id=0)
Deletes a local role and entries in rbac_fa and rbac_templates.
deleteRole(int $a_rol_id, int $a_ref_id)
Deletes a role and deletes entries in rbac_pa, rbac_templates, rbac_ua, rbac_fa.
static getActionsByTemplateId(int $a_tpl_id)
Get actions of one template.
represents a creation of local roles action
assignUserLimited(int $a_role_id, int $a_usr_id, int $a_limit, array $a_limited_roles=[])
ilRbacReview $rbacreview
copyRolePermissionSubtract(int $a_source_id, int $a_source_parent, int $a_dest_id, int $a_dest_parent)
Subtract role permissions.
const MOVE_OBJECT
Class ilRbacAdmin Core functions for role based access control.
assignOperationToObject(int $a_type_id, int $a_ops_id)
Assign an existing operation to an object Update of rbac_ta.
manipulate(string $query)
Run a (write) Query on the database.
static _lookupType(int $id, bool $reference=false)
setBlockedStatus(int $a_role_id, int $a_ref_id, bool $a_blocked_status)
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)
deassignUser(int $a_rol_id, int $a_usr_id)
Deassigns a user from a role.