• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Services/AccessControl/classes/class.ilAccessHandler.php

Go to the documentation of this file.
00001 <?php
00002 /*
00003         +-----------------------------------------------------------------------------+
00004         | ILIAS open source                                                           |
00005         +-----------------------------------------------------------------------------+
00006         | Copyright (c) 1998-2001 ILIAS open source, University of Cologne            |
00007         |                                                                             |
00008         | This program is free software; you can redistribute it and/or               |
00009         | modify it under the terms of the GNU General Public License                 |
00010         | as published by the Free Software Foundation; either version 2              |
00011         | of the License, or (at your option) any later version.                      |
00012         |                                                                             |
00013         | This program is distributed in the hope that it will be useful,             |
00014         | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00015         | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
00016         | GNU General Public License for more details.                                |
00017         |                                                                             |
00018         | You should have received a copy of the GNU General Public License           |
00019         | along with this program; if not, write to the Free Software                 |
00020         | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. |
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                 // use function enable to switch on/off tests (only cache is used so far)
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                 //var_dump("<pre>",$a_permission,"</pre>");
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 //echo "<br>write-$a_ref_id-$a_permission-$a_cmd-$a_user_id-$a_access_granted-";
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                 // get new info object
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                 /*if (is_object($this->results[$a_ref_id][$a_permission][$a_cmd][$a_user_id]['info']))
00128                 {
00129                         $this->current_info = $this->results[$a_ref_id][$a_permission][$a_cmd][$a_user_id]['info'];
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 //var_dump($this->results);
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                 // get object id if not provided
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                 // get cache result
00250 //echo "<br>CheckAccess-".$a_permission."-".$a_cmd."-".$a_ref_id."-".$a_user_id."-";
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                 // to do: payment handling
00259 
00260                 // check if object is in tree and not deleted
00261                 if (!$this->doTreeCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id))
00262                 {
00263                         return false;
00264                 }
00265 
00266                 // rbac check for current object
00267                 if (!$this->doRBACCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id))
00268                 {
00269                         return false;
00270                 }
00271 
00272                 // check read permission for all parents
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                 // condition check (currently only implemented for read permission)
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                 // object type specific check
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                 // all checks passed
00292                 return true;
00293         }
00294 
00298         function getInfo()
00299         {
00300                 //return $this->last_result;
00301                 //$this->last_info->setQueryData($this->current_result_element);
00302                 //var_dump("<pre>",$this->results,"</pre>");
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                 //echo "cacheCheck<br/>";
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                 //var_dump($stored_access);
00336                 if (is_array($stored_access))
00337                 {
00338 //echo "Hit";
00339                         $this->current_info = $stored_access["info"];
00340                         //var_dump("cache-treffer:");
00341                         $ilBench->stop("AccessControl", "1000_checkAccess_get_cache_result");
00342                         return array("hit" => true, "granted" => $stored_access["granted"]);
00343                 }
00344                 
00345                 // not in cache
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                 //echo "treeCheck<br/>";
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                 //echo "rbacCheck<br/>";
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 //echo "<br>dopathcheck";
00415                 //echo "pathCheck<br/>";
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                 //var_dump($this->tmp_info);
00422                                         
00423                 foreach ($path as $id)
00424                 {
00425                         if ($a_ref_id == $id)
00426                         {
00427                                 continue;
00428                         }
00429 
00430                         // Check course activation
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                                 //$this->doCacheCheck($a_permission, $a_cmd, $a_ref_id, $a_user_id);
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 //echo "<br>doActivationCheck-$cache_perm-$a_ref_id-$a_user_id-".$ilObjDataCache->lookupType($ilObjDataCache->lookupObjId($a_ref_id));
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                 // nothings needs to be done if current permission is write permission
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                         // read preloaded
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                 // if activation isn't enabled
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                 // if within activation time
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                 // if user has write permission
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                 // if current permission is visible and visible is set in activation
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                 // no access
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                 //echo "conditionCheck<br/>";
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                 //echo "statusCheck<br/>";
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                 // static call to ilObj..::_checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id)
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                         //$this->current_info->addInfoItem(IL_NO_OBJECT_ACCESS, $obj_acess);
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 }

Generated on Fri Dec 13 2013 17:56:55 for ILIAS Release_3_9_x_branch .rev 46835 by  doxygen 1.7.1