IDEMPIERE-375 Implement Forgot my Password - add validation to check new password differ from old password and change the security question design
This commit is contained in:
parent
f1860fa2ce
commit
951765ccd0
|
@ -0,0 +1,36 @@
|
||||||
|
-- Sep 12, 2012 6:56:41 PM SGT
|
||||||
|
-- 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 (200020,'D','S','Y','New password must differs from the old password','13b5a576-7b91-471b-8b40-05589dd585f7',TO_DATE('2012-09-12 18:56:39','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2012-09-12 18:56:39','YYYY-MM-DD HH24:MI:SS'),0,0,100,'Y',100,'CHANGE_PASSWORD_MUST_DIFFER')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:57:05 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
UPDATE AD_Column SET FieldLength=1024,Updated=TO_DATE('2012-09-12 18:57:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=200457
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:57:13 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
ALTER TABLE AD_User MODIFY SecurityQuestion NVARCHAR2(1024) DEFAULT NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:58:41 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','New Password must differ from Old Password',200066,'U','0d873a03-0980-4725-8a4f-a6954e4ee59e','NewPasswordMustDiffer','Y',TO_DATE('2012-09-12 18:58:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_DATE('2012-09-12 18:58:40','YYYY-MM-DD HH24:MI:SS'))
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:58:41 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
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=200066 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 12, 2012 6:58:45 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
UPDATE AD_Message SET EntityType='D',Updated=TO_DATE('2012-09-12 18:58:45','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200066
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_User u SET SecurityQuestion = (
|
||||||
|
SELECT MAX(m.MsgText) FROM AD_Message m WHERE m.Value = u.SecurityQuestion)
|
||||||
|
WHERE u.SecurityQuestion IS NOT NULL;
|
||||||
|
|
||||||
|
SELECT register_migration_script('910_IDEMPIERE-375.sql') FROM dual
|
||||||
|
;
|
|
@ -0,0 +1,36 @@
|
||||||
|
-- Sep 12, 2012 6:56:41 PM SGT
|
||||||
|
-- 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 (200020,'D','S','Y','New password must differs from the old password','13b5a576-7b91-471b-8b40-05589dd585f7',TO_TIMESTAMP('2012-09-12 18:56:39','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2012-09-12 18:56:39','YYYY-MM-DD HH24:MI:SS'),0,0,100,'Y',100,'CHANGE_PASSWORD_MUST_DIFFER')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:57:05 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
UPDATE AD_Column SET FieldLength=1024,Updated=TO_TIMESTAMP('2012-09-12 18:57:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=200457
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:57:13 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
INSERT INTO t_alter_column values('ad_user','SecurityQuestion','VARCHAR(1024)',null,'NULL')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:58:41 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','New Password must differ from Old Password',200066,'U','0d873a03-0980-4725-8a4f-a6954e4ee59e','NewPasswordMustDiffer','Y',TO_TIMESTAMP('2012-09-12 18:58:40','YYYY-MM-DD HH24:MI:SS'),100,100,0,0,TO_TIMESTAMP('2012-09-12 18:58:40','YYYY-MM-DD HH24:MI:SS'))
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Sep 12, 2012 6:58:41 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
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=200066 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 12, 2012 6:58:45 PM SGT
|
||||||
|
-- IDEMPIERE-375 Implement Forgot my Password
|
||||||
|
UPDATE AD_Message SET EntityType='D',Updated=TO_TIMESTAMP('2012-09-12 18:58:45','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200066
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_User u SET SecurityQuestion = (
|
||||||
|
SELECT MAX(m.MsgText) FROM AD_Message m WHERE m.Value = u.SecurityQuestion)
|
||||||
|
WHERE u.SecurityQuestion IS NOT NULL;
|
||||||
|
|
||||||
|
SELECT register_migration_script('910_IDEMPIERE-375.sql') FROM dual
|
||||||
|
;
|
|
@ -95,6 +95,7 @@ public class MSysConfig extends X_AD_SysConfig
|
||||||
public static final String USER_LOCKING_MAX_LOGIN_ATTEMPT = "USER_LOCKING_MAX_LOGIN_ATTEMPT";
|
public static final String USER_LOCKING_MAX_LOGIN_ATTEMPT = "USER_LOCKING_MAX_LOGIN_ATTEMPT";
|
||||||
public static final String USER_LOCKING_MAX_INACTIVE_PERIOD_DAY = "USER_LOCKING_MAX_INACTIVE_PERIOD_DAY";
|
public static final String USER_LOCKING_MAX_INACTIVE_PERIOD_DAY = "USER_LOCKING_MAX_INACTIVE_PERIOD_DAY";
|
||||||
public static final String USER_LOCKING_MAX_PASSWORD_AGE_DAY = "USER_LOCKING_MAX_PASSWORD_AGE_DAY";
|
public static final String USER_LOCKING_MAX_PASSWORD_AGE_DAY = "USER_LOCKING_MAX_PASSWORD_AGE_DAY";
|
||||||
|
public static final String CHANGE_PASSWORD_MUST_DIFFER = "CHANGE_PASSWORD_MUST_DIFFER";
|
||||||
public static final String ProductUOMConversionUOMValidate = "ProductUOMConversionUOMValidate";
|
public static final String ProductUOMConversionUOMValidate = "ProductUOMConversionUOMValidate";
|
||||||
public static final String ProductUOMConversionRateValidate = "ProductUOMConversionRateValidate";
|
public static final String ProductUOMConversionRateValidate = "ProductUOMConversionRateValidate";
|
||||||
public static final String SYSTEM_INSERT_CHANGELOG = "SYSTEM_INSERT_CHANGELOG";
|
public static final String SYSTEM_INSERT_CHANGELOG = "SYSTEM_INSERT_CHANGELOG";
|
||||||
|
|
|
@ -120,9 +120,6 @@ public final class ALogin extends CDialog
|
||||||
private static final int CONNECTED_OK = 0;
|
private static final int CONNECTED_OK = 0;
|
||||||
private static final int CONNECTED_OK_WITH_PASSWORD_EXPIRED = 1;
|
private static final int CONNECTED_OK_WITH_PASSWORD_EXPIRED = 1;
|
||||||
|
|
||||||
/* private static final int NO_OF_SECURITY_QUESTION = 5;
|
|
||||||
private static final String SECURITY_QUESTION_PREFIX = "SecurityQuestion_";
|
|
||||||
*/
|
|
||||||
private CPanel mainPanel = new CPanel(new BorderLayout());
|
private CPanel mainPanel = new CPanel(new BorderLayout());
|
||||||
private CTabbedPane loginTabPane = new CTabbedPane();
|
private CTabbedPane loginTabPane = new CTabbedPane();
|
||||||
private CPanel connectionPanel = new CPanel();
|
private CPanel connectionPanel = new CPanel();
|
||||||
|
@ -169,11 +166,11 @@ public final class ALogin extends CDialog
|
||||||
private JPasswordField txtNewPassword = new JPasswordField();
|
private JPasswordField txtNewPassword = new JPasswordField();
|
||||||
private JPasswordField txtRetypeNewPassword = new JPasswordField();
|
private JPasswordField txtRetypeNewPassword = new JPasswordField();
|
||||||
//
|
//
|
||||||
/* private CLabel lblSecurityQuestion = new CLabel();
|
private CLabel lblSecurityQuestion = new CLabel();
|
||||||
private CLabel lblAnswer = new CLabel();
|
private CLabel lblAnswer = new CLabel();
|
||||||
private VComboBox lstSecurityQuestion = new VComboBox();
|
private CTextField txtSecurityQuestion = new CTextField();
|
||||||
private CTextField txtAnswer = new CTextField();
|
private CTextField txtAnswer = new CTextField();
|
||||||
*/
|
|
||||||
/** Server Connection */
|
/** Server Connection */
|
||||||
private CConnection m_cc;
|
private CConnection m_cc;
|
||||||
/** Application User */
|
/** Application User */
|
||||||
|
@ -382,22 +379,18 @@ public final class ALogin extends CDialog
|
||||||
lblRetypeNewPassword.setHorizontalAlignment(SwingConstants.RIGHT);
|
lblRetypeNewPassword.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
lblRetypeNewPassword.setText(Msg.getMsg(m_ctx, "New Password Confirm"));
|
lblRetypeNewPassword.setText(Msg.getMsg(m_ctx, "New Password Confirm"));
|
||||||
|
|
||||||
/* lstSecurityQuestion.setName("lstSecurityQuestion");
|
txtSecurityQuestion.setName("txtSecurityQuestion");
|
||||||
lblSecurityQuestion.setRequestFocusEnabled(false);
|
lblSecurityQuestion.setRequestFocusEnabled(false);
|
||||||
lblSecurityQuestion.setLabelFor(lstSecurityQuestion);
|
lblSecurityQuestion.setLabelFor(txtSecurityQuestion);
|
||||||
lblSecurityQuestion.setHorizontalAlignment(SwingConstants.RIGHT);
|
lblSecurityQuestion.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
lblSecurityQuestion.setText(Msg.getMsg(m_ctx, "SecurityQuestion"));
|
lblSecurityQuestion.setText(Msg.getMsg(m_ctx, "SecurityQuestion"));
|
||||||
|
|
||||||
lstSecurityQuestion.removeAllItems();
|
|
||||||
for (int i = 1; i <= NO_OF_SECURITY_QUESTION; i++)
|
|
||||||
lstSecurityQuestion.addItem(new ValueNamePair(SECURITY_QUESTION_PREFIX + i, Msg.getMsg(m_ctx, SECURITY_QUESTION_PREFIX + i)));
|
|
||||||
|
|
||||||
txtAnswer.setName("txtAnswer");
|
txtAnswer.setName("txtAnswer");
|
||||||
lblAnswer.setRequestFocusEnabled(false);
|
lblAnswer.setRequestFocusEnabled(false);
|
||||||
lblAnswer.setLabelFor(txtAnswer);
|
lblAnswer.setLabelFor(txtAnswer);
|
||||||
lblAnswer.setHorizontalAlignment(SwingConstants.RIGHT);
|
lblAnswer.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
lblAnswer.setText(Msg.getMsg(m_ctx, "Answer"));
|
lblAnswer.setText(Msg.getMsg(m_ctx, "Answer"));
|
||||||
*/
|
|
||||||
changePasswordPanel.setLayout(changePasswordPanelLayout);
|
changePasswordPanel.setLayout(changePasswordPanelLayout);
|
||||||
|
|
||||||
changePasswordPanel.add(lblOldPassword, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
|
changePasswordPanel.add(lblOldPassword, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
|
||||||
|
@ -412,15 +405,15 @@ public final class ALogin extends CDialog
|
||||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
||||||
changePasswordPanel.add(txtRetypeNewPassword, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0
|
changePasswordPanel.add(txtRetypeNewPassword, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0
|
||||||
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
||||||
/* changePasswordPanel.add(lblSecurityQuestion, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
|
changePasswordPanel.add(lblSecurityQuestion, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
|
||||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
||||||
changePasswordPanel.add(lstSecurityQuestion, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0
|
changePasswordPanel.add(txtSecurityQuestion, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0
|
||||||
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
||||||
changePasswordPanel.add(lblAnswer, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0
|
changePasswordPanel.add(lblAnswer, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0
|
||||||
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(12, 12, 5, 5), 0, 0));
|
||||||
changePasswordPanel.add(txtAnswer, new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0
|
changePasswordPanel.add(txtAnswer, new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0
|
||||||
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(12, 0, 5, 12), 0, 0));
|
||||||
*/ loginTabPane.add(changePasswordPanel, res.getString("ChangePassword"));
|
loginTabPane.add(changePasswordPanel, res.getString("ChangePassword"));
|
||||||
loginTabPane.setEnabledAt(TAB_CHANGE_PASSWORD, false);
|
loginTabPane.setEnabledAt(TAB_CHANGE_PASSWORD, false);
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -656,12 +649,9 @@ public final class ALogin extends CDialog
|
||||||
String newPassword = new String(txtNewPassword.getPassword());
|
String newPassword = new String(txtNewPassword.getPassword());
|
||||||
String retypeNewPassword = new String(txtRetypeNewPassword.getPassword());
|
String retypeNewPassword = new String(txtRetypeNewPassword.getPassword());
|
||||||
|
|
||||||
/* String securityQuestion = null;
|
String securityQuestion = txtSecurityQuestion.getText();
|
||||||
if (lstSecurityQuestion.getSelectedItem() != null)
|
|
||||||
securityQuestion = ((ValueNamePair) lstSecurityQuestion.getSelectedItem()).getValue();
|
|
||||||
|
|
||||||
String answer = txtAnswer.getText();
|
String answer = txtAnswer.getText();
|
||||||
*/
|
|
||||||
if (Util.isEmpty(oldPassword))
|
if (Util.isEmpty(oldPassword))
|
||||||
{
|
{
|
||||||
statusBar.setStatusLine(Msg.getMsg(m_ctx, "OldPasswordMandatory"), true);
|
statusBar.setStatusLine(Msg.getMsg(m_ctx, "OldPasswordMandatory"), true);
|
||||||
|
@ -680,7 +670,7 @@ public final class ALogin extends CDialog
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (Util.isEmpty(securityQuestion))
|
if (Util.isEmpty(securityQuestion))
|
||||||
{
|
{
|
||||||
statusBar.setStatusLine(Msg.getMsg(m_ctx, "SecurityQuestionMandatory"), true);
|
statusBar.setStatusLine(Msg.getMsg(m_ctx, "SecurityQuestionMandatory"), true);
|
||||||
return;
|
return;
|
||||||
|
@ -691,7 +681,7 @@ public final class ALogin extends CDialog
|
||||||
statusBar.setStatusLine(Msg.getMsg(m_ctx, "AnswerMandatory"), true);
|
statusBar.setStatusLine(Msg.getMsg(m_ctx, "AnswerMandatory"), true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
String m_userPassword = new String(m_pwd);
|
String m_userPassword = new String(m_pwd);
|
||||||
if (!oldPassword.equals(m_userPassword))
|
if (!oldPassword.equals(m_userPassword))
|
||||||
{
|
{
|
||||||
|
@ -699,6 +689,15 @@ public final class ALogin extends CDialog
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.CHANGE_PASSWORD_MUST_DIFFER, true))
|
||||||
|
{
|
||||||
|
if (oldPassword.equals(newPassword))
|
||||||
|
{
|
||||||
|
statusBar.setStatusLine(Msg.getMsg(m_ctx, "NewPasswordMustDiffer"), true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Trx trx = null;
|
Trx trx = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -721,9 +720,9 @@ public final class ALogin extends CDialog
|
||||||
|
|
||||||
user.setPassword(newPassword);
|
user.setPassword(newPassword);
|
||||||
user.setIsExpired(false);
|
user.setIsExpired(false);
|
||||||
/* user.setSecurityQuestion(securityQuestion);
|
user.setSecurityQuestion(securityQuestion);
|
||||||
user.setAnswer(answer);
|
user.setAnswer(answer);
|
||||||
*/ if (!user.save(trx.getTrxName()))
|
if (!user.save(trx.getTrxName()))
|
||||||
{
|
{
|
||||||
trx.rollback();
|
trx.rollback();
|
||||||
statusBar.setStatusLine("Could not update user", true);
|
statusBar.setStatusLine("Could not update user", true);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.util.Properties;
|
||||||
import org.adempiere.exceptions.AdempiereException;
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.adempiere.webui.AdempiereIdGenerator;
|
import org.adempiere.webui.AdempiereIdGenerator;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
import org.adempiere.webui.component.Combobox;
|
|
||||||
import org.adempiere.webui.component.ConfirmPanel;
|
import org.adempiere.webui.component.ConfirmPanel;
|
||||||
import org.adempiere.webui.component.Label;
|
import org.adempiere.webui.component.Label;
|
||||||
import org.adempiere.webui.component.Textbox;
|
import org.adempiere.webui.component.Textbox;
|
||||||
|
@ -29,6 +28,7 @@ import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.theme.ITheme;
|
import org.adempiere.webui.theme.ITheme;
|
||||||
import org.adempiere.webui.theme.ThemeManager;
|
import org.adempiere.webui.theme.ThemeManager;
|
||||||
import org.adempiere.webui.window.LoginWindow;
|
import org.adempiere.webui.window.LoginWindow;
|
||||||
|
import org.compiere.model.MSysConfig;
|
||||||
import org.compiere.model.MUser;
|
import org.compiere.model.MUser;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
@ -75,10 +75,10 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
private Label lblRetypeNewPassword;
|
private Label lblRetypeNewPassword;
|
||||||
private Label lblSecurityQuestion;
|
private Label lblSecurityQuestion;
|
||||||
private Label lblAnswer;
|
private Label lblAnswer;
|
||||||
private Combobox lstSecurityQuestion;
|
|
||||||
private Textbox txtOldPassword;
|
private Textbox txtOldPassword;
|
||||||
private Textbox txtNewPassword;
|
private Textbox txtNewPassword;
|
||||||
private Textbox txtRetypeNewPassword;
|
private Textbox txtRetypeNewPassword;
|
||||||
|
private Textbox txtSecurityQuestion;
|
||||||
private Textbox txtAnswer;
|
private Textbox txtAnswer;
|
||||||
|
|
||||||
public ChangePasswordPanel(Properties ctx, LoginWindow loginWindow, String userName, String userPassword, boolean show, KeyNamePair[] clientsKNPairs)
|
public ChangePasswordPanel(Properties ctx, LoginWindow loginWindow, String userName, String userPassword, boolean show, KeyNamePair[] clientsKNPairs)
|
||||||
|
@ -168,7 +168,7 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
td = new Td();
|
td = new Td();
|
||||||
td.setSclass(ITheme.LOGIN_FIELD_CLASS);
|
td.setSclass(ITheme.LOGIN_FIELD_CLASS);
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
td.appendChild(lstSecurityQuestion);
|
td.appendChild(txtSecurityQuestion);
|
||||||
|
|
||||||
tr = new Tr();
|
tr = new Tr();
|
||||||
tr.setId("rowAnswer");
|
tr.setId("rowAnswer");
|
||||||
|
@ -216,17 +216,6 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
lblAnswer.setId("lblAnswer");
|
lblAnswer.setId("lblAnswer");
|
||||||
lblAnswer.setValue(Msg.getMsg(m_ctx, "Answer"));
|
lblAnswer.setValue(Msg.getMsg(m_ctx, "Answer"));
|
||||||
|
|
||||||
lstSecurityQuestion = new Combobox();
|
|
||||||
lstSecurityQuestion.setAutocomplete(true);
|
|
||||||
lstSecurityQuestion.setAutodrop(true);
|
|
||||||
lstSecurityQuestion.setId("lstSecurityQuestion");
|
|
||||||
lstSecurityQuestion.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + lstSecurityQuestion.getId());
|
|
||||||
lstSecurityQuestion.setWidth("220px");
|
|
||||||
|
|
||||||
lstSecurityQuestion.getItems().clear();
|
|
||||||
for (int i = 1; i <= ResetPasswordPanel.NO_OF_SECURITY_QUESTION; i++)
|
|
||||||
lstSecurityQuestion.appendItem(Msg.getMsg(m_ctx, ResetPasswordPanel.SECURITY_QUESTION_PREFIX + i), ResetPasswordPanel.SECURITY_QUESTION_PREFIX + i);
|
|
||||||
|
|
||||||
txtOldPassword = new Textbox();
|
txtOldPassword = new Textbox();
|
||||||
txtOldPassword.setId("txtOldPassword");
|
txtOldPassword.setId("txtOldPassword");
|
||||||
txtOldPassword.setType("password");
|
txtOldPassword.setType("password");
|
||||||
|
@ -248,6 +237,12 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
txtRetypeNewPassword.setCols(25);
|
txtRetypeNewPassword.setCols(25);
|
||||||
txtRetypeNewPassword.setWidth("220px");
|
txtRetypeNewPassword.setWidth("220px");
|
||||||
|
|
||||||
|
txtSecurityQuestion = new Textbox();
|
||||||
|
txtSecurityQuestion.setId("txtSecurityQuestion");
|
||||||
|
txtSecurityQuestion.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtSecurityQuestion.getId());
|
||||||
|
txtSecurityQuestion.setCols(25);
|
||||||
|
txtSecurityQuestion.setWidth("220px");
|
||||||
|
|
||||||
txtAnswer = new Textbox();
|
txtAnswer = new Textbox();
|
||||||
txtAnswer.setId("txtAnswer");
|
txtAnswer.setId("txtAnswer");
|
||||||
// txtAnswer.setType("password");
|
// txtAnswer.setType("password");
|
||||||
|
@ -274,11 +269,7 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
String oldPassword = txtOldPassword.getValue();
|
String oldPassword = txtOldPassword.getValue();
|
||||||
String newPassword = txtNewPassword.getValue();
|
String newPassword = txtNewPassword.getValue();
|
||||||
String retypeNewPassword = txtRetypeNewPassword.getValue();
|
String retypeNewPassword = txtRetypeNewPassword.getValue();
|
||||||
|
String securityQuestion = txtSecurityQuestion.getValue();
|
||||||
String securityQuestion = null;
|
|
||||||
if (lstSecurityQuestion.getSelectedItem() != null)
|
|
||||||
securityQuestion = (String) lstSecurityQuestion.getSelectedItem().getValue();
|
|
||||||
|
|
||||||
String answer = txtAnswer.getValue();
|
String answer = txtAnswer.getValue();
|
||||||
|
|
||||||
if (Util.isEmpty(oldPassword))
|
if (Util.isEmpty(oldPassword))
|
||||||
|
@ -299,6 +290,12 @@ public class ChangePasswordPanel extends Window implements EventListener<Event>
|
||||||
if (!oldPassword.equals(m_userPassword))
|
if (!oldPassword.equals(m_userPassword))
|
||||||
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "OldPasswordNoMatch"));
|
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "OldPasswordNoMatch"));
|
||||||
|
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.CHANGE_PASSWORD_MUST_DIFFER, true))
|
||||||
|
{
|
||||||
|
if (oldPassword.equals(newPassword))
|
||||||
|
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "NewPasswordMustDiffer"));
|
||||||
|
}
|
||||||
|
|
||||||
Trx trx = null;
|
Trx trx = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.Properties;
|
||||||
import org.adempiere.exceptions.AdempiereException;
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.adempiere.webui.AdempiereIdGenerator;
|
import org.adempiere.webui.AdempiereIdGenerator;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
import org.adempiere.webui.component.Combobox;
|
|
||||||
import org.adempiere.webui.component.ConfirmPanel;
|
import org.adempiere.webui.component.ConfirmPanel;
|
||||||
import org.adempiere.webui.component.Label;
|
import org.adempiere.webui.component.Label;
|
||||||
import org.adempiere.webui.component.Textbox;
|
import org.adempiere.webui.component.Textbox;
|
||||||
|
@ -68,8 +67,6 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class);
|
private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class);
|
||||||
|
|
||||||
private static final int MAX_RESET_PASSWORD_TRIES = 3;
|
private static final int MAX_RESET_PASSWORD_TRIES = 3;
|
||||||
protected static final int NO_OF_SECURITY_QUESTION = 5;
|
|
||||||
protected static final String SECURITY_QUESTION_PREFIX = "SecurityQuestion_";
|
|
||||||
private static final String RESET_PASSWORD_MAIL_TEXT_NAME = "Reset Password";
|
private static final String RESET_PASSWORD_MAIL_TEXT_NAME = "Reset Password";
|
||||||
|
|
||||||
private LoginWindow wndLogin;
|
private LoginWindow wndLogin;
|
||||||
|
@ -86,9 +83,11 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
private Label lblSecurityQuestion;
|
private Label lblSecurityQuestion;
|
||||||
private Label lblAnswer;
|
private Label lblAnswer;
|
||||||
private Label lblUserId;
|
private Label lblUserId;
|
||||||
private Combobox lstSecurityQuestion;
|
private Label lblEmail;
|
||||||
|
private Textbox txtSecurityQuestion;
|
||||||
private Textbox txtAnswer;
|
private Textbox txtAnswer;
|
||||||
private Textbox txtUserId;
|
private Textbox txtUserId;
|
||||||
|
private Textbox txtEmail;
|
||||||
|
|
||||||
public ResetPasswordPanel(Properties ctx, LoginWindow loginWindow, String userName, boolean noSecurityQuestion)
|
public ResetPasswordPanel(Properties ctx, LoginWindow loginWindow, String userName, boolean noSecurityQuestion)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +99,8 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
initComponents();
|
initComponents();
|
||||||
init();
|
init();
|
||||||
this.setId("resetPasswordPanel");
|
this.setId("resetPasswordPanel");
|
||||||
|
|
||||||
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
|
@ -145,6 +146,18 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tr = new Tr();
|
||||||
|
tr.setId("rowEmail");
|
||||||
|
table.appendChild(tr);
|
||||||
|
td = new Td();
|
||||||
|
tr.appendChild(td);
|
||||||
|
td.setSclass(ITheme.LOGIN_LABEL_CLASS);
|
||||||
|
td.appendChild(lblEmail);
|
||||||
|
td = new Td();
|
||||||
|
td.setSclass(ITheme.LOGIN_FIELD_CLASS);
|
||||||
|
tr.appendChild(td);
|
||||||
|
td.appendChild(txtEmail);
|
||||||
|
|
||||||
tr = new Tr();
|
tr = new Tr();
|
||||||
tr.setId("rowSecurityQuestion");
|
tr.setId("rowSecurityQuestion");
|
||||||
table.appendChild(tr);
|
table.appendChild(tr);
|
||||||
|
@ -155,7 +168,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
td = new Td();
|
td = new Td();
|
||||||
td.setSclass(ITheme.LOGIN_FIELD_CLASS);
|
td.setSclass(ITheme.LOGIN_FIELD_CLASS);
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
td.appendChild(lstSecurityQuestion);
|
td.appendChild(txtSecurityQuestion);
|
||||||
|
|
||||||
tr = new Tr();
|
tr = new Tr();
|
||||||
tr.setId("rowAnswer");
|
tr.setId("rowAnswer");
|
||||||
|
@ -200,6 +213,10 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
lblEmail = new Label();
|
||||||
|
lblEmail.setId("lblEmail");
|
||||||
|
lblEmail.setValue(Msg.getMsg(m_ctx, "EMail"));
|
||||||
|
|
||||||
lblSecurityQuestion = new Label();
|
lblSecurityQuestion = new Label();
|
||||||
lblSecurityQuestion.setId("lblSecurityQuestion");
|
lblSecurityQuestion.setId("lblSecurityQuestion");
|
||||||
lblSecurityQuestion.setValue(Msg.getMsg(m_ctx, "SecurityQuestion"));
|
lblSecurityQuestion.setValue(Msg.getMsg(m_ctx, "SecurityQuestion"));
|
||||||
|
@ -208,16 +225,19 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
lblAnswer.setId("lblAnswer");
|
lblAnswer.setId("lblAnswer");
|
||||||
lblAnswer.setValue(Msg.getMsg(m_ctx, "Answer"));
|
lblAnswer.setValue(Msg.getMsg(m_ctx, "Answer"));
|
||||||
|
|
||||||
lstSecurityQuestion = new Combobox();
|
txtEmail = new Textbox();
|
||||||
lstSecurityQuestion.setAutocomplete(true);
|
txtEmail.setId("txtEmail");
|
||||||
lstSecurityQuestion.setAutodrop(true);
|
txtEmail.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtEmail.getId());
|
||||||
lstSecurityQuestion.setId("lstSecurityQuestion");
|
txtEmail.setCols(25);
|
||||||
lstSecurityQuestion.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + lstSecurityQuestion.getId());
|
txtEmail.setWidth("220px");
|
||||||
lstSecurityQuestion.setWidth("220px");
|
txtEmail.setReadonly(false);
|
||||||
|
|
||||||
lstSecurityQuestion.getItems().clear();
|
txtSecurityQuestion = new Textbox();
|
||||||
for (int i = 1; i <= NO_OF_SECURITY_QUESTION; i++)
|
txtSecurityQuestion.setId("txtSecurityQuestion");
|
||||||
lstSecurityQuestion.appendItem(Msg.getMsg(m_ctx, SECURITY_QUESTION_PREFIX + i), SECURITY_QUESTION_PREFIX + i);
|
txtSecurityQuestion.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtSecurityQuestion.getId());
|
||||||
|
txtSecurityQuestion.setCols(25);
|
||||||
|
txtSecurityQuestion.setWidth("220px");
|
||||||
|
txtSecurityQuestion.setReadonly(true);
|
||||||
|
|
||||||
txtAnswer = new Textbox();
|
txtAnswer = new Textbox();
|
||||||
txtAnswer.setId("txtAnswer");
|
txtAnswer.setId("txtAnswer");
|
||||||
|
@ -225,13 +245,48 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
txtAnswer.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtAnswer.getId());
|
txtAnswer.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtAnswer.getId());
|
||||||
txtAnswer.setCols(25);
|
txtAnswer.setCols(25);
|
||||||
txtAnswer.setWidth("220px");
|
txtAnswer.setWidth("220px");
|
||||||
|
txtAnswer.setReadonly(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadData()
|
||||||
|
{
|
||||||
|
boolean email_login = MSysConfig.getBooleanValue(MSysConfig.USE_EMAIL_FOR_LOGIN, false);
|
||||||
|
if (email_login)
|
||||||
|
{
|
||||||
|
txtEmail.setText(m_userName);
|
||||||
|
loadSecurityQuestion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSecurityQuestion()
|
||||||
|
{
|
||||||
|
String email = txtEmail.getValue();
|
||||||
|
if (Util.isEmpty(email))
|
||||||
|
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "FillMandatory") + " " + lblEmail.getValue());
|
||||||
|
|
||||||
|
// Assume user with same email uses the same password and security question
|
||||||
|
StringBuilder sql = new StringBuilder("SELECT SecurityQuestion ");
|
||||||
|
sql.append("FROM AD_User ");
|
||||||
|
sql.append("WHERE IsActive='Y' ");
|
||||||
|
sql.append("AND EMail=? ");
|
||||||
|
sql.append("AND SecurityQuestion IS NOT NULL ");
|
||||||
|
sql.append("ORDER BY AD_Client_ID DESC");
|
||||||
|
|
||||||
|
String securityQuestion = DB.getSQLValueString(null, sql.toString(), email);
|
||||||
|
txtSecurityQuestion.setValue(securityQuestion);
|
||||||
|
|
||||||
|
txtEmail.setReadonly(true);
|
||||||
|
txtAnswer.setReadonly(false);
|
||||||
|
}
|
||||||
|
|
||||||
public void onEvent(Event event)
|
public void onEvent(Event event)
|
||||||
{
|
{
|
||||||
if (event.getTarget().getId().equals(ConfirmPanel.A_OK))
|
if (event.getTarget().getId().equals(ConfirmPanel.A_OK))
|
||||||
{
|
{
|
||||||
|
if (txtAnswer.isReadonly())
|
||||||
|
validateEmail();
|
||||||
|
else
|
||||||
validateResetPassword();
|
validateResetPassword();
|
||||||
}
|
}
|
||||||
else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL))
|
else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL))
|
||||||
|
@ -241,7 +296,36 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateResetPassword()
|
private void validateEmail()
|
||||||
|
{
|
||||||
|
String email = txtEmail.getValue();
|
||||||
|
if (Util.isEmpty(email))
|
||||||
|
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "FillMandatory") + " " + lblEmail.getValue());
|
||||||
|
|
||||||
|
StringBuilder whereClause = new StringBuilder("Password IS NOT NULL ");
|
||||||
|
whereClause.append("AND COALESCE(LDAPUser,Name)=? ");
|
||||||
|
whereClause.append("AND EMail=? ");
|
||||||
|
whereClause.append(" AND")
|
||||||
|
.append(" EXISTS (SELECT * FROM AD_User_Roles ur")
|
||||||
|
.append(" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID)")
|
||||||
|
.append(" WHERE ur.AD_User_ID=AD_User.AD_User_ID AND ur.IsActive='Y' AND r.IsActive='Y') AND ")
|
||||||
|
.append(" EXISTS (SELECT * FROM AD_Client c")
|
||||||
|
.append(" WHERE c.AD_Client_ID=AD_User.AD_Client_ID")
|
||||||
|
.append(" AND c.IsActive='Y') AND ")
|
||||||
|
.append(" AD_User.IsActive='Y'");
|
||||||
|
|
||||||
|
List<MUser> users = new Query(m_ctx, MUser.Table_Name, whereClause.toString(), null)
|
||||||
|
.setParameters(m_userName, email)
|
||||||
|
.setOrderBy(MUser.COLUMNNAME_AD_User_ID)
|
||||||
|
.list();
|
||||||
|
|
||||||
|
if (users.size() == 0)
|
||||||
|
throw new AdempiereException(Msg.getMsg(m_ctx, "InvalidUserNameAndEmail"));
|
||||||
|
|
||||||
|
loadSecurityQuestion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateResetPassword()
|
||||||
{
|
{
|
||||||
List<MUser> users = null;
|
List<MUser> users = null;
|
||||||
if (m_noSecurityQuestion)
|
if (m_noSecurityQuestion)
|
||||||
|
@ -278,10 +362,8 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String securityQuestion = null;
|
String email = txtEmail.getValue();
|
||||||
if (lstSecurityQuestion.getSelectedItem() != null)
|
String securityQuestion = txtSecurityQuestion.getValue();
|
||||||
securityQuestion = (String) lstSecurityQuestion.getSelectedItem().getValue();
|
|
||||||
|
|
||||||
String answer = txtAnswer.getValue();
|
String answer = txtAnswer.getValue();
|
||||||
|
|
||||||
if (Util.isEmpty(securityQuestion))
|
if (Util.isEmpty(securityQuestion))
|
||||||
|
@ -290,12 +372,8 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
if (Util.isEmpty(answer))
|
if (Util.isEmpty(answer))
|
||||||
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "AnswerMandatory"));
|
throw new IllegalArgumentException(Msg.getMsg(m_ctx, "AnswerMandatory"));
|
||||||
|
|
||||||
boolean email_login = MSysConfig.getBooleanValue(MSysConfig.USE_EMAIL_FOR_LOGIN, false);
|
|
||||||
StringBuilder whereClause = new StringBuilder("Password IS NOT NULL AND ");
|
StringBuilder whereClause = new StringBuilder("Password IS NOT NULL AND ");
|
||||||
if (email_login)
|
|
||||||
whereClause.append("EMail=?");
|
whereClause.append("EMail=?");
|
||||||
else
|
|
||||||
whereClause.append("COALESCE(LDAPUser,Name)=?");
|
|
||||||
whereClause.append(" AND")
|
whereClause.append(" AND")
|
||||||
.append(" EXISTS (SELECT * FROM AD_User_Roles ur")
|
.append(" EXISTS (SELECT * FROM AD_User_Roles ur")
|
||||||
.append(" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID)")
|
.append(" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID)")
|
||||||
|
@ -308,7 +386,7 @@ public class ResetPasswordPanel extends Window implements EventListener<Event>
|
||||||
.append(" AND AD_User.Answer=?");
|
.append(" AND AD_User.Answer=?");
|
||||||
|
|
||||||
users = new Query(m_ctx, MUser.Table_Name, whereClause.toString(), null)
|
users = new Query(m_ctx, MUser.Table_Name, whereClause.toString(), null)
|
||||||
.setParameters(m_userName, securityQuestion, answer)
|
.setParameters(email, securityQuestion, answer)
|
||||||
.setOrderBy(MUser.COLUMNNAME_AD_User_ID)
|
.setOrderBy(MUser.COLUMNNAME_AD_User_ID)
|
||||||
.list();
|
.list();
|
||||||
}
|
}
|
||||||
|
@ -358,7 +436,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();
|
||||||
throw new AdempiereException("Failed to send email to user - " + user.getEMail());
|
throw new AdempiereException(Msg.getMsg(m_ctx, "RequestActionEMailError") + ": " + user.getEMail());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue