Esempio n. 1
0
    /**
     * Display a form to edit one user account, and process that edit request.
     *
     * Parameters passed via GET:
     * --------------------------
     * numeric userid The user id of the user to be modified.
     * string  uname  The user name of the user to be modified.
     *
     * Parameters passed via POST:
     * ---------------------------
     * array access_permissions An array used to modify a user's group membership.
     *
     * See also the definition of {@link Users_Controller_FormData_ModifyUserForm}.
     *
     * Parameters passed via SESSION:
     * ------------------------------
     * None.
     *
     * @return string HTML string containing the rendered template.
     *
     * @throws Zikula_Exception_Forbidden Thrown if the current user does not have edit access, or if the method of accessing this function is improper.
     */
    public function modify()
    {
        // security check for generic edit access
        if (!SecurityUtil::checkPermission('Users::', 'ANY', ACCESS_EDIT)) {
            throw new Zikula_Exception_Forbidden();
        }

        $proceedToForm = true;

        $formData = new Users_Controller_FormData_ModifyUserForm('users_modify', $this->serviceManager);

        if ($this->request->isPost()) {
            $this->checkCsrfToken();

            $formData->setFromRequestCollection($this->request->request);
            $accessPermissions = $this->request->request->get('access_permissions', null);
            $user = $formData->toUserArray(true);
            $originalUser = UserUtil::getVars($user['uid']);
            $userAttributes = isset($originalUser['__ATTRIBUTES__']) ? $originalUser['__ATTRIBUTES__'] : array();

            // security check for this record
            if (!SecurityUtil::checkPermission('Users::', "{$originalUser['uname']}::{$originalUser['uid']}", ACCESS_EDIT)) {
                throw new Zikula_Exception_Forbidden();
            }

            if ($formData->isValid()) {
                $registrationArgs = array(
                    'checkmode'         => 'modify',
                    'emailagain'        => $formData->getField('emailagain')->getData(),
                    'setpass'           => (bool)$formData->getField('setpass')->getData(),
                    'antispamanswer'    => '',
                );
                $registrationArgs['passagain'] = $registrationArgs['setpass'] ? $formData->getField('passagain')->getData() : '';

                $registrationArgs['reginfo'] = $user;

                $errorFields = ModUtil::apiFunc($this->name, 'registration', 'getRegistrationErrors', $registrationArgs);
            } else {
                $errorFields = $formData->getErrorMessages();
            }

            $event = new Zikula_Event('module.users.ui.validate_edit.modify_user', $user, array(), new Zikula_Hook_ValidationProviders());
            $validators = $this->eventManager->notify($event)->getData();

            $hook = new Zikula_ValidationHook('users.ui_hooks.user.validate_edit', $validators);
            $this->notifyHooks($hook);
            $validators = $hook->getValidators();

            if (!$errorFields && !$validators->hasErrors()) {
                if ($originalUser['uname'] != $user['uname']) {
                    // UserUtil::setVar does not allow uname to be changed.
                    // UserUtil::setVar('uname', $user['uname'], $originalUser['uid']);
                    $updatedUserObj = array(
                        'uid'   => $originalUser['uid'],
                        'uname' => $user['uname'],
                    );
                    DBUtil::updateObject($updatedUserObj, 'users', '', 'uid');
                    $eventArgs = array(
                        'action'    => 'setVar',
                        'field'     => 'uname',
                        'attribute' => null,
                    );
                    $eventData = array(
                        'old_value' => $originalUser['uname'],
                    );
                    $updateEvent = new Zikula_Event('user.account.update', $updatedUserObj, $eventArgs, $eventData);
                    $this->eventManager->notify($updateEvent);
                }
                if ($originalUser['email'] != $user['email']) {
                    UserUtil::setVar('email', $user['email'], $originalUser['uid']);
                }
                if ($originalUser['activated'] != $user['activated']) {
                    UserUtil::setVar('activated', $user['activated'], $originalUser['uid']);
                }
                if ($originalUser['theme'] != $user['theme']) {
                    UserUtil::setVar('theme', $user['theme'], $originalUser['uid']);
                }
                if ($formData->getField('setpass')->getData()) {
                    UserUtil::setPassword($user['pass'], $originalUser['uid']);
                    UserUtil::setVar('passreminder', $user['passreminder'], $originalUser['uid']);
                }

                $user = UserUtil::getVars($user['uid'], true);

                // TODO - This all needs to move to a Groups module hook.
                if (isset($accessPermissions)) {
                    // Fixing a high numitems to be sure to get all groups
                    $groups = ModUtil::apiFunc('Groups', 'user', 'getAll', array('numitems' => 10000));
                    $curUserGroupMembership = ModUtil::apiFunc('Groups', 'user', 'getUserGroups', array('uid' => $user['uid']));

                    foreach ($groups as $group) {
                        if (in_array($group['gid'], $accessPermissions)) {
                            // Check if the user is already in the group
                            $userIsMember = false;
                            if ($curUserGroupMembership) {
                                foreach ($curUserGroupMembership as $alreadyMemberOf) {
                                    if ($group['gid'] == $alreadyMemberOf['gid']) {
                                        $userIsMember = true;
                                        break;
                                    }
                                }
                            }
                            if ($userIsMember == false) {
                                // User is not in this group
                                ModUtil::apiFunc('Groups', 'admin', 'addUser', array(
                                    'gid' => $group['gid'],
                                    'uid' => $user['uid']
                                ));
                                $curUserGroupMembership[] = $group;
                            }
                        } else {
                            // We don't need to do a complex check, if the user is not in the group, the SQL will not return
                            // an error anyway.
                            ModUtil::apiFunc('Groups', 'admin', 'removeUser', array(
                                'gid' => $group['gid'],
                                'uid' => $user['uid']
                            ));
                        }
                    }
                }

                $event = new Zikula_Event('module.users.ui.process_edit.modify_user', $user);
                $this->eventManager->notify($event);

                $hook = new Zikula_ProcessHook('users.ui_hooks.user.process_edit', $user['uid']);
                $this->notifyHooks($hook);

                $this->registerStatus($this->__("Done! Saved user's account information."));
                $proceedToForm = false;
            }
        } elseif ($this->request->isGet()) {
            $uid    = $this->request->query->get('userid', null);
            $uname  = $this->request->query->get('uname', null);

            // check arguments
            if (is_null($uid) && is_null($uname)) {
                $this->registerError(LogUtil::getErrorMsgArgs());
                $proceedToForm = false;
            }

            // retreive userid from uname
            if (is_null($uid) && !empty($uname)) {
                $uid = UserUtil::getIdFromName($uname);
            }

            // warning for guest account
            if ($uid == 1) {
                $this->registerError($this->__("Error! You can't edit the guest account."));
                $proceedToForm = false;
            }

            // get the user vars
            $originalUser = UserUtil::getVars($uid);
            if ($originalUser == false) {
                $this->registerError($this->__('Sorry! No such user found.'));
                $proceedToForm = false;
            }
            $userAttributes = isset($originalUser['__ATTRIBUTES__']) ? $originalUser['__ATTRIBUTES__'] : array();

            $formData->setFromArray($originalUser);
            $formData->getField('emailagain')->setData($originalUser['email']);
            $formData->getField('pass')->setData('');

            $accessPermissions = array();
            $errorFields = array();
        } else {
            throw new Zikula_Exception_Forbidden();
        }

        if ($proceedToForm) {
            // security check for this record
            if (!SecurityUtil::checkPermission('Users::', "{$originalUser['uname']}::{$originalUser['uid']}", ACCESS_EDIT)) {
                throw new Zikula_Exception_Forbidden();
            }

            // groups
            $gidsUserMemberOf = array();
            $allGroups = ModUtil::apiFunc('Groups', 'user', 'getall');

            if (!empty($accessPermissions)) {
                $gidsUserMemberOf = $accessPermissions;
                $accessPermissions = array();
            } else {
                $groupsUserMemberOf = ModUtil::apiFunc('Groups', 'user', 'getusergroups', array('uid' => $originalUser['uid']));
                foreach ($groupsUserMemberOf as $user_group) {
                    $gidsUserMemberOf[] = $user_group['gid'];
                }
            }

            foreach ($allGroups as $group) {
                if (SecurityUtil::checkPermission('Groups::', "{$group['gid']}::", ACCESS_EDIT)) {
                    $accessPermissions[$group['gid']] = array();
                    $accessPermissions[$group['gid']]['name'] = $group['name'];

                    if (in_array($group['gid'], $gidsUserMemberOf) || in_array($group['gid'], $gidsUserMemberOf)) {
                        $accessPermissions[$group['gid']]['access'] = true;
                    } else {
                        $accessPermissions[$group['gid']]['access'] = false;
                    }
                }
            }

            if (!isset($userAttributes['realname'])) {
                $userAttributes['realname'] = '';
            }

            return $this->view->assign_by_ref('formData', $formData)
                ->assign('user_attributes', $userAttributes)
                ->assign('defaultGroupId', ModUtil::getVar('Groups', 'defaultgroup', 1))
                ->assign('primaryAdminGroupId', ModUtil::getVar('Groups', 'primaryadmingroup', 2))
                ->assign('accessPermissions', $accessPermissions)
                ->assign('errorFields', $errorFields)
                ->fetch('users_admin_modify.tpl');
        } else {
            $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
        }
    }
