From 42eb30488fd8b8478974cdac8574f1d44bfb6ae9 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 11 Sep 2012 17:05:42 -0500 Subject: [PATCH] IDEMPIERE-375 Implement Forgot my Password --- .../oracle/907_IDEMPIERE-375.sql | 12 +---- .../oracle/909_IDEMPIERE-375.sql | 8 +++ .../postgresql/907_IDEMPIERE-375.sql | 12 +---- .../postgresql/909_IDEMPIERE-375.sql | 8 +++ .../src/org/compiere/model/MPasswordRule.java | 43 +++++++++++++++- .../src/org/compiere/model/MSysConfig.java | 3 +- .../src/org/compiere/model/MUser.java | 7 --- .../src/org/compiere/util/Login.java | 23 --------- .../webui/panel/ChangePasswordPanel.java | 21 ++++---- .../org/adempiere/webui/panel/LoginPanel.java | 28 ++++++----- .../webui/panel/ResetPasswordPanel.java | 49 ++++++++----------- 11 files changed, 107 insertions(+), 107 deletions(-) create mode 100644 migration/360lts-release/oracle/909_IDEMPIERE-375.sql create mode 100644 migration/360lts-release/postgresql/909_IDEMPIERE-375.sql diff --git a/migration/360lts-release/oracle/907_IDEMPIERE-375.sql b/migration/360lts-release/oracle/907_IDEMPIERE-375.sql index de9cdfe0ec..a497c77aa7 100644 --- a/migration/360lts-release/oracle/907_IDEMPIERE-375.sql +++ b/migration/360lts-release/oracle/907_IDEMPIERE-375.sql @@ -103,16 +103,6 @@ INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,V INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200045 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) ; --- Sep 10, 2012 5:20:40 PM SGT --- IDEMPIERE-375 Implement Forgot my Password -INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Answer',200046,'D','494db2ce-7749-4f52-82a1-d7e9448ab864','Answer','Y',TO_DATE('2012-09-10 17:20:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-09-10 17:20:40','YYYY-MM-DD HH24:MI:SS')) -; - --- Sep 10, 2012 5:20:46 PM SGT --- IDEMPIERE-375 Implement Forgot my Password -INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Answer',200047,'D','397a2656-2199-4451-87fe-5850b54957c0','Answer','Y',TO_DATE('2012-09-10 17:20:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-09-10 17:20:45','YYYY-MM-DD HH24:MI:SS')) -; - -- Sep 10, 2012 5:21:23 PM SGT -- IDEMPIERE-375 Implement Forgot my Password INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Security Question is Mandatory',200048,'D','5c73ed0f-6ca9-45bc-8df7-e85f8bc3471d','SecurityQuestionMandatory','Y',TO_DATE('2012-09-10 17:21:22','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-09-10 17:21:22','YYYY-MM-DD HH24:MI:SS')) @@ -351,4 +341,4 @@ UPDATE AD_Message_Trl SET IsTranslated='N' WHERE AD_Message_ID=200059 ; SELECT register_migration_script('907_IDEMPIERE-375.sql') FROM dual -; \ No newline at end of file +; diff --git a/migration/360lts-release/oracle/909_IDEMPIERE-375.sql b/migration/360lts-release/oracle/909_IDEMPIERE-375.sql new file mode 100644 index 0000000000..5bb2bb5e1c --- /dev/null +++ b/migration/360lts-release/oracle/909_IDEMPIERE-375.sql @@ -0,0 +1,8 @@ +-- Sep 11, 2012 5:02:55 PM COT +-- IDEMPIERE-375 Implement Forgot my Password +INSERT INTO AD_SysConfig (AD_SysConfig_ID,EntityType,ConfigurationLevel,Value,Description,AD_SysConfig_UU,Created,Updated,AD_Client_ID,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name) VALUES (200019,'D','S','Y','Show reset password button on login panel','9b0ac996-a542-44e5-9777-a284402a9788',TO_DATE('2012-09-11 17:02:54','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2012-09-11 17:02:54','YYYY-MM-DD HH24:MI:SS'),0,0,100,'Y',100,'LOGIN_SHOW_RESETPASSWORD') +; + +SELECT register_migration_script('909_IDEMPIERE-375.sql') FROM dual +; + diff --git a/migration/360lts-release/postgresql/907_IDEMPIERE-375.sql b/migration/360lts-release/postgresql/907_IDEMPIERE-375.sql index 4d03e8d0d9..4ff25dd6fa 100644 --- a/migration/360lts-release/postgresql/907_IDEMPIERE-375.sql +++ b/migration/360lts-release/postgresql/907_IDEMPIERE-375.sql @@ -103,16 +103,6 @@ INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,V INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200045 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID) ; --- Sep 10, 2012 5:20:40 PM SGT --- IDEMPIERE-375 Implement Forgot my Password -INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Answer',200046,'D','494db2ce-7749-4f52-82a1-d7e9448ab864','Answer','Y',TO_TIMESTAMP('2012-09-10 17:20:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-09-10 17:20:40','YYYY-MM-DD HH24:MI:SS')) -; - --- Sep 10, 2012 5:20:46 PM SGT --- IDEMPIERE-375 Implement Forgot my Password -INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Answer',200047,'D','397a2656-2199-4451-87fe-5850b54957c0','Answer','Y',TO_TIMESTAMP('2012-09-10 17:20:45','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-09-10 17:20:45','YYYY-MM-DD HH24:MI:SS')) -; - -- Sep 10, 2012 5:21:23 PM SGT -- IDEMPIERE-375 Implement Forgot my Password INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('E','Security Question is Mandatory',200048,'D','5c73ed0f-6ca9-45bc-8df7-e85f8bc3471d','SecurityQuestionMandatory','Y',TO_TIMESTAMP('2012-09-10 17:21:22','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-09-10 17:21:22','YYYY-MM-DD HH24:MI:SS')) @@ -351,4 +341,4 @@ UPDATE AD_Message_Trl SET IsTranslated='N' WHERE AD_Message_ID=200059 ; SELECT register_migration_script('907_IDEMPIERE-375.sql') FROM dual -; \ No newline at end of file +; diff --git a/migration/360lts-release/postgresql/909_IDEMPIERE-375.sql b/migration/360lts-release/postgresql/909_IDEMPIERE-375.sql new file mode 100644 index 0000000000..09166b6146 --- /dev/null +++ b/migration/360lts-release/postgresql/909_IDEMPIERE-375.sql @@ -0,0 +1,8 @@ +-- Sep 11, 2012 5:02:55 PM COT +-- IDEMPIERE-375 Implement Forgot my Password +INSERT INTO AD_SysConfig (AD_SysConfig_ID,EntityType,ConfigurationLevel,Value,Description,AD_SysConfig_UU,Created,Updated,AD_Client_ID,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name) VALUES (200019,'D','S','Y','Show reset password button on login panel','9b0ac996-a542-44e5-9777-a284402a9788',TO_TIMESTAMP('2012-09-11 17:02:54','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2012-09-11 17:02:54','YYYY-MM-DD HH24:MI:SS'),0,0,100,'Y',100,'LOGIN_SHOW_RESETPASSWORD') +; + +SELECT register_migration_script('909_IDEMPIERE-375.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/model/MPasswordRule.java b/org.adempiere.base/src/org/compiere/model/MPasswordRule.java index d97db19560..7ec9f9d8a0 100644 --- a/org.adempiere.base/src/org/compiere/model/MPasswordRule.java +++ b/org.adempiere.base/src/org/compiere/model/MPasswordRule.java @@ -46,6 +46,7 @@ import edu.vt.middleware.password.NonAlphanumericCharacterRule; import edu.vt.middleware.password.NumericalSequenceRule; import edu.vt.middleware.password.Password; import edu.vt.middleware.password.PasswordData; +import edu.vt.middleware.password.PasswordGenerator; import edu.vt.middleware.password.PasswordValidator; import edu.vt.middleware.password.QwertySequenceRule; import edu.vt.middleware.password.RepeatCharacterRegexRule; @@ -63,7 +64,7 @@ public class MPasswordRule extends X_AD_PasswordRule { /** * */ - private static final long serialVersionUID = -4262842010340413022L; + private static final long serialVersionUID = 7376091524332484101L; /** * @param ctx @@ -225,4 +226,44 @@ public class MPasswordRule extends X_AD_PasswordRule { return new MessageResolver(props); } + public String generate() { + CharacterCharacteristicsRule charRule = new CharacterCharacteristicsRule(); + int numValidations = 0; + if (getDigitCharacter() > 0) { + // require at least n digit in passwords + numValidations++; + charRule.getRules().add(new DigitCharacterRule(getDigitCharacter())); + } + if (getNonAlphaNumericCharacter() > 0) { + // require at least n non-alphanumeric char + numValidations++; + charRule.getRules().add(new NonAlphanumericCharacterRule(getNonAlphaNumericCharacter())); + } + if (getUppercaseCharacter() > 0) { + numValidations++; + charRule.getRules().add(new UppercaseCharacterRule(getUppercaseCharacter())); + } + if (getLowercaseCharacter() > 0) { + numValidations++; + charRule.getRules().add(new LowercaseCharacterRule(getLowercaseCharacter())); + } + if (getAlphabeticalCharacter() > 0){ + numValidations++; + charRule.getRules().add(new AlphabeticalCharacterRule(getAlphabeticalCharacter())); + } + if (! charRule.getRules().isEmpty()) { + charRule.setNumberOfCharacteristics(numValidations); + } + + int len = 10; // suggested length to generate + if (len < getMinLength()) { + len = getMinLength(); + } + if (len > getMaxLength()) { + len = getMaxLength(); + } + + return new PasswordGenerator().generatePassword(len, charRule.getRules()); + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 6dcb7a7b3f..3fcab94481 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -37,7 +37,7 @@ public class MSysConfig extends X_AD_SysConfig /** * */ - private static final long serialVersionUID = -9111154530183645884L; + private static final long serialVersionUID = 5434521728516112616L; public final static String PDF_FONT_DIR = "PDF_FONT_DIR"; public final static String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS"; @@ -50,6 +50,7 @@ public class MSysConfig extends X_AD_SysConfig public static final String ZK_DASHBOARD_REFRESH_INTERVAL = "ZK_DASHBOARD_REFRESH_INTERVAL"; public static final String RecentItems_MaxShown = "RecentItems_MaxShown"; public static final String USE_EMAIL_FOR_LOGIN = "USE_EMAIL_FOR_LOGIN"; + public static final String LOGIN_SHOW_RESETPASSWORD = "LOGIN_SHOW_RESETPASSWORD"; public static final String ALogin_ShowOneRole = "ALogin_ShowOneRole"; public static final String ZK_BROWSER_ICON = "ZK_BROWSER_ICON"; public static final String ZK_BROWSER_TITLE = "ZK_BROWSER_TITLE"; diff --git a/org.adempiere.base/src/org/compiere/model/MUser.java b/org.adempiere.base/src/org/compiere/model/MUser.java index 0a6c7b75a8..eea203901f 100644 --- a/org.adempiere.base/src/org/compiere/model/MUser.java +++ b/org.adempiere.base/src/org/compiere/model/MUser.java @@ -212,13 +212,6 @@ public class MUser extends X_AD_User clientsValidated.add(user.getAD_Client_ID()); boolean valid = false; if (hash_password) { - String hash = user.getPassword(); - String salt = user.getSalt(); - // always do calculation to confuse timing based attacks - if ( hash == null ) - hash = "0000000000000000"; - if ( salt == null ) - salt = "0000000000000000"; valid = user.authenticateHash(password); } else { // password not hashed diff --git a/org.adempiere.base/src/org/compiere/util/Login.java b/org.adempiere.base/src/org/compiere/util/Login.java index 6f72ca7133..47e3740c4e 100644 --- a/org.adempiere.base/src/org/compiere/util/Login.java +++ b/org.adempiere.base/src/org/compiere/util/Login.java @@ -292,28 +292,12 @@ public class Login MUser user = MTable.get(m_ctx, MUser.Table_ID).createQuery( where, null).setParameters(app_user).firstOnly(); // throws error if username collision occurs - String hash = null; - String salt = null; - int AD_User_ID = -1; - - if (user != null ) - { - hash = user.getPassword(); - salt = user.getSalt(); - } - // always do calculation to confuse timing based attacks if ( user == null ) user = MUser.get(m_ctx, 0); - if ( hash == null ) - hash = "0000000000000000"; - if ( salt == null ) - salt = "0000000000000000"; - if ( user.authenticateHash(app_pwd) ) { authenticated = true; - AD_User_ID = user.getAD_User_ID(); app_pwd = null; } } @@ -1396,13 +1380,6 @@ public class Login clientsValidated.add(user.getAD_Client_ID()); boolean valid = false; if (hash_password) { - String hash = user.getPassword(); - String salt = user.getSalt(); - // always do calculation to confuse timing based attacks - if ( hash == null ) - hash = "0000000000000000"; - if ( salt == null ) - salt = "0000000000000000"; valid = user.authenticateHash(app_pwd); } else { // password not hashed diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ChangePasswordPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ChangePasswordPanel.java index 9e1b9b5a46..734e325eef 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ChangePasswordPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ChangePasswordPanel.java @@ -51,12 +51,12 @@ import org.zkoss.zul.Image; */ public class ChangePasswordPanel extends Window implements EventListener { - /** + /** * */ - private static final long serialVersionUID = 5323925843783103350L; + private static final long serialVersionUID = 6055606520280550335L; - private static CLogger logger = CLogger.getCLogger(ChangePasswordPanel.class); + private static CLogger logger = CLogger.getCLogger(ChangePasswordPanel.class); private LoginWindow wndLogin; @@ -260,7 +260,7 @@ public class ChangePasswordPanel extends Window implements EventListener { if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) { - validateChangePassword(); + validateChangePassword(); } else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { @@ -316,24 +316,21 @@ public class ChangePasswordPanel extends Window implements EventListener logger.severe("Could not find user '" + m_userName + "'"); throw new AdempiereException("Could not find user"); } - - user.setPassword(newPassword); + + user.set_ValueOfColumn("Password", newPassword); // will be hashed and validate on saveEx user.setIsExpired(false); user.setSecurityQuestion(securityQuestion); user.setAnswer(answer); - if (!user.save(trx.getTrxName())) - { - trx.rollback(); - throw new AdempiereException("Could not update user"); - } + user.saveEx(trx.getTrxName()); } trx.commit(); } - catch (Exception e) + catch (AdempiereException e) { if (trx != null) trx.rollback(); + throw e; } finally { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java index 6ecbfa50db..c7b00e5103 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/LoginPanel.java @@ -220,19 +220,21 @@ public class LoginPanel extends Window implements EventListener tr.appendChild(td); td.appendChild(chkRememberMe); } - - tr = new Tr(); - tr.setId("rowResetPassword"); - table.appendChild(tr); - td = new Td(); - tr.appendChild(td); - td.setSclass(ITheme.LOGIN_LABEL_CLASS); - td.appendChild(new Label("")); - td = new Td(); - td.setSclass(ITheme.LOGIN_FIELD_CLASS); - tr.appendChild(td); - td.appendChild(btnResetPassword); - btnResetPassword.addEventListener(Events.ON_CLICK, this); + + if (MSysConfig.getBooleanValue(MSysConfig.LOGIN_SHOW_RESETPASSWORD, true)) { + tr = new Tr(); + tr.setId("rowResetPassword"); + table.appendChild(tr); + td = new Td(); + tr.appendChild(td); + td.setSclass(ITheme.LOGIN_LABEL_CLASS); + td.appendChild(new Label("")); + td = new Td(); + td.setSclass(ITheme.LOGIN_FIELD_CLASS); + tr.appendChild(td); + td.appendChild(btnResetPassword); + btnResetPassword.addEventListener(Events.ON_CLICK, this); + } div = new Div(); div.setSclass(ITheme.LOGIN_BOX_FOOTER_CLASS); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ResetPasswordPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ResetPasswordPanel.java index 8e98d8afe5..dede9b63f2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ResetPasswordPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ResetPasswordPanel.java @@ -34,6 +34,7 @@ import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.window.LoginWindow; import org.compiere.model.MClient; import org.compiere.model.MMailText; +import org.compiere.model.MPasswordRule; import org.compiere.model.MSysConfig; import org.compiere.model.MUser; import org.compiere.model.Query; @@ -62,8 +63,8 @@ public class ResetPasswordPanel extends Window implements EventListener /** * */ - private static final long serialVersionUID = 190270426336225224L; - + private static final long serialVersionUID = -657724758165769510L; + private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class); private static final int MAX_RESET_PASSWORD_TRIES = 3; @@ -325,15 +326,15 @@ public class ResetPasswordPanel extends Window implements EventListener } throw new AdempiereException(errMsg); } - - boolean hash_password = MSysConfig.getBooleanValue(MSysConfig.USER_PASSWORD_HASH, false); - StringBuilder sqlUpdate = new StringBuilder("UPDATE AD_User "); - sqlUpdate.append("SET IsExpired='Y', Password=? "); - sqlUpdate.append("WHERE AD_User_ID=? "); - - SecureRandom random = new SecureRandom(); - String newPassword = BigInteger.probablePrime(50, random).toString(Character.MAX_RADIX); + String newPassword; + MPasswordRule pwdrule = MPasswordRule.getRules(Env.getCtx(), null); + if (pwdrule != null) { + newPassword = pwdrule.generate(); + } else { + SecureRandom random = new SecureRandom(); + newPassword = BigInteger.probablePrime(50, random).toString(Character.MAX_RADIX); + } String errorMsg = ""; Trx trx = null; @@ -346,18 +347,10 @@ public class ResetPasswordPanel extends Window implements EventListener { user.set_TrxName(trx.getTrxName()); - user.setPassword(newPassword); - if (hash_password) - user.setPassword(user.getPassword()); - // use SQL to update the password to skip password rule validation - int no = DB.executeUpdate(sqlUpdate.toString(), new Object[] {user.getPassword(), user.getAD_User_ID()}, false, trx.getTrxName()); - if (no <= 0) - { - trx.rollback(); - logger.severe("Failed to update user '" + m_userName + "'"); - throw new AdempiereException("Failed to update user"); - } - + user.set_ValueOfColumn("Password", newPassword); // will be hashed and validate on saveEx + user.setIsExpired(true); + user.saveEx(); + if (sendEmail(user, newPassword)) logger.fine(user.getEMail()); else @@ -365,8 +358,8 @@ public class ResetPasswordPanel extends Window implements EventListener if (errorMsg.length() > 0) errorMsg += ", "; errorMsg += user.getEMail(); - logger.warning("Failed to send email to user - " + user.getEMail()); - } + throw new AdempiereException("Failed to send email to user - " + user.getEMail()); + } } trx.commit(); @@ -381,7 +374,7 @@ public class ResetPasswordPanel extends Window implements EventListener if (trx != null) trx.close(); } - + if (errorMsg.length() > 0) throw new AdempiereException(Msg.getMsg(m_ctx, "RequestActionEMailError") + ": " + errorMsg); else @@ -408,10 +401,10 @@ public class ResetPasswordPanel extends Window implements EventListener return false; MMailText mailText = new MMailText(m_ctx, R_MailText_ID, null); - to.setPassword(newPassword); + to.set_ValueOfColumn("Password", newPassword); // will be hashed and validate on saveEx mailText.setUser(to); String message = mailText.getMailText(true); - message = Env.parseVariable(message, to, to.get_TrxName(), true); + message = Env.parseVariable(message, to, to.get_TrxName(), true); EMail email = client.createEMail(to.getEMail(), mailText.getMailHeader(), message, mailText.isHtml()); if (mailText.isHtml()) email.setMessageHTML(mailText.getMailHeader(), message); @@ -427,4 +420,4 @@ public class ResetPasswordPanel extends Window implements EventListener } return EMail.SENT_OK.equals(email.send()); } -} \ No newline at end of file +}