IDEMPIERE-375 Implement Forgot my Password

This commit is contained in:
Carlos Ruiz 2012-09-11 17:05:42 -05:00
parent 7c7a3d9464
commit 42eb30488f
11 changed files with 107 additions and 107 deletions

View File

@ -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) 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 -- Sep 10, 2012 5:21:23 PM SGT
-- IDEMPIERE-375 Implement Forgot my Password -- 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')) 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'))

View File

@ -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
;

View File

@ -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) 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 -- Sep 10, 2012 5:21:23 PM SGT
-- IDEMPIERE-375 Implement Forgot my Password -- 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')) 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'))

View File

@ -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
;

View File

@ -46,6 +46,7 @@ import edu.vt.middleware.password.NonAlphanumericCharacterRule;
import edu.vt.middleware.password.NumericalSequenceRule; import edu.vt.middleware.password.NumericalSequenceRule;
import edu.vt.middleware.password.Password; import edu.vt.middleware.password.Password;
import edu.vt.middleware.password.PasswordData; import edu.vt.middleware.password.PasswordData;
import edu.vt.middleware.password.PasswordGenerator;
import edu.vt.middleware.password.PasswordValidator; import edu.vt.middleware.password.PasswordValidator;
import edu.vt.middleware.password.QwertySequenceRule; import edu.vt.middleware.password.QwertySequenceRule;
import edu.vt.middleware.password.RepeatCharacterRegexRule; 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 * @param ctx
@ -225,4 +226,44 @@ public class MPasswordRule extends X_AD_PasswordRule {
return new MessageResolver(props); 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());
}
} }

View File

@ -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 PDF_FONT_DIR = "PDF_FONT_DIR";
public final static String TWOPACK_HANDLE_TRANSLATIONS = "2PACK_HANDLE_TRANSLATIONS"; 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 ZK_DASHBOARD_REFRESH_INTERVAL = "ZK_DASHBOARD_REFRESH_INTERVAL";
public static final String RecentItems_MaxShown = "RecentItems_MaxShown"; public static final String RecentItems_MaxShown = "RecentItems_MaxShown";
public static final String USE_EMAIL_FOR_LOGIN = "USE_EMAIL_FOR_LOGIN"; 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 ALogin_ShowOneRole = "ALogin_ShowOneRole";
public static final String ZK_BROWSER_ICON = "ZK_BROWSER_ICON"; public static final String ZK_BROWSER_ICON = "ZK_BROWSER_ICON";
public static final String ZK_BROWSER_TITLE = "ZK_BROWSER_TITLE"; public static final String ZK_BROWSER_TITLE = "ZK_BROWSER_TITLE";

View File

@ -212,13 +212,6 @@ public class MUser extends X_AD_User
clientsValidated.add(user.getAD_Client_ID()); clientsValidated.add(user.getAD_Client_ID());
boolean valid = false; boolean valid = false;
if (hash_password) { 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); valid = user.authenticateHash(password);
} else { } else {
// password not hashed // password not hashed

View File

@ -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 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 // always do calculation to confuse timing based attacks
if ( user == null ) if ( user == null )
user = MUser.get(m_ctx, 0); user = MUser.get(m_ctx, 0);
if ( hash == null )
hash = "0000000000000000";
if ( salt == null )
salt = "0000000000000000";
if ( user.authenticateHash(app_pwd) ) if ( user.authenticateHash(app_pwd) )
{ {
authenticated = true; authenticated = true;
AD_User_ID = user.getAD_User_ID();
app_pwd = null; app_pwd = null;
} }
} }
@ -1396,13 +1380,6 @@ public class Login
clientsValidated.add(user.getAD_Client_ID()); clientsValidated.add(user.getAD_Client_ID());
boolean valid = false; boolean valid = false;
if (hash_password) { 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); valid = user.authenticateHash(app_pwd);
} else { } else {
// password not hashed // password not hashed

View File

@ -51,12 +51,12 @@ import org.zkoss.zul.Image;
*/ */
public class ChangePasswordPanel extends Window implements EventListener<Event> public class ChangePasswordPanel extends Window implements EventListener<Event>
{ {
/** /**
* *
*/ */
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; private LoginWindow wndLogin;
@ -260,7 +260,7 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
{ {
if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) if (event.getTarget().getId().equals(ConfirmPanel.A_OK))
{ {
validateChangePassword(); validateChangePassword();
} }
else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL))
{ {
@ -317,23 +317,20 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
throw new AdempiereException("Could not find user"); 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.setIsExpired(false);
user.setSecurityQuestion(securityQuestion); user.setSecurityQuestion(securityQuestion);
user.setAnswer(answer); user.setAnswer(answer);
if (!user.save(trx.getTrxName())) user.saveEx(trx.getTrxName());
{
trx.rollback();
throw new AdempiereException("Could not update user");
}
} }
trx.commit(); trx.commit();
} }
catch (Exception e) catch (AdempiereException e)
{ {
if (trx != null) if (trx != null)
trx.rollback(); trx.rollback();
throw e;
} }
finally finally
{ {

View File

@ -221,18 +221,20 @@ public class LoginPanel extends Window implements EventListener<Event>
td.appendChild(chkRememberMe); td.appendChild(chkRememberMe);
} }
tr = new Tr(); if (MSysConfig.getBooleanValue(MSysConfig.LOGIN_SHOW_RESETPASSWORD, true)) {
tr.setId("rowResetPassword"); tr = new Tr();
table.appendChild(tr); tr.setId("rowResetPassword");
td = new Td(); table.appendChild(tr);
tr.appendChild(td); td = new Td();
td.setSclass(ITheme.LOGIN_LABEL_CLASS); tr.appendChild(td);
td.appendChild(new Label("")); td.setSclass(ITheme.LOGIN_LABEL_CLASS);
td = new Td(); td.appendChild(new Label(""));
td.setSclass(ITheme.LOGIN_FIELD_CLASS); td = new Td();
tr.appendChild(td); td.setSclass(ITheme.LOGIN_FIELD_CLASS);
td.appendChild(btnResetPassword); tr.appendChild(td);
btnResetPassword.addEventListener(Events.ON_CLICK, this); td.appendChild(btnResetPassword);
btnResetPassword.addEventListener(Events.ON_CLICK, this);
}
div = new Div(); div = new Div();
div.setSclass(ITheme.LOGIN_BOX_FOOTER_CLASS); div.setSclass(ITheme.LOGIN_BOX_FOOTER_CLASS);

View File

@ -34,6 +34,7 @@ import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.LoginWindow; import org.adempiere.webui.window.LoginWindow;
import org.compiere.model.MClient; import org.compiere.model.MClient;
import org.compiere.model.MMailText; import org.compiere.model.MMailText;
import org.compiere.model.MPasswordRule;
import org.compiere.model.MSysConfig; import org.compiere.model.MSysConfig;
import org.compiere.model.MUser; import org.compiere.model.MUser;
import org.compiere.model.Query; import org.compiere.model.Query;
@ -62,7 +63,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
/** /**
* *
*/ */
private static final long serialVersionUID = 190270426336225224L; private static final long serialVersionUID = -657724758165769510L;
private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class); private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class);
@ -326,14 +327,14 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
throw new AdempiereException(errMsg); throw new AdempiereException(errMsg);
} }
boolean hash_password = MSysConfig.getBooleanValue(MSysConfig.USER_PASSWORD_HASH, false); String newPassword;
MPasswordRule pwdrule = MPasswordRule.getRules(Env.getCtx(), null);
StringBuilder sqlUpdate = new StringBuilder("UPDATE AD_User "); if (pwdrule != null) {
sqlUpdate.append("SET IsExpired='Y', Password=? "); newPassword = pwdrule.generate();
sqlUpdate.append("WHERE AD_User_ID=? "); } else {
SecureRandom random = new SecureRandom();
SecureRandom random = new SecureRandom(); newPassword = BigInteger.probablePrime(50, random).toString(Character.MAX_RADIX);
String newPassword = BigInteger.probablePrime(50, random).toString(Character.MAX_RADIX); }
String errorMsg = ""; String errorMsg = "";
Trx trx = null; Trx trx = null;
@ -346,17 +347,9 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
{ {
user.set_TrxName(trx.getTrxName()); user.set_TrxName(trx.getTrxName());
user.setPassword(newPassword); user.set_ValueOfColumn("Password", newPassword); // will be hashed and validate on saveEx
if (hash_password) user.setIsExpired(true);
user.setPassword(user.getPassword()); user.saveEx();
// 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");
}
if (sendEmail(user, newPassword)) if (sendEmail(user, newPassword))
logger.fine(user.getEMail()); logger.fine(user.getEMail());
@ -365,7 +358,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
if (errorMsg.length() > 0) if (errorMsg.length() > 0)
errorMsg += ", "; errorMsg += ", ";
errorMsg += user.getEMail(); errorMsg += user.getEMail();
logger.warning("Failed to send email to user - " + user.getEMail()); throw new AdempiereException("Failed to send email to user - " + user.getEMail());
} }
} }
@ -408,7 +401,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
return false; return false;
MMailText mailText = new MMailText(m_ctx, R_MailText_ID, null); 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); mailText.setUser(to);
String message = mailText.getMailText(true); String message = mailText.getMailText(true);
message = Env.parseVariable(message, to, to.get_TrxName(), true); message = Env.parseVariable(message, to, to.get_TrxName(), true);