|
From: <gem...@li...> - 2012-03-23 18:23:15
|
Revision: 564
http://gemstracker.svn.sourceforge.net/gemstracker/?rev=564&view=rev
Author: matijsdejong
Date: 2012-03-23 18:23:04 +0000 (Fri, 23 Mar 2012)
Log Message:
-----------
Password validated in login form
OldStyle staff users are upgraded to new style staff users during login
Authentication easier to extend / adapt
Fixed temp fix in svn update 552 with callable (in project using it)
Modified Paths:
--------------
trunk/library/changelog.txt
trunk/library/classes/Gems/Default/IndexAction.php
trunk/library/classes/Gems/Project/ProjectSettings.php
trunk/library/classes/Gems/User/DbUserDefinitionAbstract.php
trunk/library/classes/Gems/User/Form/ChangePasswordForm.php
trunk/library/classes/Gems/User/Form/LoginForm.php
trunk/library/classes/Gems/User/NoLoginDefinition.php
trunk/library/classes/Gems/User/OldStaffUserDefinition.php
trunk/library/classes/Gems/User/ProjectUserDefinition.php
trunk/library/classes/Gems/User/RadiusUserDefinition.php
trunk/library/classes/Gems/User/User.php
trunk/library/classes/Gems/User/UserDefinitionInterface.php
trunk/library/classes/Gems/User/UserLoader.php
trunk/library/classes/MUtil/Model/DatabaseModelAbstract.php
trunk/library/classes/MUtil/Model/TableBridgeAbstract.php
trunk/library/configs/db/patches.sql
trunk/library/configs/db/tables/gems__user_login_attempts.10.sql
Added Paths:
-----------
trunk/library/classes/Gems/User/Validate/
trunk/library/classes/Gems/User/Validate/GetUserInterface.php
trunk/library/classes/Gems/User/Validate/GetUserPasswordValidator.php
trunk/library/classes/Gems/User/Validate/NewPasswordValidator.php
trunk/library/classes/Gems/User/Validate/PasswordValidatorAbstract.php
trunk/library/classes/Gems/User/Validate/UserPasswordValidator.php
Removed Paths:
-------------
trunk/library/classes/Gems/User/UserNewPasswordValidator.php
trunk/library/classes/Gems/User/UserPasswordValidator.php
Modified: trunk/library/changelog.txt
===================================================================
--- trunk/library/changelog.txt 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/changelog.txt 2012-03-23 18:23:04 UTC (rev 564)
@@ -1,3 +1,12 @@
+Important changes from 1.5.2 => 1.5.3
+============================================================
+People can login using their e-amil address as user name.
+Showing a list of organizations to choose during login happens except when 1) there is only one organization or 2) a url is used that is assigned to a specific organization.
+Login & other password forms are now easy to customize on a per project basis.
+Login and authorizaiton rules are easier to extend.
+Alll password rules are reported during reset.
+
+
Important changes from 1.5.1 => 1.5.2
============================================================
Renamed project.ini setting concentRejected to consentRejected
Modified: trunk/library/classes/Gems/Default/IndexAction.php
===================================================================
--- trunk/library/classes/Gems/Default/IndexAction.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/Default/IndexAction.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -161,7 +161,7 @@
Gems_Html::init();
return $this->loader->getUserLoader()->getLoginForm($args);
-
+ /*
$form = $this->_getBasicForm();
$form->addElement($this->_getOrganizationElement());
$form->addElement($this->_getUserLoginElement());
@@ -175,7 +175,7 @@
$form->addElement($this->_getResetLinkElement());
}
- return $form;
+ return $form; // */
}
/**
@@ -330,64 +330,54 @@
if ($request->isPost()) {
if ($form->isValid($request->getPost(), false)) {
+ $user = $form->getUser();
- $user = $this->loader->getUser($request->getParam('userlogin'), $request->getParam('organization'));
+ $previousRequestParameters = $this->session->previousRequestParameters;
- // NO!!! DO not test! Otherwise it is easy to test which users exist.
- // if ($user->isActive()) {
- $formValues = $form->getValues();
- $authResult = $user->authenticate($formValues);
+ $user->setAsCurrentUser();
- if ($authResult->isValid()) {
- $previousRequestParameters = $this->session->previousRequestParameters;
+ if ($messages = $user->reportPasswordWeakness($request->getParam($form->passwordFieldName))) {
+ $user->setPasswordResetRequired(true);
+ $this->addMessage($this->_('Your password must be changed.'));
+ $this->addMessage($messages);
+ }
- $user->setAsCurrentUser();
+ /**
+ * Fix current locale in cookies
+ */
+ Gems_Cookies::setLocale($user->getLocale(), $this->basepath->getBasePath());
- $user->afterLogin($form->getValues());
+ /**
+ * Ready
+ */
+ $this->addMessage(sprintf($this->_('Login successful, welcome %s.'), $user->getFullName()));
- //*
- if ($messages = $user->reportPasswordWeakness($request->getParam('password'))) {
- $user->setPasswordResetRequired(true);
- $this->addMessage($this->_('Your password must be changed.'));
- $this->addMessage($messages);
- } // */
+ /**
+ * Log the login
+ */
+ Gems_AccessLog::getLog($this->db)->log("index.login", $this->getRequest(), null, $user->getUserId(), true);
- /**
- * Fix current locale in cookies
- */
- Gems_Cookies::setLocale($user->getLocale(), $this->basepath->getBasePath());
-
- /**
- * Ready
- */
- $this->addMessage(sprintf($this->_('Login successful, welcome %s.'), $user->getFullName()));
-
- /**
- * Log the login
- */
- Gems_AccessLog::getLog($this->db)->log("index.login", $this->getRequest(), null, $user->getUserId(), true);
-
- if ($previousRequestParameters) {
- $this->_reroute(array('controller' => $previousRequestParameters['controller'], 'action' => $previousRequestParameters['action']), false);
- } else {
- // This reroutes to the first available menu page after login.
- //
- // Do not user $user->gotoStartPage() as the menu is still set
- // for no login.
- $this->_reroute(array('controller' => null, 'action' => null), true);
- }
- return;
+ if ($previousRequestParameters) {
+ $this->_reroute(array('controller' => $previousRequestParameters['controller'], 'action' => $previousRequestParameters['action']), false);
} else {
- //Now present the user with an error message
- $errors = $authResult->getMessages();
- $this->addMessage($errors);
-
- //Also log the error to the log table
- //when the project has logging enabled
- $logErrors = join(' - ', $errors);
- $log = Gems_AccessLog::getLog();
- $log->log('loginFail', $this->getRequest(), sprintf('Failed login for : %s (%s) - %s', $formValues['userlogin'], $formValues['organization'], $logErrors), null, true);
+ // This reroutes to the first available menu page after login.
+ //
+ // Do not user $user->gotoStartPage() as the menu is still set
+ // for no login.
+ $this->_reroute(array('controller' => null, 'action' => null), true);
}
+ return;
+ } else {
+ //Now present the user with an error message
+ $errors = $form->getErrorMessages();
+ $this->addMessage($errors);
+
+ //Also log the error to the log table
+ //when the project has logging enabled
+ $logErrors = join(' - ', $errors);
+ $msg = sprintf('Failed login for : %s (%s) - %s', $request->getParam($form->usernameFieldName), $request->getParam($form->organizationFieldName), $logErrors);
+ $log = Gems_AccessLog::getLog();
+ $log->log('loginFail', $this->getRequest(), $msg, null, true);
}
}
$this->view->form = $form;
Modified: trunk/library/classes/Gems/Project/ProjectSettings.php
===================================================================
--- trunk/library/classes/Gems/Project/ProjectSettings.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/Project/ProjectSettings.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -187,20 +187,6 @@
}
/**
- * Returns the factor used to delay account reloading.
- *
- * @return int
- */
- public function getAccountDelayFactor()
- {
- if ($this->offsetExists('account') && isset($this->account['delayFactor'])) {
- return intval($this->account['delayFactor']);
- } else {
- return 4;
- }
- }
-
- /**
* Returns an array with throttling settings for the ask
* controller
*
Modified: trunk/library/classes/Gems/User/DbUserDefinitionAbstract.php
===================================================================
--- trunk/library/classes/Gems/User/DbUserDefinitionAbstract.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/DbUserDefinitionAbstract.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -123,12 +123,11 @@
/**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
+ * @param Gems_User_User $user
* @param string $password
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password)
+ public function getAuthAdapter(Gems_User_User $user, $password)
{
$adapter = new Zend_Auth_Adapter_DbTable($this->db, 'gems__user_passwords', 'gul_login', 'gup_password');
@@ -137,9 +136,9 @@
$select = $adapter->getDbSelect();
$select->join('gems__user_logins', 'gup_id_user = gul_id_user', array())
->where('gul_can_login = 1')
- ->where('gul_id_organization = ?', $organizationId);
+ ->where('gul_id_organization = ?', $user->getBaseOrganizationId());
- $adapter->setIdentity($username)
+ $adapter->setIdentity($user->getLoginName())
->setCredential($pwd_hash);
return $adapter;
Modified: trunk/library/classes/Gems/User/Form/ChangePasswordForm.php
===================================================================
--- trunk/library/classes/Gems/User/Form/ChangePasswordForm.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/Form/ChangePasswordForm.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -168,7 +168,7 @@
$element->setAttrib('maxlength', 20);
$element->setRequired(true);
$element->setRenderPassword(true);
- $element->addValidator(new Gems_User_UserNewPasswordValidator($this->user));
+ $element->addValidator(new Gems_User_Validate_NewPasswordValidator($this->user));
$element->addValidator(new MUtil_Validate_IsConfirmed($this->_repeatPasswordFieldName, $this->translate->_('Repeat password')));
$this->addElement($element);
@@ -194,7 +194,7 @@
$element->setAttrib('maxlength', 20);
$element->setRenderPassword(true);
$element->setRequired(true);
- $element->addValidator(new Gems_User_UserPasswordValidator($this->user, $this->translate));
+ $element->addValidator(new Gems_User_Validate_UserPasswordValidator($this->user, $this->translate->_('Wrong password.')));
$this->addElement($element);
}
Modified: trunk/library/classes/Gems/User/Form/LoginForm.php
===================================================================
--- trunk/library/classes/Gems/User/Form/LoginForm.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/Form/LoginForm.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -44,7 +44,7 @@
* @license New BSD License
* @since Class available since version 1.5
*/
-class Gems_User_Form_LoginForm extends Gems_Form_AutoLoadFormAbstract
+class Gems_User_Form_LoginForm extends Gems_Form_AutoLoadFormAbstract implements Gems_User_Validate_GetUserInterface
{
/**
* The field name for the lost password element.
@@ -54,14 +54,6 @@
protected $_lostPasswordFieldName = 'lost_password';
/**
- * The field name for the organization element.
- *
- * @var string
- */
- protected $_organizationFieldName = 'organization';
-
-
- /**
* When true the organization was derived from the the url
*
* @var boolean
@@ -69,13 +61,6 @@
protected $_organizationFromUrl = false;
/**
- * The field name for the password element.
- *
- * @var string
- */
- protected $_passwordFieldName = 'password';
-
- /**
* The field name for the submit element.
*
* @var string
@@ -90,11 +75,10 @@
protected $_tokenFieldName = 'token_link';
/**
- * The field name for the username element.
*
- * @var string
+ * @var Gems_User_User
*/
- protected $_usernameFieldName = 'userlogin';
+ protected $_user;
/**
*
@@ -103,6 +87,13 @@
protected $loader;
/**
+ * The field name for the organization element.
+ *
+ * @var string
+ */
+ public $organizationFieldName = 'organization';
+
+ /**
* For small numbers of organizations a multiline selectbox will be nice. This
* setting handles how many lines will display at once. Use 1 for the normal
* dropdown selectbox
@@ -112,7 +103,14 @@
protected $organizationMaxLines = 6;
/**
+ * The field name for the password element.
*
+ * @var string
+ */
+ public $passwordFieldName = 'password';
+
+ /**
+ *
* @var Zend_Controller_Request_Abstract
*/
protected $request;
@@ -138,7 +136,14 @@
protected $translate;
/**
+ * The field name for the username element.
*
+ * @var string
+ */
+ public $usernameFieldName = 'userlogin';
+
+ /**
+ *
* @var Zend_Util
*/
protected $util;
@@ -161,7 +166,7 @@
}
$request = $this->getRequest();
- if ($request->isPost() && ($orgId = $request->getParam($this->_organizationFieldName))) {
+ if ($request->isPost() && ($orgId = $request->getParam($this->organizationFieldName))) {
return $orgId;
}
@@ -216,14 +221,14 @@
*/
public function getOrganizationElement()
{
- $element = $this->getElement($this->_organizationFieldName);
+ $element = $this->getElement($this->organizationFieldName);
$orgId = $this->getCurrentOrganizationId();
$orgs = $this->getLoginOrganizations();
$hidden = $this->_organizationFromUrl || (count($orgs) < 2);
if ($hidden) {
if (! $element instanceof Zend_Form_Element_Hidden) {
- $element = new Zend_Form_Element_Hidden($this->_organizationFieldName);
+ $element = new Zend_Form_Element_Hidden($this->organizationFieldName);
$this->addElement($element);
}
@@ -234,7 +239,7 @@
}
} elseif (! $element instanceof Zend_Form_Element_Select) {
- $element = new Zend_Form_Element_Select($this->_organizationFieldName);
+ $element = new Zend_Form_Element_Select($this->organizationFieldName);
$element->setLabel($this->translate->_('Organization'));
$element->setRequired(true);
$element->setMultiOptions($orgs);
@@ -257,16 +262,23 @@
*/
public function getPasswordElement()
{
- $element = $this->getElement($this->_passwordFieldName);
+ $element = $this->getElement($this->passwordFieldName);
if (! $element) {
// Veld password
- $element = new Zend_Form_Element_Password($this->_passwordFieldName);
+ $element = new Zend_Form_Element_Password($this->passwordFieldName);
$element->setLabel($this->translate->_('Password'));
$element->setAttrib('size', 10);
$element->setAttrib('maxlength', 20);
$element->setRequired(true);
+ if ($this->getOrganizationElement() instanceof Zend_Form_Element_Hidden) {
+ $explain = $this->translate->_('Combination of user and password not found.');
+ } else {
+ $explain = $this->translate->_('Combination of user and password not found for this organization.');
+ }
+ $element->addValidator(new Gems_User_Validate_GetUserPasswordValidator($this, $explain));
+
$this->addElement($element);
}
@@ -338,18 +350,29 @@
{
return MUtil_Html::create('a', array('controller' => 'ask', 'action' => 'token'), $this->translate->_('Enter your token...'), array('class' => 'actionlink'));
}
+
/**
+ * Returns a user
+ *
+ * @return Gems_User_User
+ */
+ public function getUser()
+ {
+ return $this->_user;
+ }
+
+ /**
* Returns/sets a login name element.
*
* @return Zend_Form_Element_Text
*/
public function getUserNameElement()
{
- $element = $this->getElement($this->_usernameFieldName);
+ $element = $this->getElement($this->usernameFieldName);
if (! $element) {
// Veld inlognaam
- $element = new Zend_Form_Element_Text($this->_usernameFieldName);
+ $element = new Zend_Form_Element_Text($this->usernameFieldName);
$element->setLabel($this->translate->_('Username'));
$element->setAttrib('size', 10);
$element->setAttrib('maxlength', 20);
@@ -362,6 +385,26 @@
}
/**
+ * Validate the form
+ *
+ * As it is better for translation utilities to set the labels etc. translated,
+ * the MUtil default is to disable translation.
+ *
+ * However, this also disables the translation of validation messages, which we
+ * cannot set translated. The MUtil form is extended so it can make this switch.
+ *
+ * @param array $data
+ * @param boolean $disableTranslateValidators Extra switch
+ * @return boolean
+ */
+ public function isValid($data, $disableTranslateValidators = null)
+ {
+ $this->_user = $this->loader->getUser($data[$this->usernameFieldName], $data[$this->organizationFieldName]);
+
+ return parent::isValid($data, $disableTranslateValidators);
+ }
+
+ /**
* The function that determines the element load order
*
* @return Gems_User_Form_LoginForm (continuation pattern)
Modified: trunk/library/classes/Gems/User/NoLoginDefinition.php
===================================================================
--- trunk/library/classes/Gems/User/NoLoginDefinition.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/NoLoginDefinition.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -47,27 +47,15 @@
class Gems_User_NoLoginDefinition extends Gems_User_UserDefinitionAbstract
{
/**
- * Helper method for the case a user tries to authenticate while he is inactive
- *
- * @return boolean
- */
- public function alwaysFalse()
- {
- return false;
- }
-
- /**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
+ * @param Gems_User_User $user
* @param string $password
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password)
+ public function getAuthAdapter(Gems_User_User $user, $password)
{
- $adapter = new Gems_Auth_Adapter_Callback(array($this,'alwaysFalse'), $username);
- return $adapter;
+ return false;
}
/**
@@ -80,8 +68,11 @@
public function getUserData($login_name, $organization)
{
return array(
- 'user_active' => false,
- 'user_role' => 'nologin',
+ 'user_login' => $login_name,
+ 'user_name' => $login_name,
+ 'user_base_org_id' => $organization,
+ 'user_active' => false,
+ 'user_role' => 'nologin',
);
}
}
Modified: trunk/library/classes/Gems/User/OldStaffUserDefinition.php
===================================================================
--- trunk/library/classes/Gems/User/OldStaffUserDefinition.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/OldStaffUserDefinition.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -60,23 +60,6 @@
protected $project;
/**
- * Perform UserDefinition specific post-login logic
- *
- * @param Zend_Auth_Result $authResult
- * @return void
- */
- public function afterLogin(Zend_Auth_Result $authResult, $formValues)
- {
- // MUtil_Echo::track($authResult->isValid(), $formValues);
- if ($authResult->isValid()) {
- $login_name = $formValues['userlogin'];
- $organization = $formValues['organization'];
- $password = $formValues['password'];
- $this->makeNewStaffUser($login_name, $organization, $password);
- }
- }
-
- /**
* Return true if the password can be set.
*
* Returns the setting for the definition whan no user is passed, otherwise
@@ -93,13 +76,25 @@
/**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
+ * @param Gems_User_User $user
* @param string $password
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password)
+ public function getAuthAdapter(Gems_User_User $user, $password)
{
+ $pwd_hash = $this->hashPassword($password);
+
+ $sql = "SELECT gsf_id_user FROM gems__staff WHERE gsf_active = 1 AND gsf_login = ? AND gsf_id_organization = ? AND gsf_password = ?";
+
+ if ($this->db->fetchOne($sql, array($user->getLoginName(), $user->getBaseOrganizationId(), $pwd_hash))) {
+ $this->makeNewStaffUser($user, $password);
+
+ return true;
+ } else {
+ return false;
+ }
+
+ /*
$adapter = new Zend_Auth_Adapter_DbTable(null, 'gems__staff', 'gsf_login', 'gsf_password');
$pwd_hash = $this->hashPassword($password);
@@ -112,6 +107,7 @@
->setCredential($pwd_hash);
return $adapter;
+ // */
}
/**
@@ -200,15 +196,19 @@
return md5($password);
}
- protected function makeNewStaffUser($login_name, $organization, $password)
+ /**
+ * Sets the user up as a new staff user
+ *
+ * @param Gems_User_User $user
+ * @param string $password
+ */
+ protected function makeNewStaffUser(Gems_User_User $user, $password)
{
- $userData = $this->getUserData($login_name, $organization);
- $staff_id = $userData['user_id'];
+ $staff_id = $user->getUserId();
+ $sql = 'SELECT gul_id_user FROM gems__user_logins WHERE gul_can_login = 1 AND gul_login = ? AND gul_id_organization = ?';
- $sql = 'SELECT gul_id_user FROM gems__user_logins WHERE gul_can_login = 1 AND gul_login = ? AND gul_id_organization = ?';
-
try {
- $user_id = $this->db->fetchOne($sql, array($login_name, $organization));
+ $user_id = $this->db->fetchOne($sql, array($user->getLoginName(), $user->getBaseOrganizationId()));
$currentTimestamp = new Zend_Db_Expr('CURRENT_TIMESTAMP');
@@ -240,6 +240,8 @@
$this->db->update('gems__staff', $values, $this->db->quoteInto('gsf_id_user = ?', $staff_id));
+ $user->refresh(Gems_User_UserLoader::USER_STAFF);
+
} catch (Zend_Db_Exception $e) {
GemsEscort::getInstance()->logger->log($e->getMessage(), Zend_Log::ERR);
// Fall through as this does not work if the database upgrade did not run
@@ -257,7 +259,7 @@
*/
public function setPassword(Gems_User_User $user, $password)
{
- $this->makeNewStaffUser($user->getLoginName(), $user->getBaseOrganizationId(), $password);
+ $this->makeNewStaffUser($user, $password);
return $this;
}
Modified: trunk/library/classes/Gems/User/ProjectUserDefinition.php
===================================================================
--- trunk/library/classes/Gems/User/ProjectUserDefinition.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/ProjectUserDefinition.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -55,14 +55,13 @@
/**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
+ * @param Gems_User_User $user
* @param string $password
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password)
+ public function getAuthAdapter(Gems_User_User $user, $password)
{
- $adapter = new Gems_Auth_Adapter_Callback(array($this->project,'checkSuperAdminPassword'), $username, array($password));
+ $adapter = new Gems_Auth_Adapter_Callback(array($this->project, 'checkSuperAdminPassword'), $user->getLoginName(), array($password));
return $adapter;
}
@@ -76,14 +75,15 @@
public function getUserData($login_name, $organization)
{
return array(
- 'user_id' => 1,
- 'user_login' => $login_name,
- 'user_name' => $login_name,
- 'user_group' => 800,
- 'user_role' => 'master',
- 'user_style' => 'gems',
- 'user_base_org_id' => $organization,
+ 'user_id' => 1,
+ 'user_login' => $login_name,
+ 'user_name' => $login_name,
+ 'user_group' => 800,
+ 'user_role' => 'master',
+ 'user_style' => 'gems',
+ 'user_base_org_id' => $organization,
'user_allowed_ip_ranges' => $this->project->getSuperAdminIPRanges(),
+ 'user_blockable' => false,
);
}
}
\ No newline at end of file
Modified: trunk/library/classes/Gems/User/RadiusUserDefinition.php
===================================================================
--- trunk/library/classes/Gems/User/RadiusUserDefinition.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/RadiusUserDefinition.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -128,15 +128,14 @@
/**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
+ * @param Gems_User_User $user
* @param string $password
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password)
+ public function getAuthAdapter(Gems_User_User $user, $password)
{
//Ok hardcoded for now this needs to be read from the userdefinition
- $configData = $this->loadConfig(array('gor_id_organization' => $organizationId));
+ $configData = $this->loadConfig(array('gor_id_organization' => $user->getBaseOrganizationId()));
$config = array('ip' => $configData['grcfg_ip'],
'authenticationport' => $configData['grcfg_port'],
@@ -150,7 +149,7 @@
}
$adapter = new Gems_User_Adapter_Radius($config);
- $adapter->setIdentity($username)
+ $adapter->setIdentity($user->getLoginName())
->setCredential($password);
return $adapter;
Modified: trunk/library/classes/Gems/User/User.php
===================================================================
--- trunk/library/classes/Gems/User/User.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/User.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -87,7 +87,21 @@
protected $definition;
/**
+ * Sets number failed accounts that trigger a block
*
+ * @var int
+ */
+ protected $failureBlockCount = 6;
+
+ /**
+ * Sets number of seconds until a previous failed login can be ignored
+ *
+ * @var int
+ */
+ protected $failureIgnoreTime = 600;
+
+ /**
+ *
* @var Zend_Controller_Request_Abstract
*/
protected $request;
@@ -113,7 +127,16 @@
protected $userLoader;
/**
+ * Use Zend_Auth for authentication
*
+ * Warning: Zend_Auth contains only a partial ID of the current user, the base organization is missing
+ *
+ * @var boolean
+ */
+ protected $useZendAuth = false;
+
+ /**
+ *
* @var Gems_Util
*/
protected $util;
@@ -221,56 +244,205 @@
}
/**
- * Perform project specific after login logic here, can also delegate to the user definition
+ * Process everything after authentication.
*
- * @return void
+ * @param Zend_Auth_Result $result
*/
- public function afterLogin($formValues) {
- if (is_callable(array($this->definition, 'afterLogin'))) {
- // Use the USERS organization, not the one he or she is using currently
- $formValues['organization'] = $this->getBaseOrganizationId();
- $this->definition->afterLogin($this->_authResult, $formValues);
+ protected function afterAuthorization(Zend_Auth_Result $result)
+ {
+ try {
+ $select = $this->db->select();
+ $select->from('gems__user_login_attempts', array('gula_failed_logins', 'gula_last_failed', 'gula_block_until', 'UNIX_TIMESTAMP() - UNIX_TIMESTAMP(gula_last_failed) AS since_last'))
+ ->where('gula_login = ?', $this->getLoginName())
+ ->where('gula_id_organization = ?', $this->getCurrentOrganizationId())
+ ->limit(1);
+
+ $values = $this->db->fetchRow($select);
+
+ // The first login attempt
+ if (! $values) {
+ $values['gula_login'] = $this->getLoginName();
+ $values['gula_id_organization'] = $this->getCurrentOrganizationId();
+ $values['gula_failed_logins'] = 0;
+ $values['gula_last_failed'] = null;
+ $values['gula_block_until'] = null;
+ $values['since_last'] = $this->failureBlockCount + 1;
+ }
+
+ if ($result->isValid()) {
+ // Reset login failures
+ $values['gula_failed_logins'] = 0;
+ $values['gula_last_failed'] = null;
+ $values['gula_block_until'] = null;
+
+ } else {
+
+ // Reset the counters when the last login was longer ago than the delay factor
+ if ($values['since_last'] > $this->failureIgnoreTime) {
+ $values['gula_failed_logins'] = 1;
+ } else {
+ $values['gula_failed_logins'] += 1;
+ }
+
+ // If block is already set
+ if ($values['gula_block_until']) {
+ // Do not change it anymore
+ unset($values['gula_block_until']);
+
+ } else {
+ // Only set the block when needed
+ if ($this->failureBlockCount <= $values['gula_failed_logins']) {
+ $values['gula_block_until'] = new Zend_Db_Expr('DATE_ADD(CURRENT_TIMESTAMP, INTERVAL ' . $this->failureIgnoreTime . ' SECOND)');
+ }
+ }
+
+ // Always record the last fail
+ $values['gula_last_failed'] = new Zend_Db_Expr('CURRENT_TIMESTAMP');
+
+ // Response gets slowly slower
+ $sleepTime = min($values['gula_failed_logins'] - 1, 10) * 2;
+ sleep($sleepTime);
+ // MUtil_Echo::track($sleepTime, $values, $result->getMessages());
+ }
+
+ // Value not saveable
+ unset($values['since_last']);
+
+ if (isset($values['gula_login'])) {
+ $this->db->insert('gems__user_login_attempts', $values);
+ } else {
+ $where = $this->db->quoteInto('gula_login = ? AND ', $this->getLoginName());
+ $where .= $this->db->quoteInto('gula_id_organization = ?', $this->getCurrentOrganizationId());
+ $this->db->update('gems__user_login_attempts', $values, $where);
+ }
+
+ } catch (Zend_Db_Exception $e) {
+ // Fall through as this does not work if the database upgrade did not yet run
+ // MUtil_Echo::r($e);
}
+
}
/**
- * Helper method for the case a user tries to authenticate while he is inactive
+ * Authenticate a users credentials using the submitted form
*
- * @return boolean
+ * @param string $password The password to test
+ * @return Zend_Auth_Result
*/
- public function alwaysFalse()
+ public function authenticate($password)
{
- return false;
+ if ($this->useZendAuth) {
+ $zendAuth = Zend_Auth::getInstance();
+ }
+ $auths = $this->loadAuthorizers($password);
+
+ foreach ($auths as $result) {
+ if (is_callable($result)) {
+ $result = call_user_func($result);
+ }
+
+ if ($result instanceof Zend_Auth_Adapter_Interface) {
+ if ($this->useZendAuth) {
+ $result = $zendAuth->authenticate($result);
+ } else {
+ $result = $result->authenticate();
+ }
+ }
+
+ if ($result instanceof Zend_Auth_Result) {
+ if (! $result->isValid()) {
+ break;
+ }
+ } else {
+ if (true === $result) {
+ $result = new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $this->getLoginName());
+
+ } else {
+ // Always a fail when not true
+ if ($result === false) {
+ $code = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
+ $result = array();
+ } else {
+ $code = Zend_Auth_Result::FAILURE_UNCATEGORIZED;
+ if (is_string($result)) {
+ $result = array($result);
+ }
+ }
+ $result = new Zend_Auth_Result($code, $this->getLoginName(), $result);
+ break;
+ }
+ }
+ }
+
+ $this->afterAuthorization($result);
+
+ // MUtil_Echo::track($result);
+ $this->_authResult = $result;
+
+ return $result;
}
/**
- * Authenticate a users credentials using the submitted form
+ * Checks if the user is allowed to login or is blocked
*
- * @param array $formValues the array containing all formvalues from the login form
- * @return Zend_Auth_Result
+ * An adapter authorizes and if the end resultis boolean, string or array
+ * it is converted into a Zend_Auth_Result.
+ *
+ * @return mixed Zend_Auth_Adapter_Interface|Zend_Auth_Result|boolean|string|array
*/
- public function authenticate($formValues)
+ protected function authorizeBlock()
{
- // Check if the client IP address is within allowed IP ranges
- if (! $this->util->isAllowedIP($_SERVER['REMOTE_ADDR'], $this->getAllowedIPRanges())) {
- return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, $this->getLoginName(), array($this->translate->_('You are not allowed to login from this location.')));
- }
+ try {
+ $select = $this->db->select();
+ $select->from('gems__user_login_attempts', array('UNIX_TIMESTAMP(gula_block_until) - UNIX_TIMESTAMP() AS wait'))
+ ->where('gula_block_until is not null')
+ ->where('gula_login = ?', $this->getLoginName())
+ ->where('gula_id_organization = ?', $this->getCurrentOrganizationId())
+ ->limit(1);
- $auth = Gems_Auth::getInstance();
+ // Not the first login
+ if ($block = $this->db->fetchOne($select)) {
+ if ($block > 0) {
+ $minutes = intval($block / 60) + 1;
- $formValues['organization'] = $this->getBaseOrganizationId();
- $formValues['userlogin'] = $this->getLoginName();
+ // Report all is not well
+ return sprintf($this->translate->plural('Your account is temporarily blocked, please wait a minute.', 'Your account is temporarily blocked, please wait %d minutes.', $minutes), $minutes);
- if ($this->isActive()) {
- $adapter = $this->definition->getAuthAdapter($formValues['userlogin'], $formValues['organization'], $formValues['password']);
- } else {
- $adapter = new Gems_Auth_Adapter_Callback(array($this,'alwaysFalse'), $formValues['userlogin']);
+ } else {
+ // Clean the block once it's past
+ $values['gula_failed_logins'] = 0;
+ $values['gula_last_failed'] = null;
+ $values['gula_block_until'] = null;
+ $where = $this->db->quoteInto('gula_login = ? AND ', $this->getLoginName());
+ $where .= $this->db->quoteInto('gula_id_organization = ?', $this->getCurrentOrganizationId());
+
+ $this->db->update('gems__user_login_attempts', $values, $where);
+ }
+ }
+
+ } catch (Zend_Db_Exception $e) {
+ // Fall through as this does not work if the database upgrade did not run
+ // MUtil_Echo::r($e);
}
- $authResult = $auth->authenticate($adapter, $formValues);
- $this->_authResult = $authResult;
+ return true;
+ }
- return $authResult;
+ /**
+ * Checks if the user is allowed to login using the current IP address
+ *
+ * An adapter authorizes and if the end resultis boolean, string or array
+ * it is converted into a Zend_Auth_Result.
+ *
+ * @return mixed Zend_Auth_Adapter_Interface|Zend_Auth_Result|boolean|string|array
+ */
+ protected function authorizeIp()
+ {
+ if ($this->util->isAllowedIP($_SERVER['REMOTE_ADDR'], $this->getAllowedIPRanges())) {
+ return true;
+ } else {
+ return $this->translate->_('You are not allowed to login from this location.');
+ }
}
/**
@@ -439,20 +611,6 @@
}
/**
- * Get the array to use for authenticate()
- *
- * @param string $password
- * @return array
- */
- public function getFormValuesForPassword($password)
- {
- return array(
- 'userlogin' => $this->getLoginName(),
- 'password' => $password,
- 'organization' => $this->getCurrentOrganizationId());
- }
-
- /**
* Returns the full user name (first, prefix, last).
*
* @return string
@@ -704,6 +862,20 @@
}
/**
+ * True when this user must enter a new password.
+ *
+ * @return boolean
+ */
+ public function isBlockable()
+ {
+ if ($this->_hasVar('user_blockable')) {
+ return (boolean) $this->_getVar('user_blockable');
+ } else {
+ return true;
+ }
+ }
+
+ /**
* Checks if this user is the current user
*
* @return boolean
@@ -744,6 +916,53 @@
}
/**
+ * Load the callables | results needed to authenticate/authorize this user
+ *
+ * A callable will be called, then an adapter authorizes and if the end result
+ * is boolean, string or array it is converted into a Zend_Auth_Result.
+ *
+ * @param string $password
+ * @return array Of Callable|Zend_Auth_Adapter_Interface|Zend_Auth_Result|boolean|string|array
+ */
+ protected function loadAuthorizers($password)
+ {
+ $auths['ip'] = array($this, 'authorizeIp');
+
+ if ($this->isBlockable()) {
+ $auths['block'] = array($this, 'authorizeBlock');
+ }
+
+ if ($this->isActive()) {
+ $auths['pwd'] = $this->definition->getAuthAdapter($this, $password);
+ } else {
+ $auths['pwd'] = false;
+ }
+
+ return $auths;
+ }
+
+ /**
+ *
+ * @param string $defName Optional
+ * @return Gems_User_User (continuation pattern)
+ */
+ public function refresh($defName = null)
+ {
+ if ($defName) {
+ $this->definition = $this->userLoader->getUserDefinition($defName);
+ }
+
+ $newData = $this->definition->getUserData($this->getLoginName(), $this->getBaseOrganizationId());
+ $newData = $this->userLoader->ensureDefaultUserValues($newData, $this->definition, $defName);
+
+ foreach ($newData as $key => $value) {
+ $this->_setVar($key, $value);
+ }
+
+ return $this;
+ }
+
+ /**
* Allowes a refresh of the existing list of organizations
* for this user.
*
Modified: trunk/library/classes/Gems/User/UserDefinitionInterface.php
===================================================================
--- trunk/library/classes/Gems/User/UserDefinitionInterface.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/UserDefinitionInterface.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -80,12 +80,10 @@
/**
* Returns an initialized Zend_Auth_Adapter_Interface
*
- * @param string $username
- * @param int $organizationId
- * @param string $password
+ * @param Gems_User_User $user
* @return Zend_Auth_Adapter_Interface
*/
- public function getAuthAdapter($username, $organizationId, $password);
+ public function getAuthAdapter(Gems_User_User $user, $password);
/**
* Return a password reset key
Modified: trunk/library/classes/Gems/User/UserLoader.php
===================================================================
--- trunk/library/classes/Gems/User/UserLoader.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/UserLoader.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -171,6 +171,30 @@
}
/**
+ * Makes sure default values are set for a user
+ *
+ * @param array $values
+ * @param Gems_User_UserDefinitionInterface $definition
+ * @param string $defName Optional
+ * @return array
+ */
+ public function ensureDefaultUserValues(array $values, Gems_User_UserDefinitionInterface $definition, $defName = null)
+ {
+ if (! isset($values['user_active'])) {
+ $values['user_active'] = true;
+ }
+ if (! isset($values['user_staff'])) {
+ $values['user_staff'] = $definition->isStaff();
+ }
+
+ if ($defName) {
+ $values['__user_definition'] = $defName;
+ }
+
+ return $values;
+ }
+
+ /**
* Get userclass / description array of available UserDefinitions for respondents
*
* @return array
@@ -464,15 +488,8 @@
$values = $definition->getUserData($userName, $userOrganization);
// MUtil_Echo::track($defName, $login_name, $userOrganization, $values);
- if (! isset($values['user_active'])) {
- $values['user_active'] = true;
- }
- if (! isset($values['user_staff'])) {
- $values['user_staff'] = $definition->isStaff();
- }
+ $values = $this->ensureDefaultUserValues($values, $definition, $defName);
- $values['__user_definition'] = $defName;
-
return $this->_loadClass('User', true, array($values, $definition));
}
Deleted: trunk/library/classes/Gems/User/UserNewPasswordValidator.php
===================================================================
--- trunk/library/classes/Gems/User/UserNewPasswordValidator.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/UserNewPasswordValidator.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -1,117 +0,0 @@
-<?php
-
-/**
- * Copyright (c) 2011, Erasmus MC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Erasmus MC nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * @package Gems
- * @subpackage User
- * @author Matijs de Jong <mj...@ma...>
- * @copyright Copyright (c) 2011 Erasmus MC
- * @license New BSD License
- * @version $Id$
- */
-
-/**
- *
- *
- * @package Gems
- * @subpackage User
- * @copyright Copyright (c) 2011 Erasmus MC
- * @license New BSD License
- * @since Class available since version 1.5
- */
-class Gems_User_UserNewPasswordValidator implements Zend_Validate_Interface
-{
- /**
- * The reported problems with the password.
- *
- * @var array or null
- */
- private $_report;
-
- /**
- *
- * @var Gems_User_User
- */
- private $_user;
-
- /**
- *
- * @param Gems_User_User $user The user to check
- */
- public function __construct(Gems_User_User $user)
- {
- $this->_user = $user;
- }
-
- /**
- * Returns true if and only if $value meets the validation requirements
- *
- * If $value fails validation, then this method returns false, and
- * getMessages() will return an array of messages that explain why the
- * validation failed.
- *
- * @param mixed $value
- * @param mixed $content
- * @return boolean
- * @throws Zend_Validate_Exception If validation of $value is impossible
- */
- public function isValid($value, $context = array())
- {
- $this->_report = $this->_user->reportPasswordWeakness($value);
-
- foreach ($this->_report as &$report) {
- $report = ucfirst($report) . '.';
- }
-
- // MUtil_Echo::track($value, $this->_report);
-
- return ! (boolean) $this->_report;
- }
-
- /**
- * Returns an array of messages that explain why the most recent isValid()
- * call returned false. The array keys are validation failure message identifiers,
- * and the array values are the corresponding human-readable message strings.
- *
- * If isValid() was never called or if the most recent isValid() call
- * returned true, then this method returns an empty array.
- *
- * @return array
- */
- public function getMessages()
- {
- if ($this->_report) {
- return $this->_report;
-
- } else {
- return array();
- }
-
-
- }
-}
Deleted: trunk/library/classes/Gems/User/UserPasswordValidator.php
===================================================================
--- trunk/library/classes/Gems/User/UserPasswordValidator.php 2012-03-22 17:05:18 UTC (rev 563)
+++ trunk/library/classes/Gems/User/UserPasswordValidator.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -1,120 +0,0 @@
-<?php
-
-/**
- * Copyright (c) 2011, Erasmus MC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Erasmus MC nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * @package Gems
- * @subpackage User
- * @author Matijs de Jong <mj...@ma...>
- * @copyright Copyright (c) 2011 Erasmus MC
- * @license New BSD License
- * @version $Id$
- */
-
-/**
- *
- *
- * @package Gems
- * @subpackage User
- * @copyright Copyright (c) 2011 Erasmus MC
- * @license New BSD License
- * @since Class available since version 1.5
- */
-class Gems_User_UserPasswordValidator implements Zend_Validate_Interface
-{
- /**
- *
- * @var Gems_User_User
- */
- private $_user;
-
- /**
- *
- * @var Zend_Translate
- */
- private $_translate;
-
- /**
- *
- * @var boolean
- */
- private $_valid = false;
-
- /**
- *
- * @param Gems_User_User $user The user to check
- * @param Zend_Translate $translate Optional translator
- */
- public function __construct(Gems_User_User $user, Zend_Translate $translate = null)
- {
- $this->_user = $user;
- $this->_translate = $translate ? $translate : new MUtil_Translate_Adapter_Potemkin();
- }
-
- /**
- * Returns true if and only if $value meets the validation requirements
- *
- * If $value fails validation, then this method returns false, and
- * getMessages() will return an array of messages that explain why the
- * validation failed.
- *
- * @param mixed $value
- * @param mixed $content
- * @return boolean
- * @throws Zend_Validate_Exception If validation of $value is impossible
- */
- public function isValid($value, $context = array())
- {
- $authResult = $this->_user->authenticate($this->_user->getFormValuesForPassword($value));
-
- $this->_valid = $authResult->isValid();
-
- return $this->_valid;
- }
-
- /**
- * Returns an array of messages that explain why the most recent isValid()
- * call returned false. The array keys are validation failure message identifiers,
- * and the array values are the corresponding human-readable message strings.
- *
- * If isValid() was never called or if the most recent isValid() call
- * returned true, then this method returns an empty array.
- *
- * @return array
- */
- public function getMessages()
- {
- if ($this->_valid) {
- return array();
-
- } else {
- return array($this->_translate->_('Wrong password.'));
- }
-
-
- }
-}
Property changes on: trunk/library/classes/Gems/User/Validate
___________________________________________________________________
Added: bugtraq:url
+ http://survey.erasmusmc.nl/support/mantis/view.php?id=%BUGID%
Added: bugtraq:logregex
+ #(\d+)
Added: trunk/library/classes/Gems/User/Validate/GetUserInterface.php
===================================================================
--- trunk/library/classes/Gems/User/Validate/GetUserInterface.php (rev 0)
+++ trunk/library/classes/Gems/User/Validate/GetUserInterface.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Copyright (c) 2012, Erasmus MC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Erasmus MC nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @package Gems
+ * @subpackage User
+ * @author Matijs de Jong <mj...@ma...>
+ * @copyright Copyright (c) 2012 Erasmus MC
+ * @license New BSD License
+ * @version $id: GetUserInterface.php 203 2012-01-01 12:51:32Z matijs $
+ */
+
+/**
+ *
+ *
+ * @package Gems
+ * @subpackage User
+ * @copyright Copyright (c) 2012 Erasmus MC
+ * @license New BSD License
+ * @since Class available since version 1.5.3
+ */
+interface Gems_User_Validate_GetUserInterface
+{
+ /**
+ * Returns a user
+ *
+ * @return Gems_User_User
+ */
+ public function getUser();
+}
Added: trunk/library/classes/Gems/User/Validate/GetUserPasswordValidator.php
===================================================================
--- trunk/library/classes/Gems/User/Validate/GetUserPasswordValidator.php (rev 0)
+++ trunk/library/classes/Gems/User/Validate/GetUserPasswordValidator.php 2012-03-23 18:23:04 UTC (rev 564)
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * Copyright (c) 2011, Erasmus MC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Erasmus MC nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @package Gems
+ * @subpackage User
+ * @author Matijs de Jong <mj...@ma...>
+ * @copyright Copyright (c) 2011 Erasmus MC
+ * @license New BSD License
+ * @version $Id: UserPasswordValidator.php 370 2011-12-19 09:27:19Z mennodekker $
+ */
+
+/**
+ *
+ *
+ * @package Gems
+ * @subpackage User
+ * @copyright Copyright (c) 2011 Erasmus MC
+ * @license New BSD License
+ * @since Class available since version 1.5
+ */
+class Gems_User_Validate_GetUserPasswordValidator extends Gems_User_Validate_PasswordValidatorAbstract
+{
+ /**
+ *
+ * @var Gems_User_Validate_GetUserInterface
+ */
+ private $_userSource;
+
+ /**
+ *
+ * @param Gems_User_Validate_GetUserInterface $userSource The source for the user
+ * @param string $message Default message for standard login fail.
+ */
+ public function __construct(Gems_User_Validate_GetUserInterface $userSource, $message)
+ {
+ $this->_userSource = $userSource;
+
+ parent::__construct($message);
+ }
+
+ /**
+ * Returns true if and only if $value meets the validation requirements
+ *
+ * If $value fails validation, then this method returns false, and
+ * getMessages() will return an array of messages that explain why the
+ * validation failed.
+ *
+ * @param mixed $value
+ * @param mixed $content
+ * @return boolean
+ * @throws Zend_Validate_Exception If validation of $value is impossible
+ */
+ public function isValid($value, $context = array())
+ {
+ $user = $this->_userSource->getUser();
+ if ($user instanceof Gems_User_User) {
+ $result = $user->authenticate($value);
+ } else {
+ $result = new Zend_Auth_Result(Zend_Auth_Result::FAILURE_UNCATEGORIZED, null);
+ }
+
+ return $this->setAuthResult($result);
+ }
+}
Added: trunk/library/classes/Gems/User/Validate/NewPassword...
[truncated message content] |