Esempio n. 2
0
 public function  applyCsvValues($args){
     $this->throwForbiddenUnless(SecurityUtil::checkPermission('IWusers::', '::', ACCESS_DELETE));
     $update = isset($args['update'])?$args['update']:null;
     $insert = isset($args['insert'])?$args['insert']:null;
     
     // Upate users table with new values
     if (!(DBUtil::updateObjectArray($update, 'users', 'uid')))
             LogUtil::registerError($this->__('Error! Update attempt failed.'));
     // Update IWusers table
     foreach ($update as &$user){
         if (DBUtil::updateObject($user, 'IWusers', "iw_uid =".$user['uid']))
             $user['action'] = 'm'; // modified //$this->__('Update');
         else 
             $user['error']= $user['uname']." - ".$this->__('Error! Update attempt failed.'). " ";
     }
     if (count($insert)){
         // Create new users in users table
         if (!(DBUtil::InsertObjectArray($insert, 'users', 'uid')))
             LogUtil::registerError($this->__('Error! New user creation attempt failed.'));
         // Create new users in IWusers table
         if (!(DBUtil::InsertObjectArray($insert, 'IWusers')))
             LogUtil::registerError($this->__('Error! New user creation attempt failed.'));
     }
     // Join update and insert arrays and process 
     $allChanges = array_merge($update, $insert);
    
     foreach ($allChanges as &$user){
         // Process "in" and "out" groups information
         ModUtil::apiFunc($this->name, 'admin', 'updateUserGroups', $user);
         // Set user pass
         if (isset($user['password']) && ($user['password']!="")) {
             // Validate pass length and pass <> uname or new_uname
             if (userUtil::validatePassword($user['password'])) {
                 UserUtil::setPassword($user['password'], $user['uid']);
             } else {
                 // Not a valid password -> error
                 $result['error'][$user['uid']] = $user;
                 $user['error'].=  $this->__('Password does not meet the minimum criteria.')." ";                    
             }
         }        
         // Force user change password?
         if ($forcechgpass) {
             switch ($user['forcechgpass']) {
                 case 1:
                     UserUtil::setVar('_Users_mustChangePassword', 1, $user['uid']);
                     break;
                 case 0;
                     UserUtil::delVar('_Users_mustChangePassword', $user['uid']);
                     break;
             }
         }
         // Change uname
         if (isset($user['new_uname']) && ($user['new_uname']!= "") && (!is_null($user['uid']))) {
             // search repeated uname/new_uname
             if (!(UserUtil::getIdFromName($user['new_uname']))) { 
                 // new_uname not exists proceed with uname change
                 $object['uname'] = $user['new_uname'];
                 //$object['uid'] = $user['uid'];
                 DBUtil::updateObject($object, 'users', "uid=".$user['uid']);
                 //UserUtil::setPassword($user['pass'], $user['uid']);
             } else {
                  $user['error'].=  $this->__f('Duplicated username: %s.', $user['new_uname']);
             }    
         }       
     }
     return $allChanges;
 }
Esempio n. 3
0
/**
 * Alias to UserUtil::setVar for setting the password on the account.
 *
 * @deprecated
 * @see UserUtil::setPassword()
 *
 * @param string $pass The password.
 * @return bool True if set; otherwise false.
 */
function pnUserSetPassword($pass)
{
    LogUtil::log(__f('Warning! Function %1$s is deprecated. Please use %2$s instead.', array(__FUNCTION__, 'UserUtil::setPassword()')), E_USER_DEPRECATED);
    return UserUtil::setPassword($pass);
}
Esempio n. 4
0
 /**
  * Creació i/o Edició d'un usuari del catàleg
  *
  * ### Paràmetres rebuts per POST:
  * -Corresponents als diferents camps de la taula *users*-
  * * integer **uid** [opcional definit-edició/no_definit-creació]
  * * string **uname**
  * 
  * -Corresponents als diferents camps de la taula *iw_users*-
  * * string **iw_nom**
  * * string **iw_cognom1**
  * * string **iw_cognom2**
  * 
  * -Per gestionar les grups relacionats amb el catàleg-
  * * array **groups**
  * 
  * -Per gestionar la contrasenya de l'usuari-
  * * string **password**
  * * string **rpassword**
  * * string **changeme**
  *
  * @return void Retorna a la funció *usergest* després de desar les dades
  */
 public function addeditUser() {
     //Comprovacions de seguretat. Només els gestors poden crear i editar usuaris
     if (!SecurityUtil::checkPermission('Cataleg::', '::', ACCESS_ADMIN)) {
         return LogUtil::registerPermissionError();
     }
     // Primer desem les modificacions de les dades d'usuari a users i a IWusers i reassignem els grups de l'usuari
     $user['zk']['uid'] = FormUtil::getPassedValue('uid', null, 'POST');
     //Comprovem si es passa una uid (per editar) o no (i s'ha de crear un nou usuari)
     if (!empty($user['zk']['uid'])) {
         //Comprovem que aquest usuari eixisteixi i es pugui editar (és a dir, que sigui del grup d'usuaris del catàleg)
         $grupCat = ModUtil::apiFunc('Cataleg', 'admin', 'getgrupsZikula');
         $catUsersList = UserUtil::getUsersForGroup($grupCat['Sirius']);
         if (!in_array($user['zk']['uid'], $catUsersList)) {
             LogUtil::registerError($this->__('No existeix cap usuari del catàleg amb l\'identificador indicat.'));
             return system::redirect(ModUtil::url('Cataleg', 'admin', 'usersgest'));
         }
         $user['iw']['uid'] = $user['zk']['uid'];
         $user['iw']['suid'] = $user['zk']['uid'];
         $r = 'edit';
     }
     $user['zk']['uname'] = FormUtil::getPassedValue('uname', null, 'POST');
     //Comprovem que no existeix cap usuari amb aquest uname
     if (!empty($user['zk']['uid'])) {
         $where = "uname = '" . $user['zk']['uname'] . "' AND uid != " . $user['zk']['uid'];
     } else {
         $where = "uname = '" . $user['zk']['uname'] . "'";
     }
     $uname = UserUtil::getUsers($where);
     if ($uname) {
         LogUtil::registerError($this->__('El nom d\'usuari triat ja existeix.'));
         return system::redirect(ModUtil::url('Cataleg', 'admin', 'usersgest'));
     }
     $user['zk']['email'] = FormUtil::getPassedValue('email', null, 'POST');
     $user['iw']['nom'] = FormUtil::getPassedValue('iw_nom', null, 'POST');
     $user['iw']['cognom1'] = FormUtil::getPassedValue('iw_cognom1', null, 'POST');
     $user['iw']['cognom2'] = FormUtil::getPassedValue('iw_cognom2', null, 'POST');
     $user['gr'] = FormUtil::getPassedValue('groups', null, 'POST');
     
     $prev_pass = FormUtil::getPassedValue('prev_pass', 0, 'POST');
     $setpass = FormUtil::getPassedValue('setpass', 0, 'POST');
     if ($setpass == 1) {
         $password = FormUtil::getPassedValue('password', null, 'POST');
         $changeme = FormUtil::getPassedValue('changeme', 0, 'POST');
     } else {
         $password = null;
     }
     $setcode = FormUtil::getPassedValue('setcode', 0, 'POST');
     if ($setcode == 1) $iwcode = FormUtil::getPassedValue('iwcode_s', null, 'POST');
     if ($setcode == 2) $iwcode = FormUtil::getPassedValue('iwcode_m', null, 'POST');
     if ($iwcode) {
         $user['iw']['code'] = $iwcode;
     } elseif ($r == 'edit'){
         $iwcode = DBUtil::selectField('IWusers', 'code', 'iw_uid='.$user['zk']['uid']);
     }
     if ($iwcode) {
         $gtafInfo = ModUtil::apiFunc('Cataleg','admin','getGtafEntity',$iwcode);
         $grupCat = ModUtil::apiFunc('Cataleg', 'admin', 'getgrupsZikula');
         if (isset($grupCat[$gtafInfo['entity']['tipus']])) $user['gr'][] = $grupCat[$gtafInfo['entity']['tipus']];
     }
     $insertUserId = ModUtil::apifunc('Cataleg', 'admin', 'saveUser', $user);
     if ($insertUserId) {
         if ($r == 'edit') {
             LogUtil::registerStatus($this->__('L\'usuari s\'ha editat correctament.'));
         } else {
             LogUtil::registerStatus($this->__('L\'usuari s\'ha creat correctament.'));
         }
     } else {
         LogUtil::registerError($this->__('No s\'ha pogut desar l\'usuari.'));
         return system::redirect(ModUtil::url('Cataleg', 'admin', 'usersgest'));
     }
     //Si es tria 'buidar' la contrasenya, aquesta opció mana sobre el canvi i forçar el canvi
     if ($setpass == 2) {
         $reg = array('pass' => '');
         if (DBUtil::updateObject($reg,'users','uid ='. $insertUserId)) {
             UserUtil::setVar('', $passreminder, $insertUserId);
             LogUtil::registerStatus($this->__('L\'usuari haurà de validar-se per LDAP'));
         }
     }
     // Segon pas: desem el possible canvi de contrasenya
     if ($password) {
         $rpassword = FormUtil::getPassedValue('rpassword', null, 'POST');
         $passreminder = $this->__('Constasenya establerta des de l\'administració.');
         $passwordErrors = ModUtil::apiFunc('Users', 'registration', 'getPasswordErrors', array(
                     'uname' => $user['zk']['uname'],
                     'pass' => $password,
                     'passagain' => $rpassword,
                     'passreminder' => $passreminder
         ));
         if (empty($passwordErrors)) {
             if (UserUtil::setPassword($password, $insertUserId)) {
                 UserUtil::setVar('passreminder', $passreminder, $insertUserId);
                 LogUtil::registerStatus($this->__('S\'ha desat la contrasenya.'));
             }
         } else {
             LogUtil::registerError($this->__('No s\'ha desat la contrasenya.'));
             LogUtil::registerError($passwordErrors['pass']);
         }
     }
     // Tercer pas: establim la variable que controla el forçar el canvi de contrasenya
     if ($setpass == 1 && ($prev_pass || $password)) {
         UserUtil::setVar('_Users_mustChangePassword', $changeme, $insertUserId);
         if ($changeme == 1)
             LogUtil::registerStatus($this->__('L\'usuari haurà de canviar la contrasenya en la propera validació.'));
     }
     return system::redirect(ModUtil::url('Cataleg', 'admin', 'usersgest'));
 }
