public function testBooleanOperators() { $vo_acr = AccessRestrictions::load(true); // OR $va_access_restrictions = array("administrate/setup/list_editor/ListEditorController" => array("default" => array("operator" => "OR", "actions" => array("can_edit_ca_lists", "can_create_ca_lists", "can_delete_ca_lists")))); $vo_acr->opa_acr = $va_access_restrictions; // no role -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions(array()); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has one of the OR-ed roles -> can access controller $this->opt_role->setMode(ACCESS_WRITE); $va_actions = $va_access_restrictions["administrate/setup/list_editor/ListEditorController"]["default"]["actions"]; $this->opt_role->setRoleActions(array($va_actions[array_rand($va_actions)])); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertTrue($vb_access); // AND $va_access_restrictions = array("administrate/setup/list_editor/ListEditorController" => array("default" => array("operator" => "AND", "actions" => array("can_edit_ca_lists", "can_create_ca_lists", "can_delete_ca_lists")))); $vo_acr->opa_acr = $va_access_restrictions; // no role -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions(array()); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has one of the AND-ed roles -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $va_actions = $va_access_restrictions["administrate/setup/list_editor/ListEditorController"]["default"]["actions"]; $this->opt_role->setRoleActions(array($va_actions[array_rand($va_actions)])); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has all AND-ed roles -> can access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions($va_actions); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertTrue($vb_access); }
/** * Checks if user is allowed to perform the specified action (possible actions are defined in app/conf/user_actions.conf) * Returns true if user can do action, false otherwise. */ public function canDoAction($ps_action) { $vs_cache_key = $ps_action . "/" . $this->getPrimaryKey(); if (isset(ca_users::$s_user_action_access_cache[$vs_cache_key])) { return ca_users::$s_user_action_access_cache[$vs_cache_key]; } if (!$this->getPrimaryKey()) { return ca_users::$s_user_action_access_cache[$vs_cache_key] = false; } // "empty" ca_users object -> no groups or roles associated -> can't do action if (!ca_user_roles::isValidAction($ps_action)) { return ca_users::$s_user_action_access_cache[$vs_cache_key] = false; } // return false if action is not valid // is user administrator? if ($this->getPrimaryKey() == $this->_CONFIG->get('administrator_user_id')) { return ca_users::$s_user_action_access_cache[$vs_cache_key] = true; } // access restrictions don't apply to user with user_id = admin id // get user roles $va_roles = $this->getUserRoles(); foreach ($this->getGroupRoles() as $vn_role_id => $va_role_info) { $va_roles[$vn_role_id] = $va_role_info; } $va_actions = ca_user_roles::getActionsForRoleIDs(array_keys($va_roles)); if (in_array('is_administrator', $va_actions)) { return ca_users::$s_user_action_access_cache[$vs_cache_key] = true; } // access restrictions don't apply to users with is_administrator role return ca_users::$s_user_action_access_cache[$vs_cache_key] = in_array($ps_action, $va_actions); }
public function processRoles() { require_once __CA_MODELS_DIR__ . "/ca_user_roles.php"; $va_roles = array(); if ($this->ops_base_name) { // "merge" profile and its base if ($this->opo_base->roles) { foreach ($this->opo_base->roles->children() as $vo_role) { $va_roles[self::getAttribute($vo_role, "code")] = $vo_role; } } if ($this->opo_profile->roles) { foreach ($this->opo_profile->roles->children() as $vo_role) { $va_roles[self::getAttribute($vo_role, "code")] = $vo_role; } } } else { if ($this->opo_profile->roles) { foreach ($this->opo_profile->roles->children() as $vo_role) { $va_roles[self::getAttribute($vo_role, "code")] = $vo_role; } } } foreach ($va_roles as $vs_role_code => $vo_role) { $t_role = $this->opb_updating ? ca_user_roles::find(array('code' => $vs_role_code), array('returnAs' => 'firstModelInstance')) : false; $t_role = $t_role ? $t_role : new ca_user_roles(); $t_role->setMode(ACCESS_WRITE); $t_role->set('name', trim((string) $vo_role->name)); $t_role->set('description', trim((string) $vo_role->description)); $t_role->set('code', $vs_role_code); // add actions $va_actions = array(); if ($vo_role->actions) { foreach ($vo_role->actions->children() as $vo_action) { $va_actions[] = trim((string) $vo_action); } } $t_role->setRoleActions($va_actions); if ($t_role->getPrimaryKey()) { $t_role->update(); } else { $t_role->insert(); } if ($t_role->numErrors()) { $this->addError("Errors inserting access role {$vs_role_code}: " . join("; ", $t_role->getErrors())); return false; } // add bundle level ACL items if ($vo_role->bundleLevelAccessControl) { foreach ($vo_role->bundleLevelAccessControl->children() as $vo_permission) { $vs_permission_table = self::getAttribute($vo_permission, 'table'); $vs_permission_bundle = self::getAttribute($vo_permission, 'bundle'); $vn_permission_access = $this->_convertACLStringToConstant(self::getAttribute($vo_permission, 'access')); if (!$t_role->setAccessSettingForBundle($vs_permission_table, $vs_permission_bundle, $vn_permission_access)) { $this->addError("Could not add bundle level access control for table '{$vs_permission_table}' and bundle '{$vs_permission_bundle}'. Check the table and bundle names."); //return false; } } } // add type level ACL items if ($vo_role->typeLevelAccessControl) { foreach ($vo_role->typeLevelAccessControl->children() as $vo_permission) { $vs_permission_table = self::getAttribute($vo_permission, 'table'); $vs_permission_type = self::getAttribute($vo_permission, 'type'); $vn_permission_access = $this->_convertACLStringToConstant(self::getAttribute($vo_permission, 'access')); if (!$t_role->setAccessSettingForType($vs_permission_table, $vs_permission_type, $vn_permission_access)) { $this->addError("Could not add type level access control for table '{$vs_permission_table}' and type '{$vs_permission_type}'. Check the table name and the type code."); //return false; } } } // add source level ACL items if ($vo_role->sourceLevelAccessControl) { foreach ($vo_role->sourceLevelAccessControl->children() as $vo_permission) { $vs_permission_table = self::getAttribute($vo_permission, 'table'); $vs_permission_source = self::getAttribute($vo_permission, 'source'); $vs_permission_default = self::getAttribute($vo_permission, 'default'); $vn_permission_access = $this->_convertACLStringToConstant(self::getAttribute($vo_permission, 'access')); if (!$t_role->setAccessSettingForSource($vs_permission_table, $vs_permission_source, $vn_permission_access, (bool) $vs_permission_default)) { $this->addError("Could not add source level access control for table '{$vs_permission_table}' and source '{$vs_permission_source}'. Check the table name and the source code."); //return false; } } } } return true; }
/** * Determines if $ps_action is a valid user action * * @param string $ps_action A user action code to test * @return bool True if code is valid, false if not */ public static function isValidAction($ps_action) { $va_actions = ca_user_roles::loadRoleActionList(); if (isset($va_actions['flattened'][$ps_action])) { return true; } return false; }
public function getRolesAsDOM() { $t_role = new ca_user_roles(); $t_list = new ca_lists(); $t_ui_screens = new ca_editor_ui_screens(); $vo_roles = $this->opo_dom->createElement("roles"); $qr_roles = $this->opo_db->query("SELECT * FROM ca_user_roles"); while ($qr_roles->nextRow()) { $t_role->load($qr_roles->get("role_id")); $vo_role = $this->opo_dom->createElement("role"); $vo_role->setAttribute("code", $this->makeIDNO($t_role->get("code"))); $vo_role->appendChild($this->opo_dom->createElement("name", $t_role->get("name"))); $vo_role->appendChild($this->opo_dom->createElement("description", $t_role->get("description"))); if (is_array($va_actions = $t_role->getRoleActions())) { $vo_actions = $this->opo_dom->createElement("actions"); foreach ($va_actions as $vs_action) { $vo_actions->appendChild($this->opo_dom->createElement("action", $vs_action)); } $vo_role->appendChild($vo_actions); } $va_vars = $t_role->get('vars'); // add bundle level ACL items if (is_array($va_vars['bundle_access_settings'])) { $vo_bundle_lvl_ac = $this->opo_dom->createElement("bundleLevelAccessControl"); foreach ($va_vars['bundle_access_settings'] as $vs_bundle => $vn_val) { $va_tmp = explode('.', $vs_bundle); $vs_table_name = $va_tmp[0]; $vs_bundle_name = $va_tmp[1]; if ($t_ui_screens->isAvailableBundle($vs_table_name, $vs_bundle_name)) { // only add this entry to the export if it's actually a valid bundle $vs_access = $this->_convertACLConstantToString(intval($vn_val)); $vo_permission = $this->opo_dom->createElement("permission"); $vo_bundle_lvl_ac->appendChild($vo_permission); $vo_permission->setAttribute('table', $vs_table_name); $vo_permission->setAttribute('bundle', $vs_bundle_name); $vo_permission->setAttribute('access', $vs_access); } } $vo_role->appendChild($vo_bundle_lvl_ac); } // add type level ACL items if (is_array($va_vars['type_access_settings'])) { $vo_type_lvl_ac = $this->opo_dom->createElement("typeLevelAccessControl"); foreach ($va_vars['type_access_settings'] as $vs_id => $vn_val) { $va_tmp = explode('.', $vs_id); $vs_table_name = $va_tmp[0]; $vn_type_id = $va_tmp[1]; $vs_access = $this->_convertACLConstantToString(intval($vn_val)); /** @var BaseModelWithAttributes $t_instance */ $t_instance = $this->opo_dm->getInstanceByTableName($vs_table_name, true); if (!($vs_list_code = $t_instance->getTypeListCode())) { continue; } $va_item = $t_list->getItemFromListByItemID($vs_list_code, $vn_type_id); if (!isset($va_item['idno'])) { continue; } $vo_permission = $this->opo_dom->createElement("permission"); $vo_type_lvl_ac->appendChild($vo_permission); $vo_permission->setAttribute('table', $vs_table_name); $vo_permission->setAttribute('type', $va_item['idno']); $vo_permission->setAttribute('access', $vs_access); } $vo_role->appendChild($vo_type_lvl_ac); } $vo_roles->appendChild($vo_role); } return $vo_roles; }
public function getRolesAsDOM() { $t_role = new ca_user_roles(); $vo_roles = $this->opo_dom->createElement("roles"); $qr_roles = $this->opo_db->query("SELECT * FROM ca_user_roles"); while ($qr_roles->nextRow()) { $t_role->load($qr_roles->get("role_id")); $vo_role = $this->opo_dom->createElement("role"); $vo_role->setAttribute("code", $this->makeIDNO($t_role->get("code"))); $vo_role->appendChild($this->opo_dom->createElement("name", $t_role->get("name"))); $vo_role->appendChild($this->opo_dom->createElement("description", $t_role->get("description"))); if (is_array($va_actions = $t_role->getRoleActions())) { $vo_actions = $this->opo_dom->createElement("actions"); foreach ($va_actions as $vs_action) { $vo_actions->appendChild($this->opo_dom->createElement("action", $vs_action)); } $vo_role->appendChild($vo_actions); } $vo_roles->appendChild($vo_role); } return $vo_roles; }
/** * Determines whether current group has a specified role. * * @access public * @param mixed $pm_role The role to test for the current group. Role may be specified by name, code or id. * @return bool Returns true if group has the role, false if not. */ function hasGroupRole($ps_role) { if (!($vn_group_id = $this->getPrimaryKey())) { return false; } $vb_got_role = 0; $t_role = new ca_user_roles(); if (is_numeric($ps_role)) { $vb_got_role = $t_role->load($ps_role); } if (!$vb_got_role) { if (!$t_role->load(array("name" => $ps_role))) { if (!$t_role->load(array("code" => $ps_role))) { return false; } } $vb_got_role = 1; } if ($vb_got_role) { $o_db = $this->getDb(); $qr_res = $o_db->query("\n\t\t\t\tSELECT * \n\t\t\t\tFROM ca_groups_x_roles\n\t\t\t\tWHERE\n\t\t\t\t\t(group_id = ?) AND\n\t\t\t\t\t(role_id = ?)\n\t\t\t", (int) $vn_group_id, (int) $t_role->getPrimaryKey()); if (!$qr_res) { return false; } if ($qr_res->nextRow()) { return true; } else { return false; } } else { $this->postError(940, _t("Invalid role '%1'", $ps_role), "ca_user_groups->hasRole()"); return false; } }
/** * Returns change log display for currently edited record in current view inherited from ActionController * * @param array $pa_options Array of options passed through to _initView */ public function Log($pa_options = null) { AssetLoadManager::register('tableList'); list($vn_subject_id, $t_subject) = $this->_initView($pa_options); if (!$this->_checkAccess($t_subject)) { return false; } if (ca_user_roles::isValidAction('can_view_change_log_' . $t_subject->tableName()) && !$this->request->user->canDoAction('can_view_change_log_' . $t_subject->tableName())) { $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2575?r=' . urlencode($this->request->getFullUrlPath())); return; } $this->render('log_html.php'); }