/** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. */ protected function setUp() { parent::setUp(); // Clear the static caches. JAccess::clearStatics(); $this->object = new JAccess(); }
/** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. */ protected function setUp() { parent::setUp(); // Clear the static caches. JAccess::clearStatics(); $this->object = new JAccess(); // Make sure previous test files are cleaned up $this->_cleanupTestFiles(); // Make some test files and folders mkdir(JPath::clean(JPATH_TESTS . '/tmp/access'), 0777, true); }
/** * Get the files the user has access to, filtering or not by the externalRef. * * @param int $userId * @param string $externalRef * @return array */ public static function getAuthorizedFilesForUser($userId, $externalRef = '') { // Flush any JAccess cache JAccess::clearStatics(); $authorizedViewLevels = JAccess::getAuthorisedViewLevels($userId); $authorizedViewLevels = implode(',', $authorizedViewLevels); // Get the files the user has access to and external ref has the suffix .pro $db = JFactory::getDbo(); $query = $db->getQuery(true)->select('*')->from('#__osdownloads_documents')->where("access IN ({$authorizedViewLevels})"); if ($externalRef !== '') { $query->where('external_ref LIKE "' . $externalRef . '"'); } $db->setQuery($query); return $db->loadObjectList(); }
/** * Clears the access rights cache of this user * * @return void * * @since 3.4.0 */ public function clearAccessRights() { $this->_authLevels = null; $this->_authGroups = null; $this->isRoot = null; JAccess::clearStatics(); }
/** * Helper wrapper method for addUserToGroup * * @return void * * @see JAccess::clearStatics * @since 3.4 */ public function clearStatics() { return JAccess::clearStatics(); }
/** * Adjusts user's ACL and block user if no subscriptions left. * * @param UserTable $user * @param string $cause cause of the change * @param int $block 1: block user, 0: don't block * @param int[] $gids new ACL gids (in Joomla < 1.6: only 1 entry) * @param int[] $removeGids old ACL gids from plans that just expired * @param array $oldChldGids old ACL gids and children * @param string $reason reason of change: 'N'=new subscription (default), 'R'=renewal, 'U'=update + 'X'=expiries */ protected function _adjustUserAclBlock($user, $cause, $block, $gids, $removeGids, $oldChldGids, $reason) { global $_CB_framework; if ($user && $user->id) { if (self::_anyValueOfArrayInArray((array) $user->gids, $oldChldGids)) { // test above is to not degrade higher-level users ! $wasBlocked = $user->block; $gidsUniqueSorted = array_unique($gids); sort($gidsUniqueSorted, SORT_NUMERIC); $userGids = array_unique((array) $user->gids); sort($userGids, SORT_NUMERIC); if ($block != $wasBlocked || $userGids != $gidsUniqueSorted) { $superadministratorgid = $_CB_framework->acl->mapGroupNamesToValues('Superadministrator'); $k_SA = array_search($superadministratorgid, $removeGids); if ($k_SA !== false) { unset($removeGids[$k_SA]); } $user->gids = array_unique(array_merge(array_diff($userGids, $removeGids), $gidsUniqueSorted)); sort($user->gids, SORT_NUMERIC); if ($block && !in_array($superadministratorgid, (array) $user->gids)) { $user->block = 1; } $oldPwd = $user->password; $user->password = null; // don't update cleartext password in case of registration $user->store(); // takes care of Mambo/Joomla ACL tables and many other stuff $user->password = $oldPwd; if (checkJversion() == 2) { // This is needed for instant adding of groups to logged-in user (fixing bug #3581): Can be removed once CB 1.9 is released: $session = JFactory::getSession(); $jUser = $session->get('user'); if ($jUser && $jUser->id == $user->id) { JAccess::clearStatics(); $session->set('user', new JUser((int) $user->id)); } } if ($block == 0 && $wasBlocked == 1) { $messagesToUser = $reason == 'N' && (!$user->lastvisitDate || $user->lastvisitDate == '0000-00-00 00:00:00'); activateUser($user, 0, 'PaidSubscription', $messagesToUser, $messagesToUser); //TBD: //FIXME Don't ACTIVATE user 2nd time if this function is called from subscription->activate as a result of onUserActivate? } } } } else { user_error(sprintf('AdjustUserAclBlock: user id %d not found in users table.', $user->id), E_USER_NOTICE); } }
/** * Method to store the permission values in the asset table. * * This method will get an array with permission key value pairs and transform it * into json and update the asset table in the database. * * @param string $permission Need an array with Permissions (component, rule, value and title) * * @return array A list of result data. * * @since 3.5 */ public function storePermissions($permission = null) { $app = JFactory::getApplication(); $user = JFactory::getUser(); if (is_null($permission)) { // Get data from input. $permission = array('component' => $app->input->get('comp'), 'action' => $app->input->get('action'), 'rule' => $app->input->get('rule'), 'value' => $app->input->get('value'), 'title' => $app->input->get('title', '', 'RAW')); } // We are creating a new item so we don't have an item id so don't allow. if (substr($permission['component'], -6) === '.false') { $app->enqueueMessage(JText::_('JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS'), 'error'); return false; } // Check if the user is authorized to do this. if (!$user->authorise('core.admin', $permission['component'])) { $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); return false; } $permission['component'] = empty($permission['component']) ? 'root.1' : $permission['component']; // Current view is global config? $isGlobalConfig = $permission['component'] === 'root.1'; // Check if changed group has Super User permissions. $isSuperUserGroupBefore = JAccess::checkGroup($permission['rule'], 'core.admin'); // Check if current user belongs to changed group. $currentUserBelongsToGroup = in_array((int) $permission['rule'], $user->groups) ? true : false; // Get current user groups tree. $currentUserGroupsTree = JAccess::getGroupsByUser($user->id, true); // Check if current user belongs to changed group. $currentUserSuperUser = $user->authorise('core.admin'); // If user is not Super User cannot change the permissions of a group it belongs to. if (!$currentUserSuperUser && $currentUserBelongsToGroup) { $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_GROUPS'), 'error'); return false; } // If user is not Super User cannot change the permissions of a group it belongs to. if (!$currentUserSuperUser && in_array((int) $permission['rule'], $currentUserGroupsTree)) { $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_PARENT_GROUPS'), 'error'); return false; } // If user is not Super User cannot change the permissions of a Super User Group. if (!$currentUserSuperUser && $isSuperUserGroupBefore && !$currentUserBelongsToGroup) { $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_SUPER_USER'), 'error'); return false; } // If user is not Super User cannot change the Super User permissions in any group it belongs to. if ($isSuperUserGroupBefore && $currentUserBelongsToGroup && $permission['action'] === 'core.admin') { $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'), 'error'); return false; } try { // Load the current settings for this component. $query = $this->db->getQuery(true)->select($this->db->quoteName(array('name', 'rules')))->from($this->db->quoteName('#__assets'))->where($this->db->quoteName('name') . ' = ' . $this->db->quote($permission['component'])); $this->db->setQuery($query); // Load the results as a list of stdClass objects (see later for more options on retrieving data). $results = $this->db->loadAssocList(); } catch (Exception $e) { $app->enqueueMessage($e->getMessage(), 'error'); return false; } // No record found, let's create one. if (empty($results)) { $data = array(); $data[$permission['action']] = array($permission['rule'] => $permission['value']); $rules = new JAccessRules($data); $asset = JTable::getInstance('asset'); $asset->rules = (string) $rules; $asset->name = (string) $permission['component']; $asset->title = (string) $permission['title']; // Get the parent asset id so we have a correct tree. $parentAsset = JTable::getInstance('Asset'); if (strpos($asset->name, '.') !== false) { $assetParts = explode('.', $asset->name); $parentAsset->loadByName($assetParts[0]); $parentAssetId = $parentAsset->id; } else { $parentAssetId = $parentAsset->getRootId(); } /** * @to do: incorrect ACL stored * When changing a permission of an item that doesn't have a row in the asset table the row a new row is created. * This works fine for item <-> component <-> global config scenario and component <-> global config scenario. * But doesn't work properly for item <-> section(s) <-> component <-> global config scenario, * because a wrong parent asset id (the component) is stored. * Happens when there is no row in the asset table (ex: deleted or not created on update). */ $asset->setLocation($parentAssetId, 'last-child'); if (!$asset->check() || !$asset->store()) { $app->enqueueMessage(JText::_('JLIB_UNKNOWN'), 'error'); return false; } } else { // Decode the rule settings. $temp = json_decode($results[0]['rules'], true); // Check if a new value is to be set. if (isset($permission['value'])) { // Check if we already have an action entry. if (!isset($temp[$permission['action']])) { $temp[$permission['action']] = array(); } // Check if we already have a rule entry. if (!isset($temp[$permission['action']][$permission['rule']])) { $temp[$permission['action']][$permission['rule']] = array(); } // Set the new permission. $temp[$permission['action']][$permission['rule']] = (int) $permission['value']; // Check if we have an inherited setting. if (strlen($permission['value']) === 0) { unset($temp[$permission['action']][$permission['rule']]); } } else { // There is no value so remove the action as it's not needed. unset($temp[$permission['action']]); } // Store the new permissions. try { $query->clear()->update($this->db->quoteName('#__assets'))->set($this->db->quoteName('rules') . ' = ' . $this->db->quote(json_encode($temp)))->where($this->db->quoteName('name') . ' = ' . $this->db->quote($permission['component'])); $this->db->setQuery($query)->execute(); } catch (Exception $e) { $app->enqueueMessage($e->getMessage(), 'error'); return false; } } // All checks done. $result = array('text' => '', 'class' => '', 'result' => true); // Show the current effective calculated permission considering current group, path and cascade. try { // Get the asset id by the name of the component. $query->clear()->select($this->db->quoteName('id'))->from($this->db->quoteName('#__assets'))->where($this->db->quoteName('name') . ' = ' . $this->db->quote($permission['component'])); $this->db->setQuery($query); $assetId = (int) $this->db->loadResult(); // Fetch the parent asset id. $parentAssetId = null; /** * @to do: incorrect info * When creating a new item (not saving) it uses the calculated permissions from the component (item <-> component <-> global config). * But if we have a section too (item <-> section(s) <-> component <-> global config) this is not correct. * Also, currently it uses the component permission, but should use the calculated permissions for achild of the component/section. */ // If not in global config we need the parent_id asset to calculate permissions. if (!$isGlobalConfig) { // In this case we need to get the component rules too. $query->clear()->select($this->db->quoteName('parent_id'))->from($this->db->quoteName('#__assets'))->where($this->db->quoteName('id') . ' = ' . $assetId); $this->db->setQuery($query); $parentAssetId = (int) $this->db->loadResult(); } // Get the group parent id of the current group. $query->clear()->select($this->db->quoteName('parent_id'))->from($this->db->quoteName('#__usergroups'))->where($this->db->quoteName('id') . ' = ' . (int) $permission['rule']); $this->db->setQuery($query); $parentGroupId = (int) $this->db->loadResult(); // Count the number of child groups of the current group. $query->clear()->select('COUNT(' . $this->db->quoteName('id') . ')')->from($this->db->quoteName('#__usergroups'))->where($this->db->quoteName('parent_id') . ' = ' . (int) $permission['rule']); $this->db->setQuery($query); $totalChildGroups = (int) $this->db->loadResult(); } catch (Exception $e) { $app->enqueueMessage($e->getMessage(), 'error'); return false; } // Clear access statistics. JAccess::clearStatics(); // After current group permission is changed we need to check again if the group has Super User permissions. $isSuperUserGroupAfter = JAccess::checkGroup($permission['rule'], 'core.admin'); // Get the rule for just this asset (non-recursive) and get the actual setting for the action for this group. $assetRule = JAccess::getAssetRules($assetId, false, false)->allow($permission['action'], $permission['rule']); // Get the group, group parent id, and group global config recursive calculated permission for the chosen action. $inheritedGroupRule = JAccess::checkGroup($permission['rule'], $permission['action'], $assetId); if (!empty($parentAssetId)) { $inheritedGroupParentAssetRule = JAccess::checkGroup($permission['rule'], $permission['action'], $parentAssetId); } else { $inheritedGroupParentAssetRule = null; } $inheritedParentGroupRule = !empty($parentGroupId) ? JAccess::checkGroup($parentGroupId, $permission['action'], $assetId) : null; // Current group is a Super User group, so calculated setting is "Allowed (Super User)". if ($isSuperUserGroupAfter) { $result['class'] = 'label label-success'; $result['text'] = '<span class="icon-lock icon-white"></span>' . JText::_('JLIB_RULES_ALLOWED_ADMIN'); } else { // First get the real recursive calculated setting and add (Inherited) to it. // If recursive calculated setting is "Denied" or null. Calculated permission is "Not Allowed (Inherited)". if ($inheritedGroupRule === null || $inheritedGroupRule === false) { $result['class'] = 'label label-important'; $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED_INHERITED'); } else { $result['class'] = 'label label-success'; $result['text'] = JText::_('JLIB_RULES_ALLOWED_INHERITED'); } // Second part: Overwrite the calculated permissions labels if there is an explicity permission in the current group. /** * @to do: incorect info * If a component as a permission that doesn't exists in global config (ex: frontend editing in com_modules) by default * we get "Not Allowed (Inherited)" when we should get "Not Allowed (Default)". */ // If there is an explicity permission "Not Allowed". Calculated permission is "Not Allowed". if ($assetRule === false) { $result['class'] = 'label label-important'; $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED'); } elseif ($assetRule === true) { $result['class'] = 'label label-success'; $result['text'] = JText::_('JLIB_RULES_ALLOWED'); } // Third part: Overwrite the calculated permissions labels for special cases. // Global configuration with "Not Set" permission. Calculated permission is "Not Allowed (Default)". if (empty($parentGroupId) && $isGlobalConfig === true && $assetRule === null) { $result['class'] = 'label label-important'; $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED_DEFAULT'); } elseif ($inheritedGroupParentAssetRule === false || $inheritedParentGroupRule === false) { $result['class'] = 'label label-important'; $result['text'] = '<span class="icon-lock icon-white"></span>' . JText::_('JLIB_RULES_NOT_ALLOWED_LOCKED'); } } // If removed or added super user from group, we need to refresh the page to recalculate all settings. if ($isSuperUserGroupBefore != $isSuperUserGroupAfter) { $app->enqueueMessage(JText::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_PERMISSIONS'), 'notice'); } // If this group has child groups, we need to refresh the page to recalculate the child settings. if ($totalChildGroups > 0) { $app->enqueueMessage(JText::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_CHILDS_PERMISSIONS'), 'notice'); } return $result; }
/** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. * * @return void * * @since 12.1 */ protected function setUp() { parent::setUp(); $this->saveFactoryState(); $mockApp = $this->getMockCmsApp(); $mockApp->expects($this->any())->method('getDispatcher')->willReturn($this->getMockDispatcher()); JFactory::$application = $mockApp; // Clear the static caches. JAccess::clearStatics(); $this->object = new JAccess(); // Make sure previous test files are cleaned up $this->_cleanupTestFiles(); // Make some test files and folders mkdir(JPath::clean(JPATH_TESTS . '/tmp/access'), 0777, true); }
/** * If table key (id) is NULL : inserts new rows * otherwise updates existing row in the database tables * * Can be overridden or overloaded by the child classes * * @param boolean $updateNulls TRUE: null object variables are also updated, FALSE: not. * @return boolean TRUE if successful otherwise FALSE */ function store($updateNulls = false) { global $_CB_framework, $_CB_database, $ueConfig; $this->id = (int) $this->id; if (checkJversion() == 2) { $this->gids = is_array($this->gids) ? $this->gids : array($this->gid); $this->gid = (int) $_CB_framework->acl->getBackwardsCompatibleGid($this->gids); } else { $this->gid = (int) $this->gid; $this->gids = array($this->gid); } $isNew = $this->id == 0; $oldUsername = null; $oldGid = null; $oldGids = array(); $oldBlock = null; if (!$isNew) { // get actual username to update sessions in case: $sql = 'SELECT ' . $_CB_database->NameQuote($this->_cmsUserTableUsername) . (checkJversion() < 2 ? ', ' . $_CB_database->NameQuote($this->_cmsUserTableGid) : null) . ', ' . $_CB_database->NameQuote('block') . ' FROM ' . $_CB_database->NameQuote($this->_cmsUserTable) . ' WHERE ' . $_CB_database->NameQuote($this->_cmsUserTableKey) . ' = ' . (int) $this->user_id; $_CB_database->setQuery($sql); $oldEntry = null; if ($_CB_database->loadObject($oldEntry)) { $oldUsername = $oldEntry->username; if (checkJversion() == 2) { $gids = array_values((array) JFactory::getAcl()->getGroupsByUser($this->id, false)); foreach ($gids as $k => $v) { $gids[$k] = (string) $v; } $oldGids = $gids; $oldGid = (int) $_CB_framework->acl->getBackwardsCompatibleGid($oldGids); } else { $oldGid = (int) $oldEntry->gid; $oldGids = array($oldEntry->gid); } $oldBlock = $oldEntry->block; } } // insure usertype is in sync with gid: /* * This could be a better method: if ( checkJversion() == 1 ) { $gdataArray = $_CB_framework->acl->get_group_data( (int) $this->gid, 'ARO' ); if ( $gdataArray ) { $this->usertype = $gdataArray[3]; } else { user_error( sprintf( 'comprofilerUser::store: gacl:get_group_data: for user_id %d, name of group_id %d not found in acl groups table.', $this->id, $this->gid ), E_USER_WARNING ); $this->usertype = 'Registered'; } } else { $this->usertype = $_CB_framework->acl->get_group_name( (int) $gid, 'ARO' ); } */ if (checkJversion() == 2) { $this->usertype = null; } else { if (checkJversion() == 1) { $query = 'SELECT name' . "\n FROM #__core_acl_aro_groups" . "\n WHERE id = " . (int) $this->gid; } else { $query = 'SELECT name' . "\n FROM #__core_acl_aro_groups" . "\n WHERE group_id = " . (int) $this->gid; } $_CB_database->setQuery($query); $this->usertype = $_CB_database->loadResult(); } if (!$isNew && $this->confirmed == 0 && $this->cbactivation == '' && $ueConfig['reg_confirmation'] != 0) { $this->_setActivationCode(); } // creates CMS and CB objects: $this->_mapUsers(); // remove the previous email set in bindSafely() and needed for checkSafely(): unset($this->_original_email); // stores first into CMS to get id of user if new: if (is_callable(array($this->_cmsUser, 'store'))) { $result = $this->_cmsUser->store($updateNulls); if (!$result) { $this->_error = $this->_cmsUser->getError(); } } else { if (checkJversion() == 2) { $this->_cmsUser->groups = $this->gids; } $result = $this->_cmsUser->save(); // Joomla 1.5 native if (!$result) { $this->_error = $this->_cmsUser->getError(); if (class_exists('JText')) { $this->_error = JText::_($this->_error); } } } if ($result) { // synchronize id and user_id: if ($isNew) { if ($this->_cmsUser->id == 0) { // this is only for mambo 4.5.0 backwards compatibility. 4.5.2.3 $row->store() updates id on insert $sql = 'SELECT ' . $_CB_database->NameQuote($this->_cmsUserTableKey) . ' FROM ' . $_CB_database->NameQuote($this->_cmsUserTable) . ' WHERE ' . $_CB_database->NameQuote($this->_cmsUserTableUsername) . ' = ' . $_CB_database->Quote($this->username); $_CB_database->setQuery($sql); $this->_cmsUser->id = (int) $_CB_database->loadResult(); } $this->id = $this->_cmsUser->id; $this->_comprofilerUser->id = $this->_cmsUser->id; if ($this->confirmed == 0 && $this->cbactivation == '' && $ueConfig['reg_confirmation'] != 0) { $this->_setActivationCode(); } } // stores CB user into comprofiler: if new, inserts, otherwise updates: if ($this->user_id == 0) { $this->user_id = $this->_cmsUser->id; $this->_comprofilerUser->user_id = $this->user_id; $result = $this->_comprofilerUser->storeNew($updateNulls); } else { $result = $this->_comprofilerUser->store($updateNulls); } if (!$result) { $this->_error = $this->_comprofilerUser->getError(); } } if ($result) { // update the ACL: if (checkJversion() == 2) { $query = 'SELECT m.id AS aro_id, a.group_id FROM #__user_usergroup_map AS a' . "\n INNER JOIN #__usergroups AS m ON m.id= a.group_id" . "\n WHERE a.user_id = " . (int) $this->id; } elseif (checkJversion() == 1) { $query = 'SELECT a.id AS aro_id, m.group_id FROM #__core_acl_aro AS a' . "\n INNER JOIN #__core_acl_groups_aro_map AS m ON m.aro_id = a.id" . "\n WHERE a.value = " . $_CB_database->Quote((int) $this->id); } else { $query = 'SELECT a.aro_id, m.group_id FROM #__core_acl_aro AS a' . "\n INNER JOIN #__core_acl_groups_aro_map AS m ON m.aro_id = a.aro_id" . "\n WHERE a.value = " . $_CB_database->Quote((int) $this->id); } $_CB_database->setQuery($query); $aro_group = null; $result = $_CB_database->loadObject($aro_group); if ($result && $aro_group->group_id != $this->gid) { if (checkJversion() == 2) { // $query = 'UPDATE #__user_usergroup_map' // . "\n SET group_id = " . (int) $this->gid // . "\n WHERE user_id = " . (int) $this->id // . ( $oldGid ? "\n AND group_id = " . (int) $oldGid : null ) // ; // $_CB_database->setQuery( $query ); // $result = $_CB_database->query(); } else { $query = 'UPDATE #__core_acl_groups_aro_map' . "\n SET group_id = " . (int) $this->gid . "\n WHERE aro_id = " . (int) $aro_group->aro_id; $_CB_database->setQuery($query); $result = $_CB_database->query(); } } if ($result && !$isNew && ($oldUsername != $this->username || $aro_group->group_id != $this->gid || $oldGid != $this->gid || self::_ArraysEquivalent($oldGids, $this->gids) || $oldBlock == 0 && $this->block == 1)) { // Update current sessions state if there is a change in gid or in username: if ($this->block == 0) { $sessionGid = 1; if ($_CB_framework->acl->is_group_child_of($this->usertype, 'Registered', 'ARO') || $_CB_framework->acl->is_group_child_of($this->usertype, 'Public Backend', 'ARO')) { // Authors, Editors, Publishers and Super Administrators are part of the Special Group: $sessionGid = 2; } $query = 'UPDATE #__session ' . "\n SET username = "******"\n WHERE userid = " . (int) $this->id; //TBD: here maybe jaclplus fields update if JACLplus installed.... $_CB_database->setQuery($query); $result = $_CB_database->query(); if (checkJversion() >= 2) { // This is needed for instant adding of groups to logged-in user (fixing bug #3581): $session = JFactory::getSession(); $jUser = $session->get('user'); if ($jUser->id == $this->id) { JAccess::clearStatics(); $session->set('user', new JUser((int) $this->id)); } } } else { // logout user now that user login has been blocked: if ($_CB_framework->myId() == $this->id) { $_CB_framework->logout(); } $_CB_database->setQuery("DELETE FROM #__session WHERE userid = " . (int) $this->id); //TBD: check if this is enough for J 1.5 $result = $_CB_database->query(); } } if (!$result) { $this->_error = $_CB_database->stderr(); return false; } } return $result; }
/** * This method should handle any authentication and report back to the subject * * @access public * @param array $credentials Array holding the user credentials * @param array $options Array of extra options * @param object $response Authentication response object * @return boolean * @since 1.5 */ public function onUserAuthenticate($credentials, $options, &$response) { $results = JFactory::getApplication()->triggerEvent('onExternalLogin', array(&$response)); if (count($results) > 0) { // Get the DB driver $db = JFactory::getDbo(); // Get server params $params = $response->server->params; // Import JComponentHelper library jimport('joomla.application.component.helper'); // Get com_users parameters $config = JComponentHelper::getParams('com_users'); // Get default user group. $defaultUserGroup = $params->get('usergroup', $config->get('new_usertype', 2)); // Get a user $user = JUser::getInstance(); if ($id = intval(JUserHelper::getUserId($response->username))) { if ($params->get('autoupdate', 0)) { // User is found $user->load($id); // Update it on auto-update $user->set('name', $response->fullname); $user->set('email', $response->email); // Get the old groups $query = $db->getQuery(true); $query->select('group_id')->from('#__user_usergroup_map')->where('user_id = ' . (int) $id); $db->setQuery($query); $oldgroups = $db->loadColumn(); // Delete the old groups $query = $db->getQuery(true); $query->delete('#__user_usergroup_map')->where('user_id = ' . (int) $id); $db->setQuery($query); $db->execute(); $user->groups = null; // Attempt to save the user if ($user->save()) { if ($params->get('log_autoupdate', 0)) { // Log autoupdate JLog::add(new ExternalloginLogEntry('Auto-update of user "' . $user->username . '" with fullname "' . $response->fullname . '" and email "' . $response->email . '" on server ' . $response->server->id, JLog::INFO, 'authentication-externallogin-autoupdate')); } $response->status = JAuthentication::STATUS_SUCCESS; $response->id = $id; $groups = empty($response->groups) ? $oldgroups : $response->groups; // Add the groups $query = $db->getQuery(true); $query->insert('#__user_usergroup_map')->columns('user_id, group_id'); foreach ($groups as $group) { $query->values((int) $id . ',' . (int) $group); } $db->setQuery($query); $db->execute(); if (!empty($response->groups) && $params->get('log_autoupdate', 0)) { // Log autoupdate JLog::add(new ExternalloginLogEntry('Auto-update new groups of user "' . $user->username . '" with groups (' . implode(',', $groups) . ') on server ' . $response->server->id, JLog::INFO, 'authentication-externallogin-autoupdate')); } } else { // Add the old groups $query = $db->getQuery(true); $query->insert('#__user_usergroup_map')->columns('user_id, group_id'); foreach ($oldgroups as $group) { $query->values((int) $id . ',' . (int) $group); } $db->setQuery($query); $db->execute(); if ($params->get('log_autoupdate', 0)) { // Log autoupdate JLog::add(new ExternalloginLogEntry($user->getError(), JLog::ERROR, 'authentication-externallogin-autoupdate')); } $response->status = JAuthentication::STATUS_UNKNOWN; } JAccess::clearStatics(); } else { $response->status = JAuthentication::STATUS_SUCCESS; $response->id = $id; } } elseif ($params->get('autoregister', 0)) { // User is not found $user->set('id', 0); $user->set('name', $response->fullname); $user->set('username', $response->username); $user->set('email', $response->email); $user->set('usertype', 'deprecated'); // Create new user if ($user->save()) { $response->status = JAuthentication::STATUS_SUCCESS; $response->id = $user->id; $query = $db->getQuery(true); $query->insert('#__externallogin_users')->columns('server_id, user_id')->values((int) $response->server->id . ',' . (int) $user->id); $db->setQuery($query); $db->execute(); if ($params->get('log_autoregister', 0)) { // Log autoregister JLog::add(new ExternalloginLogEntry('Auto-register of user "' . $user->username . '" with fullname "' . $response->fullname . '" and email "' . $response->email . '" on server ' . $response->server->id, JLog::INFO, 'authentication-externallogin-autoregister')); } // Add the new groups $groups = empty($response->groups) ? array($defaultUserGroup) : $response->groups; $query = $db->getQuery(true); $query->insert('#__user_usergroup_map')->columns('user_id, group_id'); foreach ($groups as $group) { $query->values((int) $user->id . ',' . (int) $group); } $db->setQuery($query); $db->execute(); if ($params->get('log_autoregister', 0)) { if (empty($response->groups)) { // Log autoregister JLog::add(new ExternalloginLogEntry('Auto-register default group "' . $defaultUserGroup . '" for user "' . $user->username . '" on server ' . $response->server->id, JLog::INFO, 'authentication-externallogin-autoregister')); } else { // Log autoregister JLog::add(new ExternalloginLogEntry('Auto-register new groups for user "' . $user->username . '" with groups (' . implode(',', $groups) . ') on server ' . $response->server->id, JLog::INFO, 'authentication-externallogin-autoregister')); } } } else { if ($params->get('log_autoregister', 0)) { // Log autoregister JLog::add(new ExternalloginLogEntry($user->getError(), JLog::ERROR, 'authentication-externallogin-autoregister')); } $response->status = JAuthentication::STATUS_UNKNOWN; } } else { JLog::add(new ExternalloginLogEntry('User "' . $user->username . '" is trying to register while auto-register is disabled', JLog::WARNING, 'authentication-externallogin-autoregister')); $response->status = JAuthentication::STATUS_UNKNOWN; } return true; } else { return false; } }
/** * @param cbautoactionsActionTable $trigger * @param UserTable $user */ public function execute( $trigger, $user ) { if ( ! $user->get( 'id' ) ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_NO_USER', ':: Action [action] :: Usergroup skipped due to no user', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } return; } $cache = $user->get( 'password' ); $user->set( 'password', null ); foreach ( $trigger->getParams()->subTree( 'usergroup' ) as $row ) { /** @var ParamsInterface $row */ $groups = $row->get( 'groups', null, GetterInterface::STRING ); if ( $groups ) { $groups = explode( '|*|', $groups ); cbArrayToInts( $groups ); } $session = JFactory::getSession(); $jUser = $session->get( 'user' ); $isMe = ( $jUser ? ( $jUser->id == $user->get( 'id' ) ) : false ); switch ( $row->get( 'mode', 'add', GetterInterface::STRING ) ) { case 'create': $title = $trigger->getSubstituteString( $row->get( 'title', null, GetterInterface::STRING ) ); if ( ! $title ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_NO_TITLE', ':: Action [action] :: Usergroup skipped due to missing title', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } continue; } $usergroup = JTable::getInstance( 'usergroup' ); $usergroup->load( array( 'title' => $title ) ); if ( ! $usergroup->id ) { $usergroup->parent_id = (int) $row->get( 'parent', 0, GetterInterface::INT ); $usergroup->title = $title; if ( ! $usergroup->store() ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_CREATE_FAILED', ':: Action [action] :: Usergroup failed to create', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } continue; } } if ( $row->get( 'add', 1, GetterInterface::BOOLEAN ) ) { if ( ! in_array( $usergroup->id, $user->get( 'gids' ) ) ) { $user->gids[] = $usergroup->id; if ( ! $user->store() ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_FAILED', ':: Action [action] :: Usergroup failed to save. Error: [error]', array( '[action]' => (int) $trigger->get( 'id' ), '[error]' => $user->getError() ) ) ); } continue; } if ( $isMe ) { JAccess::clearStatics(); $session->set( 'user', new JUser( $user->get( 'id' ) ) ); } } } break; case 'replace': if ( ! $groups ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_NO_GROUPS', ':: Action [action] :: Usergroup skipped due to missing groups', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } continue; } $user->set( 'gids', $groups ); if ( ! $user->store() ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_FAILED', ':: Action [action] :: Usergroup failed to save. Error: [error]', array( '[action]' => (int) $trigger->get( 'id' ), '[error]' => $user->getError() ) ) ); } continue; } if ( $isMe ) { JAccess::clearStatics(); $session->set( 'user', new JUser( $user->get( 'id' ) ) ); } break; case 'remove': if ( ! $groups ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_NO_GROUPS', ':: Action [action] :: Usergroup skipped due to missing groups', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } continue; } $removed = false; foreach( $user->get( 'gids' ) as $k => $gid ) { if ( in_array( $gid, $groups ) ) { unset( $user->gids[$k] ); $removed = true; } } if ( $removed ) { if ( ! $user->store() ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_FAILED', ':: Action [action] :: Usergroup failed to save. Error: [error]', array( '[action]' => (int) $trigger->get( 'id' ), '[error]' => $user->getError() ) ) ); } continue; } if ( $isMe ) { JAccess::clearStatics(); $session->set( 'user', new JUser( $user->get( 'id' ) ) ); } } break; case 'add': default: if ( ! $groups ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_NO_GROUPS', ':: Action [action] :: Usergroup skipped due to missing groups', array( '[action]' => (int) $trigger->get( 'id' ) ) ) ); } continue; } $usergroups = $groups; foreach( $usergroups as $k => $usergroup ) { if ( in_array( $usergroup, $user->get( 'gids' ) ) ) { unset( $usergroups[$k] ); } } if ( $usergroups ) { $user->set( 'gids', array_unique( array_merge( $user->get( 'gids' ), $usergroups ) ) ); if ( ! $user->store() ) { if ( $trigger->getParams()->get( 'debug', false, GetterInterface::BOOLEAN ) ) { var_dump( CBTxt::T( 'AUTO_ACTION_USERGROUP_FAILED', ':: Action [action] :: Usergroup failed to save. Error: [error]', array( '[action]' => (int) $trigger->get( 'id' ), '[error]' => $user->getError() ) ) ); } continue; } if ( $isMe ) { JAccess::clearStatics(); $session->set( 'user', new JUser( $user->get( 'id' ) ) ); } } break; } } $user->set( 'password', $cache ); }
/** * If table key (id) is NULL : inserts new rows * otherwise updates existing row in the database tables * * Can be overridden or overloaded by the child classes * * @param boolean $updateNulls TRUE: null object variables are also updated, FALSE: not. * @return boolean TRUE if successful otherwise FALSE * * @throws \RuntimeException */ public function store($updateNulls = false) { global $_CB_framework, $ueConfig; $this->id = (int) $this->id; $isNew = $this->id == 0; $oldUsername = null; $oldGids = array(); $oldBlock = null; if (!$isNew) { // get actual username to update sessions in case: $sql = 'SELECT ' . $this->_db->NameQuote($this->_cmsUserTableUsername) . ', ' . $this->_db->NameQuote('block') . ' FROM ' . $this->_db->NameQuote($this->_cmsUserTable) . ' WHERE ' . $this->_db->NameQuote($this->_cmsUserTableKey) . ' = ' . (int) $this->user_id; $this->_db->setQuery($sql); $oldEntry = null; if ($this->_db->loadObject($oldEntry)) { /** @var \JUser $oldEntry */ $oldUsername = $oldEntry->username; $gids = array_values((array) \JFactory::getAcl()->getGroupsByUser($this->id, false)); foreach ($gids as $k => $v) { $gids[$k] = (string) $v; } $oldGids = $gids; $oldBlock = $oldEntry->block; } } if (!$isNew && $this->confirmed == 0 && $this->cbactivation == '' && $ueConfig['reg_confirmation'] != 0) { $this->_setActivationCode(); } // creates CMS and CB objects: $this->_mapUsers(); // remove the previous email set in bindSafely() and needed for checkSafely(): unset($this->_original_email); // stores first into CMS to get id of user if new: $this->_cmsUser->groups = $this->gids; $result = $this->_cmsUser->save(); if (!$result) { $this->_error = $this->_cmsUser->getError(); if (class_exists('JText')) { $this->_error = \JText::_($this->_error); } } if ($result) { // synchronize id and user_id: if ($isNew) { $this->id = $this->_cmsUser->id; $this->_comprofilerUser->id = $this->_cmsUser->id; if ($this->confirmed == 0 && $this->cbactivation == '' && $ueConfig['reg_confirmation'] != 0) { $this->_setActivationCode(); } } // stores CB user into comprofiler: if new, inserts, otherwise updates: if ($this->user_id == 0) { $this->user_id = $this->_cmsUser->id; $this->_comprofilerUser->user_id = $this->user_id; $result = $this->_comprofilerUser->storeNew($updateNulls); } else { $result = $this->_comprofilerUser->store($updateNulls); } if (!$result) { $this->_error = $this->_comprofilerUser->getError(); } } if ($result) { // update the ACL: $query = 'SELECT m.id AS aro_id, a.group_id FROM #__user_usergroup_map AS a' . "\n INNER JOIN #__usergroups AS m ON m.id= a.group_id" . "\n WHERE a.user_id = " . (int) $this->id; $this->_db->setQuery($query); $aro_group = null; $result = $this->_db->loadObject($aro_group); /** @var \StdClass $aro_group */ if ($result && !$isNew && ($oldUsername != $this->username || self::_ArraysEquivalent($oldGids, $this->gids) || $oldBlock == 0 && $this->block == 1)) { // Update current sessions state if there is a change in gid or in username: if ($this->block == 0) { $query = 'UPDATE #__session ' . "\n SET username = "******"\n WHERE userid = " . (int) $this->id; $this->_db->setQuery($query); $result = $this->_db->query(); // This is needed for instant adding of groups to logged-in user (fixing bug #3581): $session = \JFactory::getSession(); $jUser = $session->get('user'); if ($jUser->id == $this->id) { \JAccess::clearStatics(); $session->set('user', new \JUser((int) $this->id)); } } else { // logout user now that user login has been blocked: if ($_CB_framework->myId() == $this->id) { $_CB_framework->logout(); } $this->_db->setQuery("DELETE FROM #__session WHERE userid = " . (int) $this->id); //TBD: check if this is enough for J 1.5 $result = $this->_db->query(); } } if (!$result) { $this->_error = $this->_db->stderr(); return false; } } return $result; }