Prechádzať zdrojové kódy

Fixed bug #102: allow users to change their password.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@532 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 15 rokov pred
rodič
commit
a01f538f08

+ 24 - 0
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)
 	{

+ 10 - 0
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)
 	{

+ 35 - 0
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))

+ 5 - 2
application/itopwebpage.class.inc.php

@@ -455,8 +455,11 @@ EOF
 		}
 		$sLogOffMenu = "<span id=\"logOffBtn\"><ul><li><img src=\"../images/onOffBtn.png\"><ul>";
 		$sLogOffMenu .= "<li><span>$sLogonMessage</span></li>\n";
-		$sLogOffMenu .= "<li><a href=\"#\">Log Off</a></li>\n";
-		$sLogOffMenu .= "<li><a href=\"#\">Change password...</a></li>\n";
+		$sLogOffMenu .= "<li><a href=\"../pages/UI.php?loginop=logoff\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
+		if (UserRights::CanChangePassword())
+		{
+			$sLogOffMenu .= "<li><a href=\"../pages/UI.php?loginop=change_pwd\">".Dict::S('UI:ChangePwdMenu')."</a></li>\n";
+		}
 		$sLogOffMenu .= "</ul>\n</li>\n</ul></span>\n";
 
 		//$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>";

+ 54 - 2
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("</div>\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("<div id=\"login-logo\"><a href=\"http://www.combodo.com/itop\"><img title=\"$sVersionShort\" src=\"../images/itop-logo.png\"></a></div>\n");
+		$this->add("<div id=\"login\">\n");
+		$this->add("<h1>".Dict::S('UI:Login:ChangeYourPassword')."</h1>\n");
+		if ($bFailedLogin)
+		{
+			$this->add("<p class=\"hilite\">".Dict::S('UI:Login:IncorrectOldPassword')."</p>\n");
+		}
+		$this->add("<form method=\"post\">\n");
+		$this->add("<table>\n");
+		$this->add("<tr><td><label for=\"old_pwd\">".Dict::S('UI:Login:OldPasswordPrompt').":</label></td><td><input type=\"password\" id=\"old_pwd\" name=\"old_pwd\" value=\"\" /></td></tr>\n");
+		$this->add("<tr><td><label for=\"new_pwd\">".Dict::S('UI:Login:NewPasswordPrompt').":</label></td><td><input type=\"password\" id=\"new_pwd\" name=\"new_pwd\" value=\"\" /></td></tr>\n");
+		$this->add("<tr><td><label for=\"retype_new_pwd\">".Dict::S('UI:Login:RetypeNewPasswordPrompt').":</label></td><td><input type=\"password\" id=\"retype_new_pwd\" name=\"retype_new_pwd\" value=\"\" /></td></tr>\n");
+		$this->add("<tr><td colspan=\"2\" class=\"center v-spacer\">  <input type=\"button\" onClick=\"GoBack();\" value=\"".Dict::S('UI:Button:Cancel')."\" />&nbsp;&nbsp;<input type=\"submit\" value=\"".Dict::S('UI:Button:ChangePassword')."\" /></td></tr>\n");
+		$this->add("</table>\n");
+		$this->add("<input type=\"hidden\" name=\"loginop\" value=\"do_change_pwd\" />\n");
+		$this->add("</form>\n");
+		$this->add("</div>\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')

+ 26 - 0
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;

+ 8 - 0
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 --',

+ 8 - 0
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 --',