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 class aliroAuthorisationAdmin {
00046 private static $instance = __CLASS__;
00047
00048 private $handler = null;
00049 private $authoriser = null;
00050 private $database = null;
00051
00052 private function __construct () {
00053 $this->handler = aliroAuthoriserCache::getInstance();
00054 $this->authoriser = aliroAuthoriser::getInstance();
00055 $this->database = aliroCoreDatabase::getInstance();
00056 }
00057
00058 private function __clone () {
00059
00060 }
00061
00062 public static function getInstance () {
00063 return is_object(self::$instance) ? self::$instance : (self::$instance = new self::$instance());
00064 }
00065
00066 private function doSQL ($sql, $clear=false) {
00067 $this->database->doSQL($sql);
00068 if ($clear) $this->clearCache();
00069 }
00070
00071 private function clearCache () {
00072 $this->handler->clearCache();
00073 $this->authoriser->clearCache();
00074 }
00075
00076 public function getAllRoles ($addSpecial=false) {
00077 return $this->authoriser->getAllRoles($addSpecial);
00078 }
00079
00080 public function getTranslatedRole ($role) {
00081 return $this->authoriser->getTranslatedRole($role);
00082 }
00083
00084 private function &permissionHolders ($subject_type, $subject_id) {
00085 $sql = "SELECT DISTINCT role, action, control, subject_type, subject_id FROM #__permissions";
00086 if ($subject_type != '*') $where[] = "(subject_type='$subject_type' OR subject_type='*')";
00087 if ($subject_id != '*') $where[] = "(subject_id='$subject_id' OR subject_id='*')";
00088 if (isset($where)) $sql .= " WHERE ".implode(' AND ', $where);
00089 $result = $this->database->doSQLget($sql);
00090 return $result;
00091 }
00092
00093 public function permittedRoles ($actions, $subject_type, $subject_id, $excluding=null) {
00094 $nonspecific = true;
00095 foreach ($this->permissionHolders ($subject_type, $subject_id) as $possible) {
00096 if ('*' == $possible->action OR in_array($possible->action, (array) $actions)) {
00097 $result[$possible->role] = $this->getTranslatedRole($possible->role);
00098 if ('*' != $possible->subject_type AND '*' != $possible->subject_id) $nonspecific = false;
00099 }
00100 }
00101 if (!isset($result) OR $nonspecific) $result['Visitor'] = $this->getTranslatedRole('Visitor');
00102 foreach ((array) $excluding as $exclude) if (isset($result[$exclude])) unset($result[$exclude]);
00103 return $result;
00104 }
00105
00106 private function &nonLocalPermissionHolders ($subject_type, $subject_id) {
00107 $sql = "SELECT role, action, control FROM #__permissions WHERE (action='*' OR subject_type='*' OR subject_id='*') AND ((subject_type='$subject_type' OR subject_type='*') AND (subject_id='$subject_id' OR subject_id='*'))";
00108 return $this->database->doSQLget($sql);
00109 }
00110
00111 private function permitSQL ($role, $control, $action, $subject_type, $subject_id) {
00112 $this->database->setQuery("SELECT id FROM #__permissions WHERE role='$role' AND action='$action' AND subject_type='$subject_type' AND subject_id='$subject_id'");
00113 $id = $this->database->loadResult();
00114 if ($id) return "UPDATE #__permissions SET control=$control WHERE id=$id";
00115 else return "INSERT INTO #__permissions (role, control, action, subject_type, subject_id) VALUES ('$role', '$control', '$action', '$subject_type', '$subject_id')";
00116 }
00117
00118 public function permit ($role, $control, $action, $subject_type, $subject_id) {
00119 $sql = $this->permitSQL($role, $control, $action, $subject_type, $subject_id);
00120 $this->doSQL($sql, true);
00121 }
00122
00123 public function assign ($role, $access_type, $access_id, $clear=true) {
00124 if ($this->handler->barredRole($role)) return false;
00125 $this->database->setQuery("SELECT id FROM #__assignments WHERE role='$role' AND access_type='$access_type' AND access_id='$access_id'");
00126 if ($this->database->loadResult()) return true;
00127 $sql = "INSERT INTO #__assignments (role, access_type, access_id) VALUES ('$role', '$access_type', '$access_id')";
00128 $this->doSQL($sql, $clear);
00129 return true;
00130 }
00131
00132 public function unassign ($role, $access_type, $access_id) {
00133 $this->database->doSQL("DELETE FROM #__assignments WHERE role='$role' AND access_type='$access_type' AND access_id='$access_id'", true);
00134 return true;
00135 }
00136
00137 public function assignRoleSet ($roleset, $access_type, $access_id) {
00138 $this->dropAccess ($access_type, $access_id);
00139 $roleset = $this->authoriser->minimizeRoleSet($roleset);
00140 foreach ($roleset as $role) $this->assign ($role, $access_type, $access_id, false);
00141 $this->clearCache();
00142 }
00143
00144 public function dropAccess ($access_type, $access_id) {
00145 $sql = "DELETE FROM #__assignments WHERE access_type='$access_type' AND access_id='$access_id'";
00146 $this->doSQL($sql, true);
00147 }
00148
00149 public function &getMyControllingRoles ($action, $subject_type, $subject_id) {
00150 $user = aliroUser::getInstance();
00151 $sql = "SELECT a.role FROM #__permissions AS p INNER JOIN #__assignments AS a ON a.role=p.role"
00152 ." WHERE a.access_type='aUser'"
00153 ." AND a.access_id='$user->id' AND (p.control&1)"
00154 ." AND p.action='$action' AND p.subject_type='$subject_type' AND p.subject_id='$subject_id'";
00155 $this->doSQL($sql);
00156 $roles = $this->database->loadResultArray();
00157 return $roles;
00158 }
00159
00160 public function &getMyPermissions () {
00161 $user = aliroUser::getInstance();
00162 $sql = 'SELECT p.action, p.subject_type, p.subject_id, control '
00163 . ' FROM #__permissions AS p INNER JOIN #__assignments AS a ON p.role=a.role '
00164 . " WHERE a.access_type='aUser' AND (a.access_id='$user->id' OR a.access_id='*')"
00165 . ' AND (p.control&1)';
00166 $this->doSQL($sql);
00167 $permissions = $this->database->loadObjectList();
00168 return $permissions;
00169 }
00170
00171 public function getMyJointPermissions ($role) {
00172 $user = aliroUser::getInstance();
00173 $sql = "SELECT p2.control AS hiscontrol, p1.control AS mycontrol, p1.action, p1.subject_type, p1.subject_id"
00174 ." FROM `#__assignments` AS a INNER JOIN `#__permissions` AS p1 ON p1.role=a.role "
00175 ." LEFT JOIN `#__permissions` AS p2"
00176 ." ON (p2.role='$role' AND p1.action=p2.action AND p1.subject_type=p2.subject_type AND p1.subject_id=p2.subject_id)"
00177 ." WHERE (p1.control&1) AND a.access_type='aUser' AND (a.access_id='$user->id' OR a.access_id='*')";
00178 $this->doSQL($sql);
00179 $permissions = $this->database->loadObjectList();
00180 return $permissions;
00181 }
00182
00183 public function getAccessLists ($access_type, $access_id, $action, $subject_type, $subject_id) {
00184 if ($this->authoriser->checkControl($access_type, $access_id, $action, $subject_type, $subject_id)) {
00185 $cangrant = $this->authoriser->checkGrant($access_type, $access_id, $action, $subject_type, $subject_id);
00186 $permissions = $this->permissionHolders($subject_type, $subject_id);
00187 $allroles = $this->getAllRoles();
00188 $alirohtml = aliroHTML::getInstance();
00189 foreach ($allroles as $role) {
00190 $itemc[] = $optionc = $alirohtml->makeOption($role, $role);
00191 $itema[] = $optiona = $alirohtml->makeOption($role, $role);
00192 if ($cangrant) $itemg[] = $optiong = $alirohtml->makeOption($role, $role);
00193 foreach ($permissions as $permission) {
00194 if (($permission->action == '*' OR $permission->action == $action) AND $permission->role == $role) {
00195 if ($permission->control & 1) $cselected[] = $optionc;
00196 if ($permission->control & 2) $aselected[] = $optiona;
00197 if ($cangrant AND $permission->control & 4) $gselected[] = $optiong;
00198 }
00199 }
00200 }
00201 $results[] = $alirohtml->selectList($itema, $action.'_arole[]', 'multiple="multiple"', 'value', 'text', $aselected);
00202 $results[] = $alirohtml->selectList($itemc, $action.'_crole[]', 'multiple="multiple"', 'value', 'text', $cselected);
00203 if ($cangrant) $results[] = $alirohtml->selectList($itemg, $action.'_grole[]', 'multiple="multiple"', 'value', 'text', $gselected);
00204 }
00205 else $results = array();
00206 return $results;
00207 }
00208
00209 public function resetPermissions ($action, $subject_type, $subject_id) {
00210 $control_types = array ('crole', 'arole', 'grole');
00211 $control_values = array (1,2,4);
00212 $permissions = $this->nonLocalPermissionHolders($subject_type, $subject_id);
00213 $this->dropPermissions($action, $subject_type, $subject_id);
00214 foreach ($control_types as $i=>$type) {
00215 $key = $action.'_'.$type;
00216 if (isset($_POST[$key])) {
00217 foreach ($_POST[$key] as $role) {
00218 $value = isset($newpermits[$role]) ? $newpermits[$role] : 0;
00219 $newpermits[$role] = $value | $control_values[$i];
00220 }
00221 }
00222 }
00223 $sql = '';
00224 foreach ($newpermits as $role=>$value) {
00225 $needed = true;
00226 foreach ($permissions as $permission) {
00227 if (($permission->action == '*' OR $permission->action == $action) AND $permission->role == $role) {
00228 if (($value & $permission->control) === $value) {
00229 $needed = false;
00230 break;
00231 }
00232 }
00233 }
00234 if ($needed) $sql .= $this->permitSQL ($role, $value, $action, $subject_type, $subject_id);
00235 }
00236 if ($sql) $this->doSQL($sql, true);
00237 }
00238
00239 public function roleExists ($role) {
00240 return in_array($role, $this->getAllRoles());
00241 }
00242
00243 public function dropRole ($role) {
00244 $sql = "DELETE FROM #__permissions WHERE action='administer' AND subject_type='$role' AND system=0";
00245 $this->doSQL($sql);
00246 $sql = "DELETE a FROM #__assignments AS a LEFT JOIN #__permissions AS p ON a.role=p.role WHERE a.role='$role' AND (p.system=0 OR p.system IS NULL)";
00247 $this->doSQL($sql);
00248 $sql = "DELETE FROM #__permissions WHERE role='$role' AND system=0";
00249 $this->doSQL($sql, true);
00250 }
00251
00252 public function dropPermissions ($action, $subject_type, $subject_id) {
00253 $sql = "DELETE FROM #__permissions WHERE action='$action' AND subject_type='$subject_type'AND subject_id='$subject_id' AND system=0";
00254 $this->doSQL($sql, true);
00255 }
00256
00257 }