00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 require_once("Services/AccessControl/classes/class.ilAccessInfo.php");
00025
00040 class ilAccessHandler
00041 {
00045 function ilAccessHandler()
00046 {
00047 global $rbacsystem;
00048
00049 $this->rbacsystem =& $rbacsystem;
00050 $this->results = array();
00051 $this->current_info = new ilAccessInfo();
00052
00053
00054 $this->cache = true;
00055 $this->rbac = true;
00056 $this->tree = true;
00057 $this->condition = true;
00058 $this->path = true;
00059 $this->status = true;
00060 $this->obj_id_cache = array();
00061 $this->obj_type_cache = array();
00062 }
00063
00074 function storeAccessResult($a_permission, $a_cmd, $a_ref_id, $a_access_granted, $a_user_id = "",$a_info = "")
00075 {
00076 global $ilUser;
00077
00078 if ($a_user_id == "")
00079 {
00080 $a_user_id = $ilUser->getId();
00081 }
00082
00083 if ($a_info == "")
00084 {
00085 $a_info = $this->current_info;
00086 }
00087
00088
00089
00090 if ($this->cache)
00091 {
00092 $this->results[$a_ref_id][$a_permission][$a_cmd][$a_user_id] =
00093 array("granted" => $a_access_granted, "info" => $a_info);
00094
00095 $this->current_result_element = array($a_access_granted,$a_ref_id,$a_permission,$a_cmd,$a_user_id);
00096 $this->last_result = $this->results[$a_ref_id][$a_permission][$a_cmd][$a_user_id];
00097 $this->last_info = $a_info;
00098 }
00099
00100
00101 $this->current_info = new ilAccessInfo();
00102
00103 }
00104
00105
00118 function getStoredAccessResult($a_permission, $a_cmd, $a_ref_id, $a_user_id = "")
00119 {
00120 global $ilUser;
00121
00122 if ($a_user_id == "")
00123 {
00124 $a_user_id = $ilUser->getId();
00125 }
00126
00127
00128
00129
00130
00131
00132 return $this->results[$a_ref_id][$a_permission][$a_cmd][$a_user_id];
00133 }
00134
00135 function storeCache()
00136 {
00137 global $ilDB, $ilUser;
00138
00139 $q = "REPLACE INTO acc_cache (user_id, time, result) VALUES ".
00140 "(".$ilDB->quote($ilUser->getId()).",".time().",".
00141 $ilDB->quote(serialize($this->results)).")";
00142 $ilDB->query($q);
00143 }
00144
00145 function readCache($a_secs = 0)
00146 {
00147 global $ilUser, $ilDB;
00148
00149 if ($a_secs > 0)
00150 {
00151 $q = "SELECT * FROM acc_cache WHERE user_id = ".
00152 $ilDB->quote($ilUser->getId());
00153 $set = $ilDB->query($q);
00154 $rec = $set->fetchRow(DB_FETCHMODE_ASSOC);
00155 if ((time() - $rec["time"]) < $a_secs)
00156 {
00157 $this->results = unserialize($rec["result"]);
00158
00159 return true;
00160 }
00161 }
00162 return false;
00163 }
00164
00165 function getResults()
00166 {
00167 return $this->results;
00168 }
00169
00170 function setResults($a_results)
00171 {
00172 $this->results = $a_results;
00173 }
00174
00178 function addInfoItem($a_type, $a_text, $a_data = "")
00179 {
00180 $this->current_info->addInfoItem($a_type, $a_text, $a_data);
00181 }
00182
00194 function checkAccess($a_permission, $a_cmd, $a_ref_id, $a_type = "", $a_obj_id = "")
00195 {
00196 global $ilUser;
00197
00198 return $this->checkAccessOfUser($ilUser->getId(),$a_permission, $a_cmd, $a_ref_id, $a_type, $a_obj_id);
00199 }
00200
00213 function checkAccessOfUser($a_user_id,$a_permission, $a_cmd, $a_ref_id, $a_type = "", $a_obj_id = "")
00214 {
00215 global $ilBench;
00216
00217 $ilBench->start("AccessControl", "0400_clear_info");
00218 $this->current_info->clear();
00219 $ilBench->stop("AccessControl", "0400_clear_info");
00220
00221 $ilBench->start("AccessControl", "0500_lookup_id_and_type");
00222
00223 if ($a_obj_id == "")
00224 {
00225 if ($this->obj_id_cache[$a_ref_id] > 0)
00226 {
00227 $a_obj_id = $this->obj_id_cache[$a_ref_id];
00228 }
00229 else
00230 {
00231 $a_obj_id = ilObject::_lookupObjId($a_ref_id);
00232 $this->obj_id_cache[$a_ref_id] = $a_obj_id;
00233 }
00234 }
00235 if ($a_type == "")
00236 {
00237 if ($this->obj_type_cache[$a_ref_id] != "")
00238 {
00239 $a_type = $this->obj_type_cache[$a_ref_id];
00240 }
00241 else
00242 {
00243 $a_type = ilObject::_lookupType($a_ref_id, true);
00244 $this->obj_type_cache[$a_ref_id] = $a_type;
00245 }
00246 }
00247 $ilBench->stop("AccessControl", "0500_lookup_id_and_type");
00248
00249
00250
00251 $cached = $this->doCacheCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id);
00252
00253 if ($cached["hit"])
00254 {
00255 return $cached["granted"];
00256 }
00257
00258
00259
00260
00261 if (!$this->doTreeCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id))
00262 {
00263 return false;
00264 }
00265
00266
00267 if (!$this->doRBACCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id))
00268 {
00269 return false;
00270 }
00271
00272
00273 $par_check = $this->doPathCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id);
00274 if (!$par_check)
00275 {
00276 return false;
00277 }
00278
00279
00280 if (!$this->doConditionCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id, $a_obj_id, $a_type))
00281 {
00282 return false;
00283 }
00284
00285
00286 if (!$this->doStatusCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id, $a_obj_id, $a_type))
00287 {
00288 return false;
00289 }
00290
00291
00292 return true;
00293 }
00294
00298 function getInfo()
00299 {
00300
00301
00302
00303 return $this->last_info->getInfoItems();
00304 }
00305
00309 function getResultLast()
00310 {
00311 return $this->last_result;
00312 }
00313
00314 function getResultAll($a_ref_id = "")
00315 {
00316 if ($a_ref_id == "")
00317 {
00318 return $this->results;
00319 }
00320
00321 return $this->results[$a_ref_id];
00322 }
00323
00328 function doCacheCheck($a_permission, $a_cmd, $a_ref_id,$a_user_id)
00329 {
00330 global $ilBench;
00331
00332
00333 $ilBench->start("AccessControl", "1000_checkAccess_get_cache_result");
00334 $stored_access = $this->getStoredAccessResult($a_permission, $a_cmd, $a_ref_id,$a_user_id);
00335
00336 if (is_array($stored_access))
00337 {
00338
00339 $this->current_info = $stored_access["info"];
00340
00341 $ilBench->stop("AccessControl", "1000_checkAccess_get_cache_result");
00342 return array("hit" => true, "granted" => $stored_access["granted"]);
00343 }
00344
00345
00346 $ilBench->stop("AccessControl", "1000_checkAccess_get_cache_result");
00347 return array("hit" => false, "granted" => false);
00348 }
00349
00354 function doTreeCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id)
00355 {
00356 global $tree, $lng, $ilBench;
00357
00358
00359 $ilBench->start("AccessControl", "2000_checkAccess_in_tree");
00360
00361 if(!$tree->isInTree($a_ref_id) or $tree->isDeleted($a_ref_id))
00362 {
00363 $this->current_info->addInfoItem(IL_DELETED, $lng->txt("object_deleted"));
00364 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, false,$a_user_id);
00365 $ilBench->stop("AccessControl", "2000_checkAccess_in_tree");
00366
00367 return false;
00368 }
00369
00370 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, true,$a_user_id);
00371 $ilBench->stop("AccessControl", "2000_checkAccess_in_tree");
00372 return true;
00373 }
00374
00379 function doRBACCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id)
00380 {
00381 global $lng, $ilBench, $ilErr, $ilLog;
00382
00383 $ilBench->start("AccessControl", "2500_checkAccess_rbac_check");
00384
00385 if ($a_permission == "")
00386 {
00387 $message = sprintf('%s::doRBACCheck(): No operations given! $a_ref_id: %s',
00388 get_class($this),
00389 $a_ref_id);
00390 $ilLog->write($message,$ilLog->FATAL);
00391 $ilErr->raiseError($message,$ilErr->MESSAGE);
00392 }
00393
00394 $access = $this->rbacsystem->checkAccessOfUser($a_user_id, $a_permission, $a_ref_id);
00395
00396 if (!$access)
00397 {
00398 $this->current_info->addInfoItem(IL_NO_PERMISSION, $lng->txt("no_permission"));
00399 }
00400
00401 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, $access,$a_user_id);
00402 $ilBench->stop("AccessControl", "2500_checkAccess_rbac_check");
00403
00404 return $access;
00405 }
00406
00411 function doPathCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id, $a_all = false)
00412 {
00413 global $tree, $lng, $ilBench,$ilObjDataCache;
00414
00415
00416 $ilBench->start("AccessControl", "3100_checkAccess_check_parents_get_path");
00417 $path = $tree->getPathId($a_ref_id);
00418 $ilBench->stop("AccessControl", "3100_checkAccess_check_parents_get_path");
00419
00420 $tmp_info = $this->current_info;
00421
00422
00423 foreach ($path as $id)
00424 {
00425 if ($a_ref_id == $id)
00426 {
00427 continue;
00428 }
00429
00430
00431 if($ilObjDataCache->lookupType($ilObjDataCache->lookupObjId($id)) == 'crs')
00432 {
00433 if(!$this->doActivationCheck($a_permission,$a_cmd,$a_ref_id,$a_user_id,$a_all))
00434 {
00435 $this->storeAccessResult($a_permission,$a_cmd,$a_ref_id,false,$a_user_id);
00436 return false;
00437 }
00438 }
00439
00440 $access = $this->checkAccessOfUser($a_user_id, "read", "info", $id);
00441
00442 if ($access == false)
00443 {
00444
00445
00446 $tmp_info->addInfoItem(IL_NO_PARENT_ACCESS, $lng->txt("no_parent_access"),$id);
00447
00448 if ($a_all == false)
00449 {
00450 $ilBench->start("AccessControl", "3200_checkAccess_check_parents_store_result");
00451 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, $access,$a_user_id,$tmp_info);
00452 $ilBench->stop("AccessControl", "3200_checkAccess_check_parents_store_result");
00453 return false;
00454 }
00455 }
00456 }
00457
00458 $ilBench->start("AccessControl", "3200_checkAccess_check_parents_store_result");
00459 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, $access,$a_user_id,$tmp_info);
00460 $ilBench->stop("AccessControl", "3200_checkAccess_check_parents_store_result");
00461
00462 return true;
00463 }
00464
00469 function doActivationCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id, $a_all = false)
00470 {
00471 global $ilBench,$ilObjDataCache;
00472
00473 $ilBench->start("AccessControl", "3150_checkAccess_check_course_activation");
00474
00475 $cache_perm = ($a_permission == "visible")
00476 ? "visible"
00477 : "other";
00478
00479
00480
00481 if (isset($this->ac_cache[$cache_perm][$a_ref_id][$a_user_id]))
00482 {
00483 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00484 return $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id];
00485 }
00486
00487
00488 if($a_permission == 'write')
00489 {
00490 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00491 return true;
00492 }
00493 include_once 'Modules/Course/classes/class.ilCourseItems.php';
00494
00495 $this->preloadActivationTimes(array($a_ref_id));
00496 if(isset($this->ac_times[$a_ref_id]))
00497 {
00498
00499 $item_data = $this->ac_times[$a_ref_id];
00500 }
00501 else
00502 {
00503 global $ilLog;
00504 $ilLog->write(__METHOD__.': Error preloading activation times failed.');
00505 $item_data = ilCourseItems::_readActivationTimes(array($a_ref_id));
00506 $item_data = $item_data[$a_ref_id];
00507 }
00508
00509
00510
00511 if($item_data['timing_type'] != IL_CRS_TIMINGS_ACTIVATION)
00512 {
00513 $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id] = true;
00514 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00515 return true;
00516 }
00517
00518
00519 if((time() >= $item_data['timing_start']) and
00520 (time() <= $item_data['timing_end']))
00521 {
00522 $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id] = true;
00523 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00524 return true;
00525 }
00526
00527
00528 if($this->checkAccessOfUser($a_user_id, "write", "", $a_ref_id))
00529 {
00530 $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id] = true;
00531 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00532 return true;
00533 }
00534
00535 if($a_permission == 'visible' and $item_data['visible'])
00536 {
00537 $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id] = true;
00538 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00539 return true;
00540 }
00541
00542 $this->ac_cache[$cache_perm][$a_ref_id][$a_user_id] = false;
00543 $ilBench->stop("AccessControl", "3150_checkAccess_check_course_activation");
00544 return false;
00545 }
00546
00555 public function preloadActivationTimes($a_ref_ids)
00556 {
00557 include_once('Modules/Course/classes/class.ilCourseItems.php');
00558
00559 $read_arr = array();
00560 foreach($a_ref_ids as $ref_id)
00561 {
00562 if(!isset($this->ac_times[$ref_id]))
00563 {
00564 $read_arr[] = $ref_id;
00565 }
00566 }
00567 if(count($read_arr))
00568 {
00569 $this->ac_times = (array) $this->ac_times + ilCourseItems::_readActivationTimes($read_arr);
00570 }
00571 }
00572
00577 function doConditionCheck($a_permission, $a_cmd, $a_ref_id,$a_user_id, $a_obj_id, $a_type)
00578 {
00579
00580 global $lng, $ilBench;
00581
00582 if ($a_permission == "read" &&
00583 !$this->checkAccessOfUser($a_user_id, "write", "", $a_ref_id, $a_type, $a_obj_id))
00584 {
00585 $ilBench->start("AccessControl", "4000_checkAccess_condition_check");
00586 if(!ilConditionHandler::_checkAllConditionsOfTarget($a_ref_id,$a_obj_id))
00587 {
00588 $conditions = ilConditionHandler::_getConditionsOfTarget($a_ref_id,$a_obj_id, $a_type);
00589
00590 foreach ($conditions as $condition)
00591 {
00592 $this->current_info->addInfoItem(IL_MISSING_PRECONDITION,
00593 $lng->txt("missing_precondition").": ".
00594 ilObject::_lookupTitle($condition["trigger_obj_id"])." ".
00595 $lng->txt("condition_".$condition["operator"])." ".
00596 $condition["value"], $condition);
00597 }
00598 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, false, $a_user_id);
00599 $ilBench->stop("AccessControl", "4000_checkAccess_condition_check");
00600 return false;
00601 }
00602 $ilBench->stop("AccessControl", "4000_checkAccess_condition_check");
00603 }
00604
00605 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, true, $a_user_id);
00606 return true;
00607 }
00608
00613 function doStatusCheck($a_permission, $a_cmd, $a_ref_id,$a_user_id, $a_obj_id, $a_type)
00614 {
00615 global $objDefinition, $ilBench;
00616
00617 $ilBench->start("AccessControl", "5000_checkAccess_object_check");
00618
00619 $class = $objDefinition->getClassName($a_type);
00620 $location = $objDefinition->getLocation($a_type);
00621 $full_class = "ilObj".$class."Access";
00622 include_once($location."/class.".$full_class.".php");
00623
00624
00625 $ilBench->start("AccessControl", "5001_checkAccess_".$full_class."_check");
00626 $obj_access = call_user_func(array($full_class, "_checkAccess"),
00627 $a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id);
00628 $ilBench->stop("AccessControl", "5001_checkAccess_".$full_class."_check");
00629
00630 if (!($obj_access === true))
00631 {
00632
00633 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, false, $a_user_id);
00634 $ilBench->stop("AccessControl", "5000_checkAccess_object_check");
00635 return false;
00636 }
00637
00638 $ilBench->stop("AccessControl", "5000_checkAccess_object_check");
00639
00640 $ilBench->start("AccessControl", "6000_checkAccess_store_access");
00641 $this->storeAccessResult($a_permission, $a_cmd, $a_ref_id, true, $a_user_id);
00642 $ilBench->stop("AccessControl", "6000_checkAccess_store_access");
00643 return true;
00644 }
00645
00646 function clear()
00647 {
00648 $this->results = array();
00649 $this->last_result = "";
00650 $this->current_info = new ilAccessInfo();
00651 }
00652
00653 function enable($a_str,$a_bool)
00654 {
00655 $this->$a_str = $a_bool;
00656 }
00657 }