Esempio n. 5
0
    /**
     * Authenticates authentication_info with the authenticating source, returning a simple boolean result.
     *
     * Note that, despite this function's name, there is no requirement that a password be part of the authentication_info.
     * Merely that enough information be provided in the authentication_info array to unequivocally authenticate the user. For
     * most authenticating authorities this will be the equivalent of a user name and password, but--again--there
     * is no restriction here. This is not, however, a "user exists in the system" function. It is expected that
     * the authenticating authority validate what ever is used as a password or the equivalent thereof.
     *
     * This function makes no attempt to match the given authentication_info with a Zikula user id (uid). It simply asks the
     * authenticating authority to authenticate the authentication_info provided. No "login" should take place as a result of
     * this authentication.
     *
     * This function may be called to initially authenticate a user during the registration process, or may be called
     * for a user already logged in to re-authenticate his password for a security-sensitive operation. This function
     * should merely authenticate the user, and not perform any additional login-related processes.
     *
     * This function differs from authenticateUser() in that no attempt is made to match the authentication_info with and map to a
     * Zikula user account. It does not return a Zikula user id (uid).
     *
     * Parameters passed in $args:
     * ---------------------------
     * array $args['authentication_info']   The information needed for this authenticationModule, including any user-entered
     *                                              information. For the Users module, this contains the elements 'login_id' and 'pass'.
     *                                              The 'login_id' element contains either the user name or the e-mail address of the
     *                                              user logging in, depending on the authentication_method. The 'pass' contains the
     *                                              password entered by the user.
     * array $args['authentication_method'] An array containing the authentication method, including the 'modname' (which should match this
     *                                              module's module name), and the 'method' method name. For the Users module, 'modname' would
     *                                              be 'Users' and 'method' would contain either 'email' or 'uname'.
     *
     * @param array $args All arguments passed to this function.
     *
     * @return boolean True if the authentication_info authenticates with the source; otherwise false on authentication failure.
     *
     * @throws Zikula_Exception_Fatal Thrown if invalid parameters are sent in $args.
     */
    public function checkPassword(array $args)
    {
        // Note that this is a poor example function for external authenticationModules, because the authenticating
        // information for the Users module is stored in the users table, necessitating a lookup of the uid.
        //
        // For authentication modules other than the Users module, no attempt to look up the user account in the Users tables should be
        // made in the checkPassword function.

        if (!isset($args['authentication_info']) || !is_array($args['authentication_info']) || empty($args['authentication_info'])) {
            throw new Zikula_Exception_Fatal($this->__f('Invalid \'%1$s\' parameter received in a call to %2$s', array('authentication_info', __METHOD__)));
        }

        if (!isset($args['authentication_method']) || !is_array($args['authentication_method']) || empty($args['authentication_method'])) {
            throw new Zikula_Exception_Fatal($this->__f('Invalid \'%1$s\' parameter received in a call to %2$s', array('authentication_method', __METHOD__)));
        }

        $authenticationInfo = $args['authentication_info'];
        $authenticationMethod = $args['authentication_method'];

        $passwordAuthenticates = false;

        $getUidArgs = array(
            'authentication_info'   => $authenticationInfo,
            'authentication_method' => $authenticationMethod,
        );
        $uid = ModUtil::apiFunc($this->name, 'Authentication', 'getUidForAuthenticationInfo', $getUidArgs, 'Zikula_Api_AbstractAuthentication');

        if ($uid) {
            if (!isset($authenticationInfo['pass']) || !is_string($authenticationInfo['pass'])
                    || empty($authenticationInfo['pass'])) {
                // The user did not specify a password, or the one specified is invalid.
                throw new Zikula_Exception_Fatal($this->__('Error! A password must be provided.'));
            }

            // For a custom authenticationModule, we'd map the authenticationInfo to a uid above, and then execute the custom
            // authentication process here. On success the uid would be returned, otherwise false is returned. Note that
            // any "log in" into the Zikula site is not done here. This is simply verification that the authenticationInfo,
            // including the password, is valid as a unit.

            $userObj = UserUtil::getVars($uid, true);
            if (!$userObj) {
                // Must be a registration. Acting as an authenticationModule, we should not care at this point about the user's
                // account status. We will deal with the account status in a moment.
                $userObj = UserUtil::getVars($uid, true, '', true);

                if (!$userObj) {
                    // Neither an account nor a pending registration request. This should really not happen since we have a uid.
                    throw new Zikula_Exception_Fatal($this->__f('A user id was located, but the user account record could not be retrieved in a call to %1$s.', array(__METHOD__)));
                }
            }

            // Check for an empty password, or the special marker indicating that the account record does not
            // authenticate with a uname/password (or email/password, depending on the 'loginviaoption' setting) from
            // the Users module. An empty password can be created when an administrator creates a user registration
            // record pending e-mail verification and does not set a password for the user (the user will set it
            // upon verifying his email address). The special marker indicating that the account does not authenticate
            // with the Users module is used when a user registers a new account with the system using an authentication
            // method other than uname/pass or email/pass. In both cases, authentication automatically fails.
            if (!empty($userObj['pass']) && ($userObj['pass'] != Users_Constant::PWD_NO_USERS_AUTHENTICATION)) {
                // The following check for non-salted passwords and the old 'hash_method' field is to allow the admin to log in
                // during an upgrade from 1.2.
                // *** IMPORTANT ***
                // This needs to be kept for any version that allows an upgrade from Zikula 1.2.X.
                $methodSaltDelimPosition = strpos($userObj['pass'], Users_Constant::SALT_DELIM);
                $saltPassDelimPosition = ($methodSaltDelimPosition === false) ? false : strpos($userObj['pass'], Users_Constant::SALT_DELIM, ($methodSaltDelimPosition + 1));
                if ($saltPassDelimPosition === false) {
                    // Old style unsalted password with hash_method in separate field
                    // If this release version of Zikula Users Module allows upgrade from 1.2.X, then this part must be
                    // kept. If this release version of Zikula Users Module DOES NOT support upgrade from 1.2.X then this
                    // is the part that can go away.
                    if (!isset($userObj['hash_method'])) {
                        // Something is horribly wrong. The password on the user account record does not look like the
                        // new style of hashing, and yet the old-style hash method field is nowhere to be found.
                        throw new Zikula_Exception_Fatal($this->__('Invalid account password state.'));
                    }
                    $currentPasswordHashed = $userObj['hash_method'] . '$$' . $userObj['pass'];
                } else {
                    // New style salted password including hash method code.
                    // If this release version of Zikula Users module does not allow upgrade from 1.2.X, then this
                    // is the part to keep.
                    $currentPasswordHashed = $userObj['pass'];
                }
                // *** IMPORTANT ***
                // End of old-style versus new-style hashing handling. When the possiblity to upgrade from 1.2.X is
                // removed from the released version of Zikula Users Module, then delete this section, and replace
                // $currentPasswordHashed with $userObj['pass'] in the call to passwordsMatch below.

                if (UserUtil::passwordsMatch($authenticationInfo['pass'], $currentPasswordHashed)) {
                    // Password in $authenticationInfo['pass'] is good at this point.

                    // *** IMPORTANT ***
                    // Again, this section is for converting old-style hashing to new-style hashing. Same as noted
                    // above applies to this section.
                    // See if we need to convert the password hashing to the new configuration.
                    if (version_compare($this->modinfo['version'], '2.0.0') >= 0) {
                        // Check stored hash matches the current system type, if not convert it--but only if the module version is sufficient.
                        // Note: this is purely specific to the Users module authentication. A custom module might do something similar if it
                        // changed the way it stored some piece of data between versions, but in general this would be uncommon.
                        list($currentPasswordHashCode, $currentPasswordSaltStr, $currentPasswordHashStr) = explode(Users_Constant::SALT_DELIM, $currentPasswordHashed);
                        $systemHashMethodCode = UserUtil::getPasswordHashMethodCode($this->getVar('hash_method', 'sha256'));
                        if (($systemHashMethodCode != $currentPasswordHashCode) || empty($currentPasswordSaltStr)) {
                            if (!UserUtil::setPassword($authenticationInfo['pass'], $uid)) {
                                LogUtil::log($this->__('Internal Error! Unable to update the user\'s password with the new hashing method and/or salt.'), 'CORE');
                            }
                        }
                    }
                    // *** IMPORTANT ***
                    // End of old-style to new-style hasing conversion.

                    // The password is good, so the password is authenticated.
                    $passwordAuthenticates = true;
                }
            }
        }

        if (!$passwordAuthenticates && !$this->request->getSession()->hasMessages(Zikula_Session::MESSAGE_ERROR)) {
            if ($authenticationMethod['method'] == 'email') {
                $this->registerError($this->__('Sorry! The e-mail address or password you entered was incorrect.'));
            } else {
                $this->registerError($this->__('Sorry! The user name or password you entered was incorrect.'));
            }
        }

        return $passwordAuthenticates;
    }
Esempio n. 6
0
    /**
     * Update the user's password.
     *
     * Parameters passed via GET:
     * --------------------------
     * None.
     *
     * Parameters passed via POST:
     * ---------------------------
     * string oldpassword        The original password.
     * string newpassword        The new password to be stored for the user.
     * string newpasswordconfirm Verification of the new password to be stored for the user.
     *
     * Parameters passed via SESSION:
     * ------------------------------
     * Namespace: Zikula_Users
     * Variable:  Users_Controller_User_updatePassword
     * Type:      array
     * Contents:  An array containing the information saved from the log-in attempt in order to re-enter it, including:
     *              'authentication_method', an array containing the selected authentication module name and method name,
     *              'authentication_info', an array containing the authentication information entered by the user,
     *              'user_obj', a user record containing the user information found during the log-in attempt,
     *              'password_errors', errors that have occurred during a previous pass through this function.
     *
     * @return bool True on success, otherwise false.
     */
    public function updatePassword()
    {
        $sessionVars = $this->request->getSession()->get('Users_Controller_User_updatePassword', null, 'Zikula_Users');
        $this->request->getSession()->del('Users_Controller_User_updatePassword', 'Zikula_Users');

        if (!$this->request->isPost()) {
            throw new Zikula_Exception_Forbidden();
        }

        $this->checkCsrfToken();

        if (isset($sessionVars) && !empty($sessionVars)) {
            $login = true;
            $userObj = $sessionVars['user_obj'];
        } else {
            $login = false;
            $userObj = UserUtil::getVars(UserUtil::getVar('uid'), true);
        }
        $uid = $userObj['uid'];

        if (!$login && !UserUtil::isLoggedIn()) {
            throw new Zikula_Exception_Forbidden();
        } elseif ($login && UserUtil::isLoggedIn()) {
            throw new Zikula_Exception_Fatal();
        }

        $passwordChanged    = false;
        $currentPassword    = $this->request->request->get('oldpassword', '');
        $newPassword        = $this->request->request->get('newpassword', '');
        $newPasswordAgain   = $this->request->request->get('newpasswordconfirm', '');
        $newPasswordReminder= $this->request->request->get('passreminder', '');
        $passwordErrors     = array();

        if (empty($currentPassword) || !UserUtil::passwordsMatch($currentPassword, $userObj['pass'])) {
            $passwordErrors['oldpass'][] = $this->__('The current password you entered is not correct. Please correct your entry and try again.');
        } else {
            $passwordErrors = ModUtil::apiFunc($this->name, 'registration', 'getPasswordErrors', array(
                'uname'         => $userObj['uname'],
                'pass'          => $newPassword,
                'passagain'     => $newPasswordAgain,
                'passreminder'  => $newPasswordReminder
            ));

            if ($login && ($currentPassword == $newPassword)) {
                $passwordErrors['reginfo_pass'][] = $this->__('Your new password cannot match your current password.');
            }
        }

        if (empty($passwordErrors)) {
            if (UserUtil::setPassword($newPassword, $uid)) {
                // no user.update event for password chagnes.

                $passwordChanged = true;

                // Clear the forced change of password flag, if it exists.
                UserUtil::delVar('_Users_mustChangePassword', $uid);

                if (!UserUtil::setVar('passreminder', $newPasswordReminder, $uid)) {
                    $this->registerError($this->__('Warning! Your new password was saved, however there was a problem saving your new password reminder.'));
                } else {
                    $this->registerStatus($this->__('Done! Saved your new password.'));
                }

                $userObj = UserUtil::getVars(UserUtil::getVar('uid'), true);
                if ($login) {
                    $sessionVars['user_obj'] = $userObj;
                    if ($sessionVars['authentication_method']['modname'] == $this->name) {
                        // The password for Users module authentication was just changed.
                        // In order to successfully log in the user, we need to change it on the authentication_info.
                        $sessionVars['authentication_info']['pass'] = $newPassword;
                    }
                }
            } else {
                throw new Zikula_Exception_Fatal($this->__('Sorry! There was a problem saving your new password.'));
            }
        }

        if ($passwordChanged) {
            if ($login) {
                $loginArgs = $this->request->getSession()->get('Users_Controller_User_login', array(), 'Zikula_Users');
                $loginArgs['authentication_method'] = $sessionVars['authentication_method'];
                $loginArgs['authentication_info']   = $sessionVars['authentication_info'];
                $loginArgs['rememberme']            = $sessionVars['rememberme'];

                return ModUtil::func($this->name, 'user', 'login', $loginArgs);
            } else {
                return $this->redirect(ModUtil::url($this->name, 'user', 'main'));
            }
        } else {
            $sessionVars['password_errors'] = $passwordErrors;
            SessionUtil::requireSession();
            $this->request->getSession()->set('Users_Controller_User_changePassword', $sessionVars, 'Zikula_Users');
            $this->redirect(ModUtil::url($this->name, 'user', 'changePassword', array('login' => $login)));
        }
    }