ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilRbacSystem.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 
37 {
38  protected static $user_role_cache = array();
39  var $ilias;
40 
41  // Cache accesses to RBAC PA
42  private static $_paCache = null;
43 
44  // Cache outcomes of calls to checkAccessOfuser
45  private static $_checkAccessOfUserCache = null;
46 
51  function ilRbacSystem()
52  {
53  global $ilDB,$ilErr,$ilias;
54 
55  $this->ilias =& $ilias;
56 
57  // set db & error handler
58  (isset($ilDB)) ? $this->ilDB =& $ilDB : $this->ilDB =& $ilias->db;
59 
60  if (!isset($ilErr))
61  {
62  $ilErr = new ilErrorHandling();
63  $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK,array($ilErr,'errorHandler'));
64  }
65  else
66  {
67  $this->ilErr =& $ilErr;
68  }
69  }
70 
90  function checkAccess($a_operations,$a_ref_id,$a_type = "")
91  {
92  global $ilUser,$ilBench;
93 
94  $ilBench->start("RBAC", "system_checkAccess");
95 
96  $result = $this->checkAccessOfUser($ilUser->getId(), $a_operations, $a_ref_id, $a_type);
97 
98  $ilBench->stop("RBAC", "system_checkAccess");
99 
100  return $result;
101  }
102 
103  function checkAccessOfUser($a_user_id, $a_operations, $a_ref_id, $a_type = "")
104  {
105  global $ilUser, $rbacreview,$ilObjDataCache,$ilDB;
106 
107  // Create the user cache key
108  $cacheKey = $a_user_id.':'.$a_operations.':'.$a_ref_id.':'.$a_type;
109 
110  // Create the cache if it does not yet exist
111  if (! is_array(self::$_checkAccessOfUserCache)) {
112  self::$_checkAccessOfUserCache = array();
113  }
114 
115  // Try to return result from cache
116  if (array_key_exists($cacheKey, self::$_checkAccessOfUserCache)) {
117  return self::$_checkAccessOfUserCache[$cacheKey];
118  }
119 
120  #echo ++$counter;
121 
122  // DISABLED
123  // Check For owner
124  // Owners do always have full access to their objects
125  // Excluded are the permissions create and perm
126  // This method call return all operations that are NOT granted by the owner status
127  if(!$a_operations = $this->__filterOwnerPermissions($a_user_id,$a_operations,$a_ref_id))
128  {
129  // Store positive outcome in cache.
130  // Note: we only cache up to 1000 results to avoid memory overflows
131  if (count(self::$_checkAccessOfUserCache) < 1000) {
132  self::$_checkAccessOfUserCache[$cacheKey] = true;
133  }
134  return true;
135  }
136 
137 
138  // get roles using role cache
139  $roles = $this->fetchAssignedRoles($a_user_id);
140 
141 
142  // exclude system role from rbac
143  if (in_array(SYSTEM_ROLE_ID, $roles))
144  {
145  // Store positive outcome in cache.
146  // Note: we only cache up to 1000 results to avoid memory overflows
147  if (count(self::$_checkAccessOfUserCache) < 1000) {
148  self::$_checkAccessOfUserCache[$cacheKey] = true;
149  }
150  return true;
151  }
152 
153  if (!isset($a_operations) or !isset($a_ref_id))
154  {
155  $this->ilErr->raiseError(get_class($this)."::checkAccess(): Missing parameter! ".
156  "ref_id: ".$a_ref_id." operations: ".$a_operations,$this->ilErr->WARNING);
157  }
158 
159  if (!is_string($a_operations))
160  {
161  $this->ilErr->raiseError(get_class($this)."::checkAccess(): Wrong datatype for operations!",$this->ilErr->WARNING);
162  }
163 
164  // Create the PA cache if it does not exist yet
165  $paCacheKey = $a_user_id.':'.$a_ref_id;
166  if (! is_array(self::$_paCache)) {
167  self::$_paCache = array();
168  }
169 
170  if (array_key_exists($paCacheKey, self::$_paCache)) {
171  // Return result from PA cache
172  $ops = self::$_paCache[$paCacheKey];
173  } else {
174  // Data is not in PA cache, perform database query
175  $q = "SELECT * FROM rbac_pa ".
176  "WHERE ref_id = ".$ilDB->quote($a_ref_id)." ";
177  $r = $this->ilDB->query($q);
178 
179  $ops = array();
180 
181  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
182  {
183  if (in_array($row->rol_id, $roles)) {
184  $ops = array_merge($ops,unserialize(stripslashes($row->ops_id)));
185  }
186  }
187 
188  // Cache up to 1000 entries in the PA cache
189  if (count(self::$_paCache) < 1000) {
190  self::$_paCache[$paCacheKey] = $ops;
191  }
192  }
193 
194  $operations = explode(",",$a_operations);
195  foreach ($operations as $operation)
196  {
197  if ($operation == "create")
198  {
199  if (empty($a_type))
200  {
201  $this->ilErr->raiseError(get_class($this)."::CheckAccess(): Expect a type definition for checking a 'create' permission",
202  $this->ilErr->WARNING);
203  }
204 
205  $ops_id = ilRbacReview::_getOperationIdByName($operation."_".$a_type);
206  }
207  else
208  {
209  $ops_id = ilRbacReview::_getOperationIdByName($operation);
210  }
211 
212  if (! in_array($ops_id,$ops)) {
213  // Store negative outcome in cache.
214  // Note: we only cache up to 1000 results to avoid memory overflows
215  if (count(self::$_checkAccessOfUserCache) < 1000) {
216  self::$_checkAccessOfUserCache[$cacheKey] = false;
217  }
218 
219  return false;
220  }
221  }
222 
223  // Store positive outcome in cache.
224  // Note: we only cache up to 1000 results to avoid memory overflows
225  if (count(self::$_checkAccessOfUserCache) < 1000) {
226  self::$_checkAccessOfUserCache[$cacheKey] = true;
227  }
228  return true;
229  }
230 
239  function checkPermission($a_ref_id,$a_rol_id,$a_operation)
240  {
241  global $ilDB;
242 
243  $ops = array();
244 
245  $q = "SELECT ops_id FROM rbac_operations ".
246  "WHERE operation = ".$ilDB->quote($a_operation)." ";
247 
248  $r = $this->ilDB->query($q);
249 
250  while($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
251  {
252  $ops_id = $row->ops_id;
253  }
254 
255  $q = "SELECT * FROM rbac_pa ".
256  "WHERE rol_id = ".$ilDB->quote($a_rol_id)." ".
257  "AND ref_id = ".$ilDB->quote($a_ref_id)." ";
258 
259  $r = $this->ilDB->query($q);
260 
261  while ($row = $r->fetchRow(DB_FETCHMODE_OBJECT))
262  {
263  $ops = array_merge($ops,unserialize(stripslashes($row->ops_id)));
264  }
265  return in_array($ops_id,$ops);
266  }
267 
268  function __filterOwnerPermissions($a_user_id,$a_operations,$a_ref_id)
269  {
270  global $ilObjDataCache;
271 
272  if($a_user_id != $ilObjDataCache->lookupOwner($ilObjDataCache->lookupObjId($a_ref_id)))
273  {
274  return $a_operations;
275  }
276  // Is owner
277  foreach(explode(",",$a_operations) as $operation)
278  {
279  if($operation != 'cat_administrate_users' and $operation != 'edit_permission' and !preg_match('/^create/',$operation))
280  {
281  continue;
282  }
283  if(!strlen($new_ops))
284  {
285  $new_ops = $operation;
286  }
287  else
288  {
289  $new_ops .= (','.$operation);
290  }
291  }
292  return $new_ops;
293  }
294 
303  private function fetchAssignedRoles($a_usr_id)
304  {
305  global $ilUser,$rbacreview;
306 
307  if(isset(self::$user_role_cache[$a_usr_id]) and is_array(self::$user_role_cache))
308  {
309  return self::$user_role_cache[$a_usr_id];
310  }
311  return self::$user_role_cache[$a_usr_id] = $rbacreview->assignedRoles($a_usr_id);
312  }
313 
314 } // END class.RbacSystem
315 ?>