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
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 class aliroAuthoriserCache extends cachedSingleton {
00053 protected static $instance= __CLASS__;
00054
00055 private $linked_roles = array();
00056 private $user_roles = array();
00057 private $all_roles = array();
00058 private $all_subjects = array();
00059 private $translations = array (
00060 'Registered' => 'Registered(translated)',
00061 'Visitor' => 'Visitor(translated)',
00062 'Nobody' => 'Nobody(translated)',
00063 'none' => 'None of these(trans)'
00064 );
00065
00066 protected function __construct () {
00067
00068 $database = aliroCoreDatabase::getInstance();
00069 $database->setQuery("SELECT role, implied FROM #__role_link UNION SELECT DISTINCT role, role AS implied FROM #__assignments UNION SELECT DISTINCT role, role AS implied FROM #__permissions");
00070 $links = $database->loadObjectList();
00071 if ($links) foreach ($links as $link) {
00072 $this->all_roles[$link->role] = $link->role;
00073 $this->linked_roles[$link->role][$link->implied] = 1;
00074 foreach ($this->linked_roles as $role=>$impliedarray) {
00075 foreach ($impliedarray as $implied=>$marker) {
00076 if ($implied == $link->role OR $implied == $link->implied) {
00077 $this->linked_roles[$role][$link->implied] = 1;
00078 if (isset($this->linked_roles[$link->implied])) foreach ($this->linked_roles[$link->implied] as $more=>$marker) {
00079 $this->linked_roles[$role][$more] = 1;
00080 }
00081 }
00082 }
00083 }
00084 }
00085 $user_roles = $database->doSQLget("SELECT role, access_id FROM #__assignments WHERE access_type = 'aUser' AND (access_id = '*' OR access_id = '0')");
00086 foreach ($user_roles as $role) $this->user_roles[$role->access_id][$role->role] = 1;
00087 if (!isset($this->user_roles['0'])) $this->user_roles['0'] = array();
00088 if (isset($this->user_roles['*'])) $this->user_roles['0'] = array_merge($this->user_roles['0'], $this->user_roles['*']);
00089 $allsubject = $database->doSQLget("SELECT role, control, action FROM #__permissions WHERE subject_type = '*' AND subject_id - '*'");
00090 foreach ($allsubject as $asub) $this->all_subjects[$asub->role] = $asub;
00091
00092 }
00093
00094 public static function getInstance () {
00095 return is_object(self::$instance) ? self::$instance : (self::$instance = parent::getCachedSingleton(self::$instance));
00096 }
00097
00098 public function getTranslatedRole ($role) {
00099 if (isset($this->translations[$role])) return $this->translations[$role];
00100 else return $role;
00101 }
00102
00103 public function getAllRoles ($addSpecial=false) {
00104 $roles = $this->all_roles;
00105 if ($addSpecial) foreach ($this->translations as $raw=>$translated) $roles[$raw] = $translated;
00106 return $roles;
00107 }
00108
00109 public function barredRole ($role) {
00110 if (isset($this->translations[$role])) return true;
00111 else return false;
00112 }
00113
00114 public function getLinkedRoles () {
00115 return $this->linked_roles;
00116 }
00117
00118 public function getUserRoles ($id) {
00119 return isset($this->user_roles[$id]) ? array_keys($this->user_roles[$id]) : array();
00120 }
00121
00122 public function canRoleAccessAll ($role, $action, $control) {
00123 if (isset($this->all_subjects[$role])) {
00124 $asub = $this->all_subjects[$role];
00125 if ($action == $asub->action AND ($control & $asub->control)) return true;
00126 }
00127 return false;
00128 }
00129
00130 }
00131
00132
00133 class aliroAuthoriser {
00134 private static $instance = __CLASS__;
00135
00136 private $subj_found = array();
00137 private $permissions = array();
00138 private $access_found = array();
00139 private $access_roles = array();
00140
00141 private $linked_roles = array();
00142 private $auth_vars = array ('subj_found', 'permissions', 'access_found', 'access_roles');
00143 private $old_groupids = array ('Registered' => 18, 'Author' => 19, 'Editor' => 20, 'Publisher' => 21, 'Manager' => 23, 'Administrator' => 24, 'Super Administrator' => 25);
00144
00145 private $handler = null;
00146 private $database = null;
00147
00148 private function __construct () {
00149
00150 aliroSessionFactory::getSession();
00151
00152 foreach ($this->auth_vars as $one_var) {
00153 if (!isset($_SESSION['aliro_auth'][$one_var])) $_SESSION['aliro_auth'][$one_var] = array();
00154 $this->$one_var =& $_SESSION['aliro_auth'][$one_var];
00155 }
00156 $this->handler = aliroAuthoriserCache::getInstance();
00157 $this->linked_roles = $this->handler->getLinkedRoles();
00158 $this->database = aliroCoreDatabase::getInstance();
00159 }
00160
00161 private function __clone () {
00162
00163 }
00164
00165 public static function getInstance () {
00166 return is_object(self::$instance) ? self::$instance : (self::$instance = new self::$instance());
00167 }
00168
00169 public function clearCache () {
00170 $this->subj_found = $this->permissions = $this->access_found = $this->access_roles = $this->refused_cache = array();
00171 }
00172
00173 public function getAllRoles ($addSpecial=false) {
00174 return $this->handler->getAllRoles($addSpecial);
00175 }
00176
00177 public function getTranslatedRole ($role) {
00178 return $this->handler->getTranslatedRole($role);
00179 }
00180
00181 public function minimizeRoleSet ($roleset) {
00182 if (0 == count($roleset)) return $roleset;
00183 $first = array_shift($roleset);
00184 foreach ($roleset as $key=>$role) {
00185 if (isset($this->linked_roles[$first][$role])) unset ($roleset[$key]);
00186 if (isset($this->linked_roles[$role][$first])) return $this->minimizeRoleSet ($roleset);
00187 }
00188 array_unshift($roleset, $first);
00189 return $roleset;
00190 }
00191
00192 private function getSubjectData ($subject, $id, $action) {
00193 $stamp = time();
00194 if (isset($this->subj_found[$subject][$action][$id]) AND (($stamp - $this->subj_found[$subject][$action][$id]) < _ALIRO_AUTHORISER_SESSION_CACHE_TIME)) return;
00195 if (isset($this->subj_found[$subject][$action]['*']) AND ($stamp - $this->subj_found[$subject][$action]['*'] < _ALIRO_AUTHORISER_SESSION_CACHE_TIME)) return;
00196 $this->database->setQuery("SELECT COUNT(*) FROM `#__permissions` WHERE `subject_type`='$subject' AND (`action`='$action' OR `action`='*')");
00197 if ($this->database->loadResult() < 100) {
00198 $this->database->setQuery("SELECT `role`, `control`, `subject_id`, `action` FROM `#__permissions` WHERE `subject_type`='$subject' AND (`action`='$action' OR `action`='*')");
00199 $new_permissions = $this->database->loadObjectList();
00200 unset($this->subj_found[$subject][$action]);
00201 $this->subj_found[$subject][$action]['*'] = $stamp;
00202 }
00203 else {
00204 $this->database->setQuery("SELECT role, control, subject_id, action FROM #__permissions WHERE subject_type='$subject' AND (subject_id='$id' OR subject_id='*') AND (action='$action' OR action='*')");
00205 $new_permissions = $this->database->loadObjectList();
00206 unset($this->subj_found[$subject][$action][$id]);
00207 }
00208 if ($new_permissions) {
00209 foreach ($new_permissions as $permit) {
00210 $this->permissions[$subject][$permit->action][$permit->subject_id][$permit->role] = $permit->control;
00211 $this->subj_found[$subject][$permit->action][$permit->subject_id] = $stamp;
00212 }
00213 }
00214 }
00215
00216 public function getAccessorRoles ($type, $id) {
00217 if ('aUser' == $type AND ('0' == $id OR '*' == $id)) return $this->handler->getUserRoles($id);
00218 if (isset($this->access_found[$type][$id])) {
00219 if ((time() - $this->access_found[$type][$id]) < _ALIRO_AUTHORISER_SESSION_CACHE_TIME) {
00220 return $this->mergeAccessorResults($type, $id);
00221 }
00222 unset ($this->access_found);
00223 $this->access_roles = array();
00224 }
00225 $sql = "SELECT role, access_id FROM #__assignments AS a WHERE a.access_type='$type'";
00226 $sql .= isset($this->access_found[$type]) ? " AND a.access_id='$id'" : " AND (a.access_id='$id' OR a.access_id='*' OR a.access_id='+')";
00227 $this->database->setQuery($sql);
00228 if ($results = $this->database->loadObjectList()) {
00229 foreach ($results as $result) {
00230 $this->access_roles[$type][$result->access_id][$result->role] = 1;
00231 }
00232 }
00233 $this->access_found[$type][$id] = time();
00234 return $this->mergeAccessorResults($type, $id);
00235 }
00236
00237 private function mergeAccessorResults ($type, $id) {
00238 if (isset($this->access_roles[$type][$id])) $result = $this->access_roles[$type][$id];
00239 else $result = array();
00240 if (isset($this->access_roles[$type]['*'])) $result = array_merge($result, $this->access_roles[$type]['*']);
00241 if ($id AND isset($this->access_roles[$type]['+'])) $result = array_merge($result, $this->access_roles[$type]['+']);
00242 if ('aUser' == $type AND $id) $result['Registered'] = 1;
00243 if (count($result)) return array_keys ($result);
00244 else return array();
00245 }
00246
00247 private function blanket ($action, $type) {
00248 return (isset($this->permissions[$type][$action]['*']) AND count($this->permissions[$type][$action]['*']));
00249 }
00250
00251 private function specific ($action, $type, $id) {
00252 return (isset($this->permissions[$type][$action][$id]) AND count($this->permissions[$type][$action][$id]));
00253 }
00254
00255 private function accessorPermissionOrControl ($mask, $a_type, $a_id, $action, $s_type='*', $s_id='*') {
00256 $this->getSubjectData ($s_type, $s_id, $action);
00257 if ('*' != $s_type AND 2 == $mask AND !$this->blanket($action, $s_type) AND !($this->specific($action, $s_type, $s_id))) return 1;
00258 if ((!isset($this->permissions[$s_type][$action][$s_id]) OR 0 == count($this->permissions[$s_type][$action][$s_id]))
00259 AND (!isset($this->permissions[$s_type][$action]['*']) OR 0 == count($this->permissions[$s_type][$action]['*']))) return 1;
00260 $roles = $this->getAccessorRoles ($a_type, $a_id);
00261 return $this->rolePermissionOrControl ($mask, $roles, $action, $s_type, $s_id);
00262 }
00263
00264 public function checkPermission ($a_type, $a_id, $action, $s_type='*', $s_id='*') {
00265 return $this->accessorPermissionOrControl(2, $a_type, $a_id, $action, $s_type, $s_id);
00266 }
00267
00268 public function checkUserPermission ($action, $s_type='*', $s_id='*') {
00269 $user = aliroUser::getInstance();
00270 return $this->checkPermission ('aUser', $user->id, $action, $s_type, $s_id);
00271 }
00272
00273 public function checkControl ($a_type, $a_id, $action, $s_type='*', $s_id='*') {
00274 return $this->accessorPermissionOrControl(1, $a_type, $a_id, $action, $s_type, $s_id);
00275 }
00276
00277 public function checkGrant ($a_type, $a_id, $action, $s_type='*', $s_id='*') {
00278 return $this->accessorPermissionOrControl(4, $a_type, $a_id, $action, $s_type, $s_id);
00279 }
00280
00281 private function rolePermissionOrControl ($mask, $roles, $actions, $s_type, $s_id) {
00282 foreach ((array) $roles as $role) {
00283 foreach ((array) $actions as $action) if ($this->handler->canRoleAccessAll ($role, $action, $mask)) return 1;
00284 }
00285 foreach ((array) $actions as $action) $this->getSubjectData ($s_type, $s_id, $action);
00286 if (in_array('Visitor', (array) $roles)) {
00287 foreach ((array) $actions as $action) {
00288 if (empty($this->permissions[$s_type][$action][$s_id])) return 1;
00289 }
00290 }
00291 if (count((array) $roles)) foreach ($this->permissions[$s_type] as $act=>$level2) {
00292 if (!in_array($act, (array) $actions) AND !in_array('*', (array) $actions)) continue;
00293 foreach ($level2 as $id=>$level3) {
00294 if ($id != $s_id AND $id != '*') continue;
00295 foreach ($level3 as $role=>$control)
00296 if (in_array($role, (array) $roles) AND ($mask & $control)) {
00297 return 1;
00298 }
00299 }
00300 }
00301 return 0;
00302 }
00303
00304 public function checkRolePermission ($role, $action, $s_type, $s_id) {
00305 return $this->rolePermissionOrControl(2, $role, $action, $s_type, $s_id);
00306 }
00307
00308 public function checkRoleControl ($role, $action, $s_type, $s_id) {
00309 return $this->rolePermissionOrControl(1, $role, $action, $s_type, $s_id);
00310 }
00311
00312 public function checkRoleGrant ($role, $action, $s_type, $s_id) {
00313 return $this->rolePermissionOrControl(4, $role, $action, $s_type, $s_id);
00314 }
00315
00316 function getRefusedList ($a_type, $a_id, $s_type, $actionlist) {
00317 $roles = $this->getAccessorRoles($a_type, $a_id);
00318 $actions = explode(',', $actionlist);
00319 foreach ($actions as $i=>$action) $actions[$i] = trim($action);
00320 $alist = implode("','", $actions);
00321 $this->database->setQuery("SELECT role, subject_id, action FROM #__permissions WHERE subject_type = '$s_type' AND action IN('$alist')");
00322 $results = $this->database->loadObjectList();
00323 if ($results) foreach ($results as $result) $ids[$result->subject_id][$result->action][] = $result->role;
00324 if (isset($ids)) {
00325 $refused = array_keys($ids);
00326 foreach ($ids as $id=>$actionset) {
00327 foreach ($actions as $action) if (!isset($actionset[$action])) $permits[$id] = 1;
00328 if (!isset($permits[$id])) foreach ($actionset as $action=>$permittedroles) {
00329 if (count(array_intersect($permittedroles, $roles))) $permits[$id] = 1;
00330 }
00331 }
00332 if (isset($permits)) $refused = array_diff ($refused, array_keys($permits));
00333 }
00334 else $refused = array();
00335 return $refused;
00336 }
00337
00338 public function getRefusedListSQL ($a_type, $a_id, $s_type, $actionlist, $keyname) {
00339 $refused = $this->getRefusedList ($a_type, $a_id, $s_type, $actionlist);
00340 if (count($refused)) {
00341 $excludelist = implode("','", $refused);
00342 return " CAST($keyname AS CHAR) NOT IN ('$excludelist')";
00343 }
00344 return '';
00345 }
00346
00347 public function listPermissions ($a_type, $a_id, $action) {
00348 $roles = $this->getAccessorRoles ($a_type, $a_id);
00349 $role_list = "IN ('".implode("','", $roles)."')";
00350 $this->database->setQuery("SELECT DISTINCT subject_type FROM #__permissions WHERE role $role_list AND action='$action' AND (control & 2) ORDER BY subject_type");
00351 $subjects = $this->database->loadResultArray();
00352 return $subjects;
00353 }
00354
00355 public function &listUserPermissions ($action) {
00356 $user = aliroUser::getInstance();
00357 $results = $this->listPermissions ('aUser', $user->id, $action);
00358 return $results;
00359 }
00360
00361 public function listAccessors ($accessor_type, $role) {
00362 $this->database->setQuery("SELECT access_id FROM #__assignments WHERE access_type = '$accessor_type' AND role = '$role'");
00363 $result = $this->database->loadResultArray();
00364 return $result ? $result : array();
00365 }
00366
00367
00368 public function acl_check($aco_section_value, $aco_value,
00369 $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL) {
00370 if ($axo_section_value == 'components') return $this->checkUserPermission ($aro_value, 'aliroComponent', $axo_value);
00371 return false;
00372 }
00373
00374 public function getAroGroup ($id) {
00375 $old_roles = array_keys ($this->old_groupids);
00376 array_unshift($old_roles, '');
00377 $roles = $this->getAccessorRoles('aUser', $id);
00378 $max = 0;
00379 foreach ($roles as $role) {
00380 $key = array_search($role, $old_roles);
00381 if ($key AND $key > $max) $max = $key;
00382 }
00383 $result = new stdClass();
00384 $result->name = $old_roles[$max];
00385 return $result;
00386 }
00387
00388 public function get_group_name ($gid) {
00389 if (is_int($gid)) {
00390 $group = array_search($gid, $this->old_groupids);
00391 return $group;
00392 }
00393 return $gid;
00394 }
00395
00396 public function get_group_children_tree ($root_id=null, $root_name=null, $inclusive=true) {
00397 if (null == $root_id AND true == $inclusive) {
00398 if ('Registered' == $root_name) {
00399 $result = unserialize('a:4:{i:0;O:8:"stdClass":2:{s:5:"value";s:2:"18";s:4:"text";s:17:"- Registered";}i:1;O:8:"stdClass":2:{s:5:"value";s:2:"19";s:4:"text";s:49:" - Author";}i:2;O:8:"stdClass":2:{s:5:"value";s:2:"20";s:4:"text";s:85:" - Editor";}i:3;O:8:"stdClass":2:{s:5:"value";s:2:"21";s:4:"text";s:124:" - Publisher";}}');
00400 return $result;
00401 }
00402 if ('Public Backend' == $root_name) {
00403 $result = unserialize('a:4:{i:0;O:8:"stdClass":2:{s:5:"value";s:2:"30";s:4:"text";s:21:"- Public Backend";}i:1;O:8:"stdClass":2:{s:5:"value";s:2:"23";s:4:"text";s:50:" - Manager";}i:2;O:8:"stdClass":2:{s:5:"value";s:2:"24";s:4:"text";s:92:" - Administrator";}i:3;O:8:"stdClass":2:{s:5:"value";s:2:"25";s:4:"text";s:134:" - Super Administrator";}}');
00404 return $result;
00405 }
00406 trigger_error('Aliro emulation of get_group_children_tree needs extending');
00407 }
00408 else {
00409 foreach ($this->getAllRoles(true) as $i=>$role) $option[] = aliroHTML::makeOption($role, $role);
00410 return isset($option) ? $option : array();
00411 }
00412 }
00413
00414 public function get_object_groups ($object_section_value, $object_value, $object_type=NULL) {
00415 return $this->getAllRoles(true);
00416 }
00417
00418 public function get_group_children ($root_id=null, $root_name=null, $inclusive=true) {
00419 return array();
00420 }
00421
00422 }