ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilWorkspaceAccessHandler.php
Go to the documentation of this file.
1<?php
2
25{
26 protected ilObjUser $user;
27 protected ilLanguage $lng;
30 protected ilDBInterface $db;
34 protected ?ilTree $tree;
35
36 public function __construct(
37 ?ilTree $a_tree = null
38 ) {
39 global $DIC;
40
41 $this->user = $DIC->user();
42 $this->lng = $DIC->language();
43 $this->rbacreview = $DIC->rbac()->review();
44 $this->settings = $DIC->settings();
45 $this->db = $DIC->database();
46 $ilUser = $DIC->user();
47 $lng = $DIC->language();
48
50
51 if (!$a_tree) {
52 $a_tree = new ilWorkspaceTree($ilUser->getId());
53 }
54 $this->tree = $a_tree;
55 }
56
62 public function getTree(): ilTree
63 {
64 return $this->tree;
65 }
66
67 public function checkAccess(
68 string $a_permission,
69 string $a_cmd,
70 int $a_node_id,
71 string $a_type = ""
72 ): bool {
73 $ilUser = $this->user;
74 return $this->checkAccessOfUser($this->tree, $ilUser->getId(), $a_permission, $a_cmd, $a_node_id, $a_type);
75 }
76
80 public function checkAccessOfUser(
81 ilTree $a_tree,
82 int $a_user_id,
83 string $a_permission,
84 string $a_cmd,
85 int $a_node_id,
86 string $a_type = ""
87 ): bool {
88 $rbacreview = $this->rbacreview;
89 $ilUser = $this->user;
90 $ilSetting = $this->settings;
91
92 // :TODO: create permission for parent node with type ?!
93
94 // #20310
95 if (!$ilSetting->get("enable_global_profiles") && $ilUser->getId() == ANONYMOUS_USER_ID) {
96 return false;
97 }
98
99 // tree root is read-only
100 if ($a_permission == "write") {
101 if ($a_tree->readRootId() == $a_node_id) {
102 return false;
103 }
104 }
105
106 // node owner has all rights
107 if ($a_tree->lookupOwner($a_node_id) == $a_user_id) {
108 return true;
109 }
110
111 // other users can only read
112 if ($a_permission == "read" || $a_permission == "visible") {
113 // get all objects with explicit permission
114 $objects = $this->getPermissions($a_node_id);
115 if ($objects) {
116 // check if given user is member of object or has role
117 foreach ($objects as $obj_id) {
118 switch ($obj_id) {
120 return true;
121
123 // check against input kept in session
124 if (self::getSharedNodePassword($a_node_id) == self::getSharedSessionPassword($a_node_id) ||
125 $a_permission == "visible") {
126 return true;
127 }
128 break;
129
131 if ($ilUser->getId() != ANONYMOUS_USER_ID) {
132 return true;
133 }
134 break;
135
136 default:
137 switch (ilObject::_lookupType($obj_id)) {
138 case "grp":
139 // member of group?
140 if (ilGroupParticipants::_getInstanceByObjId($obj_id)->isAssigned($a_user_id)) {
141 return true;
142 }
143 break;
144
145 case "crs":
146 // member of course?
147 if (ilCourseParticipants::_getInstanceByObjId($obj_id)->isAssigned($a_user_id)) {
148 return true;
149 }
150 break;
151
152 case "role":
153 // has role?
154 if ($rbacreview->isAssigned($a_user_id, $obj_id)) {
155 return true;
156 }
157 break;
158
159 case "usr":
160 // direct assignment
161 if ($a_user_id == $obj_id) {
162 return true;
163 }
164 break;
165 }
166 break;
167 }
168 }
169 }
170 }
171
172 return false;
173 }
174
178 public function setPermissions(int $a_parent_node_id, int $a_node_id): void
179 {
180 // nothing to do as owner has irrefutable rights to any workspace object
181 }
182
186 public function addPermission(
187 int $a_node_id,
188 int $a_object_id,
189 ?string $a_extended_data = null
190 ): bool {
191 $ilDB = $this->db;
192 $ilUser = $this->user;
193
194 // tree owner must not be added
195 if ($this->tree->getTreeId() == $ilUser->getId() &&
196 $a_object_id == $ilUser->getId()) {
197 return false;
198 }
199
200 $ilDB->manipulate("INSERT INTO acl_ws (node_id, object_id, extended_data, tstamp)" .
201 " VALUES (" . $ilDB->quote($a_node_id, "integer") . ", " .
202 $ilDB->quote($a_object_id, "integer") . "," .
203 $ilDB->quote($a_extended_data, "text") . "," .
204 $ilDB->quote(time(), "integer") . ")");
205 return true;
206 }
207
211 public function removePermission(
212 int $a_node_id,
213 ?int $a_object_id = null
214 ): int {
215 $ilDB = $this->db;
216
217 $query = "DELETE FROM acl_ws" .
218 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer");
219
220 if ($a_object_id) {
221 $query .= " AND object_id = " . $ilDB->quote($a_object_id, "integer");
222 }
223
224 return $ilDB->manipulate($query);
225 }
226
231 public function getPermissions(int $a_node_id): array
232 {
233 return self::_getPermissions($a_node_id);
234 }
235
240 public static function _getPermissions(int $a_node_id): array // PHP8-Review: Method return type has no value type specified in iterable type array.
241 {
242 global $DIC;
243
244 $ilDB = $DIC->database();
245 $ilSetting = $DIC->settings();
246
247 $publish_enabled = $ilSetting->get("enable_global_profiles");
248 $publish_perm = array(ilWorkspaceAccessGUI::PERMISSION_ALL,
250
251 $set = $ilDB->query("SELECT object_id FROM acl_ws" .
252 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer"));
253 $res = array();
254 while ($row = $ilDB->fetchAssoc($set)) {
255 if ($publish_enabled || !in_array($row["object_id"], $publish_perm)) {
256 $res[] = (int) $row["object_id"];
257 }
258 }
259 return $res;
260 }
261
262 public function hasRegisteredPermission(int $a_node_id): bool
263 {
264 $ilDB = $this->db;
265
266 $set = $ilDB->query("SELECT object_id FROM acl_ws" .
267 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer") .
268 " AND object_id = " . $ilDB->quote(ilWorkspaceAccessGUI::PERMISSION_REGISTERED, "integer"));
269 return (bool) $ilDB->numRows($set);
270 }
271
272 public function hasGlobalPermission(int $a_node_id): bool
273 {
274 $ilDB = $this->db;
275 $ilSetting = $this->settings;
276
277 if (!$ilSetting->get("enable_global_profiles")) {
278 return false;
279 }
280
281 $set = $ilDB->query("SELECT object_id FROM acl_ws" .
282 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer") .
283 " AND object_id = " . $ilDB->quote(ilWorkspaceAccessGUI::PERMISSION_ALL, "integer"));
284 return (bool) $ilDB->numRows($set);
285 }
286
287 public function hasGlobalPasswordPermission(int $a_node_id): bool
288 {
289 $ilDB = $this->db;
290 $ilSetting = $this->settings;
291
292 if (!$ilSetting->get("enable_global_profiles")) {
293 return false;
294 }
295
296 $set = $ilDB->query("SELECT object_id FROM acl_ws" .
297 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer") .
298 " AND object_id = " . $ilDB->quote(ilWorkspaceAccessGUI::PERMISSION_ALL_PASSWORD, "integer"));
299 return (bool) $ilDB->numRows($set);
300 }
301
302 public static function getPossibleSharedTargets(): array // PHP8-Review: Method return type has no value type specified in iterable type array.
303 {
304 global $DIC;
305
306 $ilUser = $DIC->user();
307 $ilSetting = $DIC->settings();
308
309 $grp_ids = ilParticipants::_getMembershipByType($ilUser->getId(), ["grp"]);
310 $crs_ids = ilParticipants::_getMembershipByType($ilUser->getId(), ["crs"]);
311
312 $obj_ids = array_merge($grp_ids, $crs_ids);
313 $obj_ids[] = $ilUser->getId();
315
316 if ($ilSetting->get("enable_global_profiles")) {
319 }
320
321 return $obj_ids;
322 }
323
324 public function getSharedOwners(): array // PHP8-Review: Method return type has no value type specified in iterable type array.
325 {
326 $ilUser = $this->user;
327 $ilDB = $this->db;
328
329 $obj_ids = $this->getPossibleSharedTargets();
330
331 $user_ids = array();
332 $set = $ilDB->query("SELECT DISTINCT(obj.owner), u.lastname, u.firstname, u.title" .
333 " FROM object_data obj" .
334 " JOIN object_reference_ws ref ON (obj.obj_id = ref.obj_id)" .
335 " JOIN tree_workspace tree ON (tree.child = ref.wsp_id)" .
336 " JOIN acl_ws acl ON (acl.node_id = tree.child)" .
337 " JOIN usr_data u on (u.usr_id = obj.owner)" .
338 " WHERE " . $ilDB->in("acl.object_id", $obj_ids, "", "integer") . // PHP8-Review: Parameter #3 $negate of method ilDBInterface::in() expects bool, string given.
339 " AND obj.owner <> " . $ilDB->quote($ilUser->getId(), "integer") .
340 " ORDER BY u.lastname, u.firstname, u.title");
341 while ($row = $ilDB->fetchAssoc($set)) {
342 $user_ids[$row["owner"]] = $row["lastname"] . ", " . $row["firstname"];
343 if ($row["title"]) {
344 $user_ids[$row["owner"]] .= ", " . $row["title"];
345 }
346 }
347
348 return $user_ids;
349 }
350
351 public function getSharedObjects(int $a_owner_id): array // PHP8-Review: Method return type has no value type specified in iterable type array.
352 {
353 $ilDB = $this->db;
354
355 $obj_ids = $this->getPossibleSharedTargets();
356
357 $res = array();
358 $set = $ilDB->query("SELECT ref.wsp_id,obj.obj_id" .
359 " FROM object_data obj" .
360 " JOIN object_reference_ws ref ON (obj.obj_id = ref.obj_id)" .
361 " JOIN tree_workspace tree ON (tree.child = ref.wsp_id)" .
362 " JOIN acl_ws acl ON (acl.node_id = tree.child)" .
363 " WHERE " . $ilDB->in("acl.object_id", $obj_ids, "", "integer") . // PHP8-Review: Parameter #3 $negate of method ilDBInterface::in() expects bool, string given.
364 " AND obj.owner = " . $ilDB->quote($a_owner_id, "integer"));
365 while ($row = $ilDB->fetchAssoc($set)) {
366 $res[$row["wsp_id"]] = $row["obj_id"];
367 }
368
369 return $res;
370 }
371
372 public function findSharedObjects(// PHP8-Review: Method return type and parameters have no value type specified in iterable type array.
373 ?array $a_filter = null,
374 ?array $a_crs_ids = null,
375 ?array $a_grp_ids = null
376 ): array {
377 $ilDB = $this->db;
378 $ilUser = $this->user;
379 $obj_ids = [];
380 if (!$a_filter["acl_type"]) {
381 $obj_ids = $this->getPossibleSharedTargets();
382 } else {
383 switch ($a_filter["acl_type"]) {
384 case "all":
385 $obj_ids = array(ilWorkspaceAccessGUI::PERMISSION_ALL);
386 break;
387
388 case "password":
390 break;
391
392 case "registered":
394 break;
395
396 case "course":
397 $obj_ids = $a_crs_ids;
398 break;
399
400 case "group":
401 $obj_ids = $a_grp_ids;
402 break;
403
404 case "user":
405 $obj_ids = array($ilUser->getId());
406 break;
407 }
408 }
409
410 $res = array();
411
412 $sql = "SELECT ref.wsp_id,obj.obj_id,obj.type,obj.title,obj.owner," .
413 "acl.object_id acl_type, acl.tstamp acl_date" .
414 " FROM object_data obj" .
415 " JOIN object_reference_ws ref ON (obj.obj_id = ref.obj_id)" .
416 " JOIN tree_workspace tree ON (tree.child = ref.wsp_id)" .
417 " JOIN acl_ws acl ON (acl.node_id = tree.child)" .
418 " WHERE " . $ilDB->in("acl.object_id", $obj_ids, "", "integer") .
419 " AND obj.owner <> " . $ilDB->quote($ilUser->getId(), "integer");
420
421 if ($a_filter["obj_type"] ?? false) {
422 $sql .= " AND obj.type = " . $ilDB->quote($a_filter["obj_type"], "text");
423 }
424 if (($a_filter["title"] ?? false) && strlen($a_filter["title"]) >= 3) {
425 $sql .= " AND " . $ilDB->like("obj.title", "text", "%" . $a_filter["title"] . "%");
426 }
427 if (($a_filter["user"] ?? false) && strlen($a_filter["user"]) >= 3) {
428 $usr_ids = array();
429 $set = $ilDB->query("SELECT usr_id FROM usr_data" .
430 " WHERE (" . $ilDB->like("login", "text", "%" . $a_filter["user"] . "%") . " " .
431 "OR " . $ilDB->like("firstname", "text", "%" . $a_filter["user"] . "%") . " " .
432 "OR " . $ilDB->like("lastname", "text", "%" . $a_filter["user"] . "%") . " " .
433 "OR " . $ilDB->like("email", "text", "%" . $a_filter["user"] . "%") . ")");
434 while ($row = $ilDB->fetchAssoc($set)) {
435 $usr_ids[] = $row["usr_id"];
436 }
437 if (!sizeof($usr_ids)) {
438 return [];
439 }
440 $sql .= " AND " . $ilDB->in("obj.owner", $usr_ids, "", "integer"); // PHP8-Review: Parameter #3 $negate of method ilDBInterface::in() expects bool, string given.
441 }
442
443 if ($a_filter["acl_date"] ?? false) {
444 $dt = $a_filter["acl_date"]->get(IL_CAL_DATE);
445 $dt = new ilDateTime($dt . " 00:00:00", IL_CAL_DATETIME);
446 $sql .= " AND acl.tstamp > " . $ilDB->quote($dt->get(IL_CAL_UNIX), "integer");
447 }
448
449 if ($a_filter["crsgrp"] ?? false) {
450 $part = ilParticipants::getInstanceByObjId($a_filter['crsgrp']);
451 $part = $part->getParticipants();
452 if (!sizeof($part)) {
453 return [];
454 }
455 $sql .= " AND " . $ilDB->in("obj.owner", $part, "", "integer");
456 }
457
458 // we use the oldest share date
459 $sql .= " ORDER BY acl.tstamp";
460
461 $set = $ilDB->query($sql);
462 while ($row = $ilDB->fetchAssoc($set)) {
463 if (!isset($res[$row["wsp_id"]])) {
464 $row["acl_type"] = array($row["acl_type"]);
465 $res[$row["wsp_id"]] = $row;
466 } else {
467 $res[$row["wsp_id"]]["acl_type"][] = $row["acl_type"];
468 }
469 }
470
471 return $res;
472 }
473
474 public static function getSharedNodePassword(int $a_node_id): string
475 {
476 global $DIC;
477
478 $ilDB = $DIC->database();
479
480 $set = $ilDB->query("SELECT * FROM acl_ws" .
481 " WHERE node_id = " . $ilDB->quote($a_node_id, "integer") .
482 " AND object_id = " . $ilDB->quote(ilWorkspaceAccessGUI::PERMISSION_ALL_PASSWORD, "integer"));
483 $res = $ilDB->fetchAssoc($set);
484 if ($res) {
485 return $res["extended_data"];
486 }
487 return "";
488 }
489
490 public static function keepSharedSessionPassword(int $a_node_id, string $a_password): void
491 {
492 ilSession::set("ilshpw_" . $a_node_id, $a_password);
493 }
494
495 public static function getSharedSessionPassword(int $a_node_id): string
496 {
497 return (string) ilSession::get("ilshpw_" . $a_node_id);
498 }
499
500 public static function getGotoLink(int $a_node_id, int $a_obj_id, string $a_additional = ""): string
501 {
502 return ilLink::_getStaticLink($a_node_id, ilObject::_lookupType($a_obj_id), true, $a_additional . "_wsp");
503 }
504
505 public function getObjectsIShare(): array // PHP8-Review: Method return type has no value type specified in iterable type array.
506 {
507 $ilDB = $this->db;
508 $ilUser = $this->user;
509
510 $res = array();
511 $set = $ilDB->query("SELECT ref.wsp_id,obj.obj_id" .
512 " FROM object_data obj" .
513 " JOIN object_reference_ws ref ON (obj.obj_id = ref.obj_id)" .
514 " JOIN tree_workspace tree ON (tree.child = ref.wsp_id)" .
515 " JOIN acl_ws acl ON (acl.node_id = tree.child)" .
516 " WHERE obj.owner = " . $ilDB->quote($ilUser->getId(), "integer"));
517 while ($row = $ilDB->fetchAssoc($set)) {
518 $res[$row["wsp_id"]] = $row["obj_id"];
519 }
520
521 return $res;
522 }
523
524 public static function getObjectDataFromNode(int $a_node_id): ?array // PHP8-Review: Method return type has no value type specified in iterable type array.
525 {
526 global $DIC;
527
528 $ilDB = $DIC->database();
529
530 $set = $ilDB->query("SELECT obj.obj_id, obj.type, obj.title" .
531 " FROM object_reference_ws ref" .
532 " JOIN tree_workspace tree ON (tree.child = ref.wsp_id)" .
533 " JOIN object_data obj ON (ref.obj_id = obj.obj_id)" .
534 " WHERE ref.wsp_id = " . $ilDB->quote($a_node_id, "integer"));
535 return $ilDB->fetchAssoc($set);
536 }
537
538 public function addMissingPermissionForObjects(int $node_id, array $objects): bool
539 {
540 $existing = $this->getPermissions($node_id);
541 $added = false;
542 foreach ($objects as $object_id) {
543 if (!in_array($object_id, $existing, true)) {
544 $this->addPermission($node_id, $object_id);
545 $added = true;
546 }
547 }
548 return $added;
549 }
550
551}
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DATETIME
static _getInstanceByObjId(int $a_obj_id)
@classDescription Date and time handling
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
language handling
loadLanguageModule(string $a_module)
Load language module.
User class.
static _lookupType(int $id, bool $reference=false)
static _getMembershipByType(int $a_usr_id, array $a_type, bool $a_only_member_role=false)
get membership by type Get course or group membership
static getInstanceByObjId(int $a_obj_id)
Get instance by obj type.
class ilRbacReview Contains Review functions of core Rbac.
isAssigned(int $a_usr_id, int $a_role_id)
check if a specific user is assigned to specific role
static get(string $a_var)
static set(string $a_var, $a_val)
Set a value.
ILIAS Setting Class.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setPermissions(int $a_parent_node_id, int $a_node_id)
Set permissions after creating node/object.
addMissingPermissionForObjects(int $node_id, array $objects)
static getSharedNodePassword(int $a_node_id)
getPermissions(int $a_node_id)
Get all permissions of node.
checkAccessOfUser(ilTree $a_tree, int $a_user_id, string $a_permission, string $a_cmd, int $a_node_id, string $a_type="")
check access for an object
static getObjectDataFromNode(int $a_node_id)
addPermission(int $a_node_id, int $a_object_id, ?string $a_extended_data=null)
Add permission to node for object.
removePermission(int $a_node_id, ?int $a_object_id=null)
Remove permission[s] (for object) to node.
static _getPermissions(int $a_node_id)
Get all permissions to node.
findSharedObjects(?array $a_filter=null, ?array $a_crs_ids=null, ?array $a_grp_ids=null)
static keepSharedSessionPassword(int $a_node_id, string $a_password)
static getSharedSessionPassword(int $a_node_id)
checkAccess(string $a_permission, string $a_cmd, int $a_node_id, string $a_type="")
static getGotoLink(int $a_node_id, int $a_obj_id, string $a_additional="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const ANONYMOUS_USER_ID
Definition: constants.php:27
Interface ilDBInterface.
$res
Definition: ltiservices.php:69
global $ilSetting
Definition: privfeed.php:31
global $DIC
Definition: shib_login.php:26