From aa3357fe785ef65afbf57ac20efdbd72adb558ac Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Fri, 2 Jul 2010 11:23:59 +0000 Subject: [PATCH] Fixed bug #102: allow users to change their password. SVN:trunk[532] --- .../userrights/userrightsmatrix.class.inc.php | 24 ++++++++ .../userrights/userrightsnull.class.inc.php | 10 ++++ .../userrightsprofile.class.inc.php | 35 ++++++++++++ application/itopwebpage.class.inc.php | 7 ++- application/loginwebpage.class.inc.php | 56 ++++++++++++++++++- core/userrights.class.inc.php | 26 +++++++++ dictionaries/dictionary.itop.ui.php | 8 +++ dictionaries/fr.dictionary.itop.ui.php | 8 +++ 8 files changed, 170 insertions(+), 4 deletions(-) diff --git a/addons/userrights/userrightsmatrix.class.inc.php b/addons/userrights/userrightsmatrix.class.inc.php index 632905031..a85d4bf18 100644 --- a/addons/userrights/userrightsmatrix.class.inc.php +++ b/addons/userrights/userrightsmatrix.class.inc.php @@ -304,6 +304,30 @@ class UserRightsMatrix extends UserRightsAddOnAPI // todo: throw an exception? return false; } + + public function CanChangePassword() + { + return true; + } + + public function ChangePassword($iUserId, $sOldPassword, $sNewPassword) + { + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE userid = $iUserId")); + if ($oSet->Count() < 1) + { + return false; + } + + $oLogin = $oSet->Fetch(); + if ($oLogin->Get('password') == $sOldPassword) + { + $oLogin->Set('password', $sNewPassword); + $oLogin->DBUpdate(); + return true; + } + return false; + } + public function GetUserId($sUserName) { diff --git a/addons/userrights/userrightsnull.class.inc.php b/addons/userrights/userrightsnull.class.inc.php index 82d6a00d8..e4b034b90 100644 --- a/addons/userrights/userrightsnull.class.inc.php +++ b/addons/userrights/userrightsnull.class.inc.php @@ -51,6 +51,16 @@ class UserRightsNull extends UserRightsAddOnAPI { return 1; } + + public function CanChangePassword() + { + return true; + } + + public function ChangePassword($iUserId, $sOldPassword, $sNewPassword) + { + return true; + } public function GetUserId($sUserName) { diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php index ffa532cdb..929c92778 100644 --- a/addons/userrights/userrightsprofile.class.inc.php +++ b/addons/userrights/userrightsprofile.class.inc.php @@ -883,6 +883,41 @@ exit; return false; } + public function CanChangePassword() + { + // For now everyone can change their password.. + return true; + } + + public function ChangePassword($iUserId, $sOldPassword, $sNewPassword) + { + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users WHERE id = :user_id"), array(), array('user_id' => $iUserId)); + if ($oSet->Count() < 1) + { + return false; + } + + $oLogin = $oSet->Fetch(); + if ($oLogin->Get('password') == $sOldPassword) + { + $oLogin->Set('password', $sNewPassword); + $oChange = MetaModel::NewObject("CMDBChange"); + $oChange->Set("date", time()); + if (UserRights::GetUser() != UserRights::GetRealUser()) + { + $sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUser(), UserRights::GetUser()); + } + else + { + $sUserString = UserRights::GetUser(); + } + $oChange->Set("userinfo", $sUserString); + $oLogin->DBUpdateTracked($oChange); + return true; + } + return false; + } + public function GetUserId($sUserName) { if (array_key_exists($sUserName, $this->m_aLogin2UserId)) diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index dc2e5e623..b05b40bed 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -455,8 +455,11 @@ EOF } $sLogOffMenu = "\n"; //$sLogOffMenu = ""; diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index b22190477..f2da48f3e 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -40,7 +40,7 @@ body { } #login-logo { margin-top: 150px; - width: 250px; + width: 300px; padding-left: 20px; padding-right: 20px; padding-top: 10px; @@ -59,7 +59,7 @@ body { border: 0; } #login { - width: 250px; + width: 300px; margin-left: auto; margin-right: auto; padding: 20px; @@ -112,6 +112,31 @@ EOF $this->add("\n"); } + public function DisplayChangePwdForm($bFailedLogin = false) + { + $sAuthUser = utils::ReadParam('auth_user', ''); + $sAuthPwd = utils::ReadParam('suggest_pwd', ''); + + $sVersionShort = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION); + $this->add("
\n"); + $this->add("
\n"); + $this->add("

".Dict::S('UI:Login:ChangeYourPassword')."

\n"); + if ($bFailedLogin) + { + $this->add("

".Dict::S('UI:Login:IncorrectOldPassword')."

\n"); + } + $this->add("
\n"); + $this->add("\n"); + $this->add("\n"); + $this->add("\n"); + $this->add("\n"); + $this->add("\n"); + $this->add("
  
\n"); + $this->add("\n"); + $this->add("
\n"); + $this->add("
\n"); + } + static protected function ResetSession() { // Unset all of the session variables. @@ -193,6 +218,33 @@ EOF self::ResetSession(); } + if ($operation == 'change_pwd') + { + $oPage = new LoginWebPage(); + $oPage->DisplayChangePwdForm(); + $oPage->output(); + exit; + } + if ($operation == 'do_change_pwd') + { + $sAuthUser = $_SESSION['auth_user']; + $sOldPwd = utils::ReadPostedParam('old_pwd'); + $sNewPwd = utils::ReadPostedParam('new_pwd'); + if (UserRights::CanChangePassword() && ((!UserRights::Login($sAuthUser, $sOldPwd)) || (!UserRights::ChangePassword($sOldPwd, $sNewPwd)))) + { + $oPage = new LoginWebPage(); + $oPage->DisplayChangePwdForm(true); // old pwd was wrong + $oPage->output(); + exit; + } + else + { + // Remember the changed password + $_SESSION['auth_pwd'] = $sNewPwd; + return; + } + } + if (!isset($_SESSION['auth_user']) || !isset($_SESSION['auth_pwd'])) { if ($operation == 'loginurl') diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index d19a338fe..7519e5dcd 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -55,6 +55,8 @@ abstract class UserRightsAddOnAPI abstract public function Init(); // loads data (possible optimizations) abstract public function CheckCredentials($sLogin, $sPassword); // returns the id of the user or false + abstract public function CanChangePassword(); // Whether or not a user can change her/his own password + abstract public function ChangePassword($iUserId, $sOldPassword, $sNewPassword); // Change the password of the specified user abstract public function GetUserLanguage($sLogin); // returns the language code (e.g "EN US") abstract public function GetUserId($sLogin); // returns the id of the user or false abstract public function GetContactId($sLogin); // returns the id of the "business" user or false @@ -144,6 +146,30 @@ class UserRights } } + public static function CanChangePassword() + { + if (!is_null(self::$m_iUserId)) + { + return self::$m_oAddOn->CanChangePassword(self::$m_iUserId); + } + else + { + return false; + } + } + + public static function ChangePassword($sCurrentPassword, $sNewPassword) + { + if (!is_null(self::$m_iUserId)) + { + return self::$m_oAddOn->ChangePassword(self::$m_iUserId, $sCurrentPassword, $sNewPassword); + } + else + { + return false; + } + } + public static function Impersonate($sName, $sPassword) { if (!self::CheckLogin()) return false; diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php index ddbca82f1..3c66730b8 100644 --- a/dictionaries/dictionary.itop.ui.php +++ b/dictionaries/dictionary.itop.ui.php @@ -358,6 +358,7 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Button:FilterList' => ' Filter... ', 'UI:Button:Create' => ' Create ', 'UI:Button:Delete' => ' Delete ! ', + 'UI:Button:ChangePassword' => ' Change Password ', 'UI:SearchToggle' => 'Search', 'UI:ClickToCreateNew' => 'Click here to create a new %1$s', @@ -437,6 +438,13 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:Login:IdentifyYourself' => 'Identify yourself before continuing', 'UI:Login:UserNamePrompt' => 'User Name', 'UI:Login:PasswordPrompt' => 'Password', + 'UI:Login:ChangeYourPassword' => 'Change Your Password', + 'UI:Login:OldPasswordPrompt' => 'Old password', + 'UI:Login:NewPasswordPrompt' => 'New password', + 'UI:Login:RetypeNewPasswordPrompt' => 'Retype new password', + 'UI:Login:IncorrectOldPassword' => 'Error: the old password is incorrect', + 'UI:LogoffMenu' => 'Log off', + 'UI:ChangePwdMenu' => 'Change Password...', 'UI:Button:Login' => 'Enter iTop', 'UI:Login:Error:AccessRestricted' => 'iTop access is restricted. Please, contact an iTop administrator.', 'UI:CSVImport:MappingSelectOne' => '-- select one --', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 8dd286db8..1a9ff348d 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -351,6 +351,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Button:FilterList' => ' Filtrer... ', 'UI:Button:Create' => ' Créer ', 'UI:Button:Delete' => ' Supprimer ! ', + 'UI:Button:ChangePassword' => ' Changer ! ', 'UI:SearchToggle' => 'Recherche', @@ -429,6 +430,13 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:Login:IdentifyYourself' => 'Merci de vous identifier', 'UI:Login:UserNamePrompt' => 'Identifiant', 'UI:Login:PasswordPrompt' => 'Mot de passe', + 'UI:Login:ChangeYourPassword' => 'Changer de mot de passe', + 'UI:Login:OldPasswordPrompt' => 'Ancien mot de passe', + 'UI:Login:NewPasswordPrompt' => 'Nouveau mot de passe', + 'UI:Login:RetypeNewPasswordPrompt' => 'Resaisir le nouveau mot de passe', + 'UI:Login:IncorrectOldPassword' => 'Erreur: l\'ancien mot de passe est incorrect', + 'UI:LogoffMenu' => 'Déconnexion', + 'UI:ChangePwdMenu' => 'Changer de mot de passe...', 'UI:Button:Login' => 'Entrer dans iTop', 'UI:Login:Error:AccessRestricted' => 'L\'accès à iTop est soumis à autorisation. Merci de contacter votre administrateur iTop.', 'UI:CSVImport:MappingSelectOne' => '-- choisir une valeur --',