From: <gem...@li...> - 2011-11-14 11:59:04
|
Revision: 204 http://gemstracker.svn.sourceforge.net/gemstracker/?rev=204&view=rev Author: matijsdejong Date: 2011-11-14 11:58:57 +0000 (Mon, 14 Nov 2011) Log Message: ----------- #31 ready, respondents login can be added Modified Paths: -------------- branches/newUser2/classes/Gems/Default/IndexAction.php branches/newUser2/classes/Gems/Default/OptionAction.php branches/newUser2/classes/Gems/User/StaffUserDefinition.php branches/newUser2/classes/Gems/User/User.php branches/newUser2/classes/Gems/User/UserDefinitionAbstract.php branches/newUser2/classes/Gems/User/UserDefinitionInterface.php branches/newUser2/classes/GemsEscort.php Modified: branches/newUser2/classes/Gems/Default/IndexAction.php =================================================================== --- branches/newUser2/classes/Gems/Default/IndexAction.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/Default/IndexAction.php 2011-11-14 11:58:57 UTC (rev 204) @@ -105,6 +105,16 @@ } /** + * Returns an element for keeping a reset key. + * + * @return Zend_Form_Element_Hidden + */ + protected function _getKeyElement() + { + return new Zend_Form_Element_Hidden('key'); + } + + /** * Returns a login form * * @return Gems_Form @@ -187,6 +197,7 @@ protected function _getResetForm() { $form = $this->_getBasicForm($this->_('Reset password for %s application')); + $form->addElement($this->_getKeyElement()); $form->addElement($this->_getOrganizationElement()); $form->addElement($this->_getUserLoginElement()); $form->addElement($this->_getSubmitButton($this->_('Reset password'))); @@ -326,42 +337,25 @@ $this->view->setScriptPath(GEMS_LIBRARY_DIR . '/views/scripts' ); $request = $this->getRequest(); - if ($key = $request->getParam('key')) { - /* - $sql = $this->db->quoteInto("SELECT gus_id_user, gsf_email FROM gems__users INNER JOIN gems__staff ON gus_id_user = gsf_id_user WHERE gus_reset_key = ?", $key); - $result = $this->db->fetchRow($sql); + $form = $this->_getResetForm(); + if ($request->isPost() && $form->isValid($request->getPost())) { - if (!empty($result)) { - // generate new password - $password = $this->escort->getRandomPassword(); - $passwordHash = $this->escort->passwordHash(null, $password, false); + $user = $this->loader->getUser($request->getParam('userlogin'), $request->getParam('organization')); - $mail->setSubject('New password'); - $mail->setBodyText('Your new password has been generated. Your new password is: ' . $password); - - $mail->addTo($result['gsf_email']); - - try { - $mail->send(); - $this->addMessage($this->_('An e-mail was sent containing your new password')); - $this->db->update('gems__users', array('gus_reset_key' => new Zend_Db_Expr('NULL'), 'gus_reset_requested' => new Zend_Db_Expr('NULL'), 'gus_password' => $passwordHash), 'gus_id_user = ' . $result['gus_id_user']); - $this->_reroute(array('action' => 'index'), true); - } catch (Exception $e) { - $this->addMessage($this->_('Unable to send e-mail')); - throw $e; - } - } else { - $this->addMessage($this->_('Unknown request')); - } // */ - - } else { - $form = $this->_getResetForm(); - if ($request->isPost() && $form->isValid($request->getPost())) { - - $user = $this->loader->getUser($request->getParam('userlogin'), $request->getParam('organization')); - - If ($user->canResetPassword()) { - + If ($user->canResetPassword()) { + if ($key = $request->getParam('key')) { + // Key has been passed by mail + if ($user->checkPasswordResetKey($key)) { + $user->setPasswordResetRequired(true); + $user->setAsCurrentUser(); + $this->addMessage($this->_('Reset accepted, enter your new password.')); + $user->gotoStartPage($this->menu, $request); + return; + } else { + $this->addMessage($this->_('This key timed out or does not belong to this user.')); + } + } else { + // P{ass mail by key $mail = new MUtil_Mail(); $mail->setFrom('mj...@ma...'); $mail->addTo($user->getEmailAddress(), $user->getFullName()); @@ -375,22 +369,26 @@ $url = $this->util->getCurrentURI('index/resetpassword/key/' . $key); - $mail->setSubject('Password reset requested'); - $mail->setBodyText('To reset your password, please click this link: ' . $url); + $mail->setSubject($this->_('Password reset requested')); + $mail->setBodyText(sprintf($this->_('To reset your password for %s, please click this link: %s'), GEMS_PROJECT_NAME_UC, $url)); try { $mail->send(); - $this->addMessage($this->_('Follow the instructions in the e-mail.')); + $this->addMessage($this->_('We sent you an e-mail with a reset link. Click on the link in the e-mail.')); } catch (Exception $e) { $this->addMessage($this->_('Unable to send e-mail.')); throw $e; } - } else { - $this->addMessage($this->_('No such user found or no e-mail address known or user cannot be reset.')); } + } else { + $this->addMessage($this->_('No such user found or no e-mail address known or user cannot be reset.')); } - $this->view->form = $form; } + if ($request->getParam('key')) { + $this->addMessage($this->_('We received your password reset key.')); + $this->addMessage($this->_('Please enter the organization and username belonging to this key.')); + } + $this->view->form = $form; } } Modified: branches/newUser2/classes/Gems/Default/OptionAction.php =================================================================== --- branches/newUser2/classes/Gems/Default/OptionAction.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/Default/OptionAction.php 2011-11-14 11:58:57 UTC (rev 204) @@ -85,7 +85,9 @@ return; } - if ($user->hasPassword()) { + if ($user->isPasswordResetRequired()) { + $this->menu->setVisible(false); + } elseif ($user->hasPassword()) { // Field current password // // This is only used when the password is already set, which may not always be the case @@ -151,7 +153,7 @@ $table->setAsFormLayout($form, true, true); $table['tbody'][0][0]->class = 'label'; // Is only one row with formLayout, so all in output fields get class. - if ($links = $this->createMenuLinks()) { + if (! $user->isPasswordResetRequired() && ($links = $this->createMenuLinks())) { $table->tf(); // Add empty cell, no label $linksCell = $table->tf($links); } Modified: branches/newUser2/classes/Gems/User/StaffUserDefinition.php =================================================================== --- branches/newUser2/classes/Gems/User/StaffUserDefinition.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/User/StaffUserDefinition.php 2011-11-14 11:58:57 UTC (rev 204) @@ -115,6 +115,28 @@ } /** + * Check whether a reset key is really linked to a user. + * + * @param Gems_User_User $user The user the key was created for (hopefully). + * @param string The key + * @return boolean + */ + public function checkPasswordResetKey(Gems_User_User $user, $key) + { + $model = new MUtil_Model_TableModel('gems__user_passwords'); + + $filter['gup_id_user'] = $user->getUserLoginId(); + $filter[] = 'DATE_ADD(gup_reset_requested, INTERVAL 24 HOUR) >= CURRENT_TIMESTAMP'; + + $row = $model->loadFirst($filter); + if ($row && $row['gup_reset_key']) { + return $key == $row['gup_reset_key']; + } + + return false; + } + + /** * Return a password reset key * * @param Gems_User_User $user The user to create a key for. @@ -127,7 +149,7 @@ $data['gup_id_user'] = $user->getUserLoginId(); - $row = $model->loadFirst($data); + $row = $model->loadFirst($data + array('DATE_ADD(gup_reset_requested, INTERVAL 24 HOUR) >= CURRENT_TIMESTAMP')); if ($row && $row['gup_reset_key']) { // Keep using the key. $data['gup_reset_key'] = $row['gup_reset_key']; @@ -166,6 +188,8 @@ 'user_organization_id'=>'gor_id_organization', 'user_organization_name'=>'gor_name', 'user_style' => 'gor_style')) + ->joinLeft('gems__user_passwords', 'gul_id_user = gup_id_user', + array('user_password_reset' => 'gup_reset_required')) ->where('ggp_group_active = 1') ->where('gor_active = 1') ->where('gsf_active = 1') @@ -210,8 +234,10 @@ */ public function setPassword(Gems_User_User $user, $password) { - $data['gup_id_user'] = $user->getUserLoginId(); - $data['gup_reset_required'] = 0; + $data['gup_id_user'] = $user->getUserLoginId(); + $data['gup_reset_key'] = null; + $data['gup_reset_requested'] = null; + $data['gup_reset_required'] = 0; if (null === $password) { // Passwords may be emptied. $data['gup_password'] = null; Modified: branches/newUser2/classes/Gems/User/User.php =================================================================== --- branches/newUser2/classes/Gems/User/User.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/User/User.php 2011-11-14 11:58:57 UTC (rev 204) @@ -204,6 +204,17 @@ } /** + * Check whether a reset key is really linked to this user. + * + * @param string The key + * @return boolean + */ + public function checkPasswordResetKey($key) + { + return $this->definition->checkPasswordResetKey($this, $key); + } + + /** * Should be called after answering the request to allow the Target * to check if all required registry values have been set correctly. * @@ -319,6 +330,16 @@ } /** + * Returns the current user role. + * + * @return string + */ + public function getRole() + { + return $this->_getVar('user_role'); + } + + /** * Returns the user id, that identifies this user within this installation. * * One user id might be connected to multiple logins for multiple organizations. @@ -352,6 +373,35 @@ } /** + * Redirects the user to his/her start page. + * + * @param Gems_Menu $menu + * @param Zend_Controller_Request_Abstract $request + * @return Gems_Menu_SubMenuItem + */ + public function gotoStartPage(Gems_Menu $menu, Zend_Controller_Request_Abstract $request) + { + if ($this->isPasswordResetRequired()) { + // Set menu OFF + $menu->setVisible(false); + + $menuItem = $menu->findFirst(array($request->getControllerKey() => 'option', $request->getActionKey() => 'change-password')); + // This may not yet be true, but is needed for the redirect. + $menuItem->set('allowed', true); + $menuItem->set('visible', true); + } else { + $menuItem = $menu->findFirst(array('allowed' => true, 'visible' => true)); + } + + if ($menuItem) { + $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); + $redirector->gotoRoute($menuItem->toRouteUrl($request)); + } + + return $menuItem; + } + + /** * Return true if this user has a password. * * @return boolean @@ -368,7 +418,7 @@ */ public function hasPassword() { - return $this->definition->hasPassword(); + return $this->definition->hasPassword($this); } /** @@ -401,12 +451,22 @@ } /** + * True when this user must enter a new password. + * + * @return boolean + */ + public function isPasswordResetRequired() + { + return (boolean) $this->_getVar('user_password_reset'); + } + + /** * Set this user as the current user. * * This means that the data about this user will be stored in a session. * * @param boolean $signalLoader Do not set, except from UserLoader - * @return Gems_User_UserAbstract (continuation pattern) + * @return Gems_User_User (continuation pattern) */ public function setAsCurrentUser($signalLoader = true) { @@ -436,7 +496,7 @@ * Set the password, if allowed for this user type. * * @param string $password - * @return Gems_User_UserAbstract (continuation pattern) + * @return Gems_User_User (continuation pattern) */ public function setPassword($password) { @@ -445,12 +505,23 @@ } /** + * + * @param boolean $reset + * @return Gems_User_User (continuation pattern) + */ + public function setPasswordResetRequired($reset = true) + { + $this->_setVar('user_password_reset', (boolean) $reset); + return $this; + } + + /** * Unsets this user as the current user. * * This means that the data about this user will no longer be stored in a session. * * @param boolean $signalLoader Do not set, except from UserLoader - * @return Gems_User_UserAbstract (continuation pattern) + * @return Gems_User_User (continuation pattern) */ public function unsetAsCurrentUser($signalLoader = true) { Modified: branches/newUser2/classes/Gems/User/UserDefinitionAbstract.php =================================================================== --- branches/newUser2/classes/Gems/User/UserDefinitionAbstract.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/User/UserDefinitionAbstract.php 2011-11-14 11:58:57 UTC (rev 204) @@ -77,6 +77,18 @@ } /** + * Check whether a reset key is really linked to a user. + * + * @param Gems_User_User $user The user the key was created for (hopefully). + * @param string The key + * @return string + */ + public function checkPasswordResetKey(Gems_User_User $user, $key) + { + throw new Gems_Exception_Coding(sprintf('A password reset key cannot be issued for %s users.', get_class($this))); + } + + /** * Return a password reset key * * @param Gems_User_User $user The user to create a key for. Modified: branches/newUser2/classes/Gems/User/UserDefinitionInterface.php =================================================================== --- branches/newUser2/classes/Gems/User/UserDefinitionInterface.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/Gems/User/UserDefinitionInterface.php 2011-11-14 11:58:57 UTC (rev 204) @@ -79,6 +79,15 @@ public function checkPassword($login_name, $organization, $password); /** + * Check whether a reset key is really linked to a user. + * + * @param Gems_User_User $user The user the key was created for (hopefully). + * @param string The key + * @return string + */ + public function checkPasswordResetKey(Gems_User_User $user, $key); + + /** * Return a password reset key * * @param Gems_User_User $user The user to create a key for. Modified: branches/newUser2/classes/GemsEscort.php =================================================================== --- branches/newUser2/classes/GemsEscort.php 2011-11-14 10:21:54 UTC (rev 203) +++ branches/newUser2/classes/GemsEscort.php 2011-11-14 11:58:57 UTC (rev 204) @@ -1440,12 +1440,15 @@ */ public function routeShutdown(Zend_Controller_Request_Abstract $request) { + $loader = $this->getLoader(); + $user = $loader->getCurrentUser(); + // MUtil_Echo::r($request->getParams(), 'params'); // MUtil_Echo::r($request->getUserParams(), 'userparams'); // Load the menu. As building the menu can depend on all resources and the request, we do it here. // // PS: The REQUEST is needed because otherwise the locale for translate is not certain. - $this->menu = $this->getLoader()->createMenu($this); + $this->menu = $loader->createMenu($this); $this->_updateVariable('menu'); /** @@ -1453,7 +1456,7 @@ * directory with the name lock.txt */ if ($this->getUtil()->getMaintenanceLock()->isLocked()) { - if ($this->session->user_id && $this->session->user_role !== 'master') { + if ($user->isActive() && $user->getRole() !== 'master') { //Still allow logoff so we can relogin as master if (!('index' == $request->getControllerName() && 'logoff' == $request->getActionName())) { $this->setError( @@ -1461,6 +1464,7 @@ 401, $this->_('System is in maintenance mode')); } + $user->unsetAsCurrentUser(); } else { $this->addMessage($this->_('System is in maintenance mode')); MUtil_Echo::r($this->_('System is in maintenance mode')); @@ -1470,12 +1474,7 @@ // Gems does not use index/index if (('index' == $request->getControllerName()) && ('index' == $request->getActionName())) { // Instead Gems routes to the first available menu item when this is the request target - if ($menuItem = $this->menu->findFirst(array('allowed' => true, 'visible' => true))) { - $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector'); - $redirector->gotoRoute($menuItem->toRouteUrl($request)); - //$menuItem->applyToRequest($request); - //$this->setControllerDirectory($request); // Maybe the controller directory to be used changed - } else { + if (! $user->gotoStartPage($this->menu, $request)) { $this->setError( $this->_('No access to site.'), 401, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |