From f1860fa2ce05e9c8c96f7f887a97c075648a06e9 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 12 Sep 2012 18:18:34 +0800 Subject: [PATCH 1/4] IDEMPIERE-369 Master Detail layout improvements. First step - remove existing embedded tab implementation. --- .../webui/component/AbstractADTab.java | 2 +- .../webui/component/CWindowToolbar.java | 52 +--- .../org/adempiere/webui/panel/ADTabpanel.java | 151 ----------- .../adempiere/webui/panel/ADWindowPanel.java | 66 ++--- .../webui/panel/AbstractADWindowPanel.java | 250 +++++------------- .../adempiere/webui/panel/StatusBarPanel.java | 53 ++-- 6 files changed, 118 insertions(+), 456 deletions(-) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/AbstractADTab.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/AbstractADTab.java index 12c7a9cbe7..31e9727607 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/AbstractADTab.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/AbstractADTab.java @@ -135,7 +135,7 @@ public abstract class AbstractADTab extends AbstractUIPart implements IADTab private void prepareContext(int newIndex, IADTabpanel newTab) { //update context - if (newTab != null && (adWindowPanel == null || !adWindowPanel.isEmbedded())) + if (newTab != null) { List parents = new ArrayList(); //get parent list, always include first tab (0) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java index 7d6e72b356..14bd500e44 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java @@ -61,8 +61,6 @@ public class CWindowToolbar extends FToolbar implements EventListener private static final String BTNPREFIX = "Btn"; - private static final String EMBEDDED_TOOLBAR_BUTTON_STYLE = "background-color: transparent; display:inline-block; margin-left: 1px; margin-right: 1px; width: 20px; height: 18px;"; - private static CLogger log = CLogger.getCLogger(CWindowToolbar.class); private ToolBarButton btnIgnore; @@ -101,8 +99,6 @@ public class CWindowToolbar extends FToolbar implements EventListener private Map altKeyMap = new HashMap(); private Map ctrlKeyMap = new HashMap(); - private boolean embedded; - // Elaine 2008/12/04 /** Show Personal Lock */ public boolean isPersonalLock = MRole.getDefault().isPersonalLock(); @@ -120,17 +116,10 @@ public class CWindowToolbar extends FToolbar implements EventListener public CWindowToolbar() { - this(false); + this(0); } - public CWindowToolbar(boolean embedded) - { - this.embedded = embedded; - init(); - } - - public CWindowToolbar(boolean embedded, int windowNo) { - this.embedded = embedded; + public CWindowToolbar(int windowNo) { setWindowNo(windowNo); init(); } @@ -197,20 +186,7 @@ public class CWindowToolbar extends FToolbar implements EventListener configureKeyMap(); - if (embedded) - { - btnParentRecord.setVisible(false); - btnDetailRecord.setVisible(false); - btnActiveWorkflows.setVisible(false); - btnProductInfo.setVisible(false); - setAlign("end"); - setWidth("100%"); - setStyle("background: transparent none; "); - } - else - { - setWidth("100%"); - } + setWidth("100%"); } @@ -219,20 +195,13 @@ public class CWindowToolbar extends FToolbar implements EventListener ToolBarButton btn = new ToolBarButton(""); btn.setName(BTNPREFIX+name); if (windowNo > 0) - btn.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + btn.getName() + "_" + windowNo + (embedded ? "E" : "")); + btn.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + btn.getName() + "_" + windowNo); else btn.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, btn.getName()); - btn.setImage("/images/"+image + (embedded ? "16.png" : "24.png")); + btn.setImage("/images/"+image + "24.png"); btn.setTooltiptext(Msg.getMsg(Env.getCtx(),tooltip)); - if (embedded) - { - btn.setStyle(EMBEDDED_TOOLBAR_BUTTON_STYLE); - btn.setSclass("embedded-toolbar-button"); - } - else - { - btn.setSclass("toolbar-button"); - } + btn.setSclass("toolbar-button"); + buttons.put(name, btn); this.appendChild(btn); //make toolbar button last to receive focus @@ -310,10 +279,7 @@ public class CWindowToolbar extends FToolbar implements EventListener protected void addSeparator() { Space s = new Space(); - if (embedded) - s.setSpacing("3px"); - else - s.setSpacing("6px"); + s.setSpacing("6px"); s.setOrient("vertical"); this.appendChild(s); } @@ -505,7 +471,7 @@ public class CWindowToolbar extends FToolbar implements EventListener { this.btnLock.setPressed(locked); - String imgURL = "/images/"+ (this.btnLock.isPressed() ? "LockX" : "Lock") + (embedded ? "16.png" : "24.png"); + String imgURL = "/images/"+ (this.btnLock.isPressed() ? "LockX" : "Lock") + "24.png"; this.btnLock.setImage(imgURL); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java index a6fc1224d1..0bb4fe591a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java @@ -23,7 +23,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Properties; import java.util.logging.Level; import org.adempiere.webui.LayoutUtils; @@ -146,8 +145,6 @@ DataStatusListener, IADTabpanel private Map includedTab = new HashMap(); private Map includedTabFooter = new HashMap(); - private List includedPanel = new ArrayList(); - private boolean active = false; private Group currentGroup; @@ -335,14 +332,6 @@ DataStatusListener, IADTabpanel row.appendChild(new Separator()); rows.appendChild(row); - for (EmbeddedPanel ep : includedPanel) { - if (ep.adTabId == field.getIncluded_Tab_ID()) { - ep.group = includedTab.get(ep.adTabId); - createEmbeddedPanelUI(ep, field.getDisplayLength()); - break; - } - } - row = new Row(); continue; } @@ -759,27 +748,11 @@ DataStatusListener, IADTabpanel } } - //activate embedded panel - for(EmbeddedPanel ep : includedPanel) - { - activateChild(activate, ep); - } - if (gridTab.getRecord_ID() > 0 && gridTab.isTreeTab() && treePanel != null) { setSelectedNode(gridTab.getRecord_ID()); } } - private void activateChild(boolean activate, EmbeddedPanel panel) { - if (activate) - { - panel.windowPanel.getADTab().evaluate(null); - panel.windowPanel.getADTab().setSelectedIndex(0); - panel.tabPanel.query(false, 0, 0); - } - panel.tabPanel.activate(activate); - } - /** * set focus to first active editor */ @@ -928,27 +901,6 @@ DataStatusListener, IADTabpanel listPanel.updateListIndex(); listPanel.dynamicDisplay(col); } - - if (!includedPanel.isEmpty() && e.getChangedColumn() == -1) { - ArrayList parentColumnNames = new ArrayList(); - GridField[] parentFields = gridTab.getFields(); - for (GridField parentField : parentFields) - parentColumnNames.add(parentField.getColumnName()); - - for (EmbeddedPanel panel : includedPanel) - { - GridTab tab = panel.tabPanel.getGridTab(); - GridField[] fields = tab.getFields(); - for (GridField field : fields) - { - if (!parentColumnNames.contains(field.getColumnName())) - Env.setContext(Env.getCtx(), field.getWindowNo(), field.getColumnName(), ""); - } - panel.tabPanel.query(false, 0, 0); - } - - parentColumnNames = null; - } } private void deleteNode(int recordId) { @@ -1029,18 +981,8 @@ DataStatusListener, IADTabpanel public void switchRowPresentation() { if (formComponent.isVisible()) { formComponent.setVisible(false); - //de-activate embedded panel - for(EmbeddedPanel ep : includedPanel) - { - activateChild(false, ep); - } } else { formComponent.setVisible(true); - //activate embedded panel - for(EmbeddedPanel ep : includedPanel) - { - activateChild(true, ep); - } formComponent.getParent().invalidate(); } listPanel.setVisible(!formComponent.isVisible()); @@ -1069,89 +1011,10 @@ DataStatusListener, IADTabpanel } - /** - * Embed detail tab - * @param ctx - * @param windowNo - * @param gridWindow - * @param adTabId - * @param tabIndex - * @param tabPanel - */ - public void embed(Properties ctx, int windowNo, GridWindow gridWindow, - int adTabId, int tabIndex, IADTabpanel tabPanel) { - embed(ctx, windowNo, gridWindow, adTabId, tabIndex, tabPanel, 0); - } - - /** - * Embed detail tab - * @param ctx - * @param windowNo - * @param gridWindow - * @param adTabId - * @param tabIndex - * @param tabPanel - */ - public void embed(Properties ctx, int windowNo, GridWindow gridWindow, - int adTabId, int tabIndex, IADTabpanel tabPanel, int height) { - EmbeddedPanel ep = new EmbeddedPanel(); - ep.tabPanel = tabPanel; - ep.adTabId = adTabId; - ep.tabIndex = tabIndex; - ep.gridWindow = gridWindow; - includedPanel.add(ep); - Group group = includedTab.get(adTabId); - ep.group = group; - if (tabPanel instanceof ADTabpanel) { - ADTabpanel atp = (ADTabpanel) tabPanel; - atp.listPanel.setPageSize(-1); - } - ADWindowPanel panel = new ADWindowPanel(ctx, windowNo, gridWindow, tabIndex, tabPanel); - ep.windowPanel = panel; - - if (group != null) { - createEmbeddedPanelUI(ep, height); - if (active) - activateChild(true, ep); - } - } - - class EmbeddedPanel { - Group group; - GridWindow gridWindow; - int tabIndex; - ADWindowPanel windowPanel; - IADTabpanel tabPanel; - int adTabId; - } - /** * @see IADTabpanel#afterSave(boolean) */ public void afterSave(boolean onSaveEvent) { - if (!includedPanel.isEmpty()) { - for (EmbeddedPanel panel : includedPanel) - panel.tabPanel.query(false, 0, 0); - } - } - - private void createEmbeddedPanelUI(EmbeddedPanel ep, int height) { - Row row = new Row(); - row.setSpans("5"); - grid.getRows().insertBefore(row, includedTabFooter.get(ep.adTabId)); - ep.windowPanel.createPart(row); - ep.windowPanel.getComponent().setWidth("100%"); - ep.windowPanel.getComponent().setStyle("position: relative;"); - //for backward compatibility, only treat display length > 50 as height for the embedded panel - if (height > 50) - ep.windowPanel.getComponent().setHeight(height + "px"); - else - ep.windowPanel.getComponent().setHeight("400px"); - - Label title = new Label(ep.gridWindow.getTab(ep.tabIndex).getName()); - ep.group.appendChild(title); - ep.group.appendChild(ep.windowPanel.getToolbar()); - ep.windowPanel.initPanel(-1, null); } @Override @@ -1196,20 +1059,6 @@ DataStatusListener, IADTabpanel return listPanel.isVisible(); } - /** - * @param gTab - * @return embedded panel or null if not found - */ - public IADTabpanel findEmbeddedPanel(GridTab gTab) { - IADTabpanel panel = null; - for(EmbeddedPanel ep : includedPanel) { - if (ep.tabPanel.getGridTab().equals(gTab)) { - return ep.tabPanel; - } - } - return panel; - } - /** * * @return GridPanel diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java index 059eb78136..14b05a7882 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java @@ -35,7 +35,6 @@ import org.adempiere.webui.component.Tabs; import org.adempiere.webui.part.ITabOnSelectHandler; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.UserPreference; -import org.compiere.model.GridWindow; import org.compiere.model.MQuery; import org.compiere.util.CLogger; import org.compiere.util.Env; @@ -86,12 +85,6 @@ public class ADWindowPanel extends AbstractADWindowPanel } - public ADWindowPanel(Properties ctx, int windowNo, GridWindow gridWindow, - int tabIndex, IADTabpanel tabPanel) { - super(ctx, windowNo, gridWindow, tabIndex, tabPanel); - } - - protected Component doCreatePart(Component parent) { layout = new Borderlayout(); @@ -102,37 +95,24 @@ public class ADWindowPanel extends AbstractADWindowPanel layout.setPage(page); } - //toolbar would be added to group for embedded tab - if (!isEmbedded()) - { - North n = new North(); - n.setParent(layout); - n.setCollapsible(false); - n.setSclass("adwindow-north"); - toolbar.setParent(n); - toolbar.setWindowNo(getWindowNo()); - } + //toolbar + North n = new North(); + n.setParent(layout); + n.setCollapsible(false); + n.setSclass("adwindow-north"); + toolbar.setParent(n); + toolbar.setWindowNo(getWindowNo()); - //status bar on top for embedded tab - if (!isEmbedded()) - { - South s = new South(); - layout.appendChild(s); - s.setCollapsible(false); - s.setSclass("adwindow-south"); - statusBar.setParent(s); - } - else - { - North n = new North(); - layout.appendChild(n); - n.setCollapsible(false); - statusBar.setParent(n); - } + //status bar + South s = new South(); + layout.appendChild(s); + s.setCollapsible(false); + s.setSclass("adwindow-south"); + statusBar.setParent(s); LayoutUtils.addSclass("adwindow-status", statusBar); - if (!isEmbedded() && adTab.isUseExternalSelection()) + if (adTab.isUseExternalSelection()) { String tabPlacement = SessionManager.getSessionApplication().getUserPreference().getProperty(UserPreference.P_WINDOW_TAB_PLACEMENT); if (tabPlacement == null || "left".equalsIgnoreCase(tabPlacement)) @@ -183,16 +163,14 @@ public class ADWindowPanel extends AbstractADWindowPanel ((Tabpanel)parent).setOnCloseHandler(handler); } - if (!isEmbedded()) { - if (keyListener != null) - keyListener.detach(); - keyListener = new Keylistener(); - statusBar.appendChild(keyListener); - keyListener.setCtrlKeys("#f1#f2#f3#f4#f5#f6#f7#f8#f9#f10#f11#f12^f^i^n^s^d@#left@#right@#up@#down@#pgup@#pgdn@p^p@z@x#enter"); - keyListener.addEventListener(Events.ON_CTRL_KEY, toolbar); - keyListener.addEventListener(Events.ON_CTRL_KEY, this); - keyListener.setAutoBlur(false); - } + if (keyListener != null) + keyListener.detach(); + keyListener = new Keylistener(); + statusBar.appendChild(keyListener); + keyListener.setCtrlKeys("#f1#f2#f3#f4#f5#f6#f7#f8#f9#f10#f11#f12^f^i^n^s^d@#left@#right@#up@#down@#pgup@#pgdn@p^p@z@x#enter"); + keyListener.addEventListener(Events.ON_CTRL_KEY, toolbar); + keyListener.addEventListener(Events.ON_CTRL_KEY, this); + keyListener.setAutoBlur(false); layout.setAttribute(ITabOnSelectHandler.ATTRIBUTE_KEY, new ITabOnSelectHandler() { public void onSelect() { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java index 7db0b7384b..a5d7d12311 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java @@ -168,46 +168,19 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To private boolean m_findCancelled; - private int embeddedTabindex = -1; - - protected Map includedMap = new HashMap(); - - protected Map includedFieldMap = new HashMap(); - - private IADTabpanel embeddedTabPanel; - private boolean m_findCreateNew; private boolean m_queryInitiating; /** - * Constructor for non-embedded mode + * Constructor * @param ctx * @param windowNo */ public AbstractADWindowPanel(Properties ctx, int windowNo) - { - this(ctx, windowNo, null, -1, null); - } - - /** - * Constructor for embedded mode - * @param ctx - * @param windowNo - * @param gridWindow - * @param tabIndex - * @param tabPanel - */ - public AbstractADWindowPanel(Properties ctx, int windowNo, GridWindow gridWindow, int tabIndex, IADTabpanel tabPanel) { this.ctx = ctx; this.curWindowNo = windowNo; - this.gridWindow = gridWindow; - this.embeddedTabindex = tabIndex; - this.embeddedTabPanel = tabPanel; - curTabpanel = tabPanel; - if (gridWindow != null && tabIndex >= 0) - curTab = gridWindow.getTab(tabIndex); initComponents(); } @@ -236,20 +209,13 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To return statusBar; } - /** - * @return boolean - */ - public boolean isEmbedded() { - return embeddedTabindex >= 0; - } - private void initComponents() { /** Initalise toolbar */ - toolbar = new CWindowToolbar(isEmbedded(), getWindowNo()); + toolbar = new CWindowToolbar(getWindowNo()); toolbar.addListener(this); - statusBar = new StatusBarPanel(isEmbedded()); + statusBar = new StatusBarPanel(); } /** @@ -294,88 +260,69 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To // End of temporary code for [ adempiere-ZK Web Client-2832968 ] User context lost? // Set AutoCommit for this Window - if (embeddedTabindex < 0) - { - Env.setAutoCommit(ctx, curWindowNo, Env.isAutoCommit(ctx)); - boolean autoNew = Env.isAutoNew(ctx); - Env.setAutoNew(ctx, curWindowNo, autoNew); + Env.setAutoCommit(ctx, curWindowNo, Env.isAutoCommit(ctx)); + boolean autoNew = Env.isAutoNew(ctx); + Env.setAutoNew(ctx, curWindowNo, autoNew); - GridWindowVO gWindowVO = AEnv.getMWindowVO(curWindowNo, adWindowId, 0); - if (gWindowVO == null) - { - throw new ApplicationException(Msg.getMsg(ctx, - "AccessTableNoView") - + "(No Window Model Info)"); - } - gridWindow = new GridWindow(gWindowVO, true); - title = gridWindow.getName(); + GridWindowVO gWindowVO = AEnv.getMWindowVO(curWindowNo, adWindowId, 0); + if (gWindowVO == null) + { + throw new ApplicationException(Msg.getMsg(ctx, + "AccessTableNoView") + + "(No Window Model Info)"); + } + gridWindow = new GridWindow(gWindowVO, true); + title = gridWindow.getName(); - // Set AutoNew for Window - if (!autoNew && gridWindow.isTransaction()) - { - Env.setAutoNew(ctx, curWindowNo, true); - } - } + // Set AutoNew for Window + if (!autoNew && gridWindow.isTransaction()) + { + Env.setAutoNew(ctx, curWindowNo, true); + } - m_onlyCurrentRows = embeddedTabindex < 0 && gridWindow.isTransaction(); + m_onlyCurrentRows = gridWindow.isTransaction(); MQuery detailQuery = null; /** * Window Tabs */ - if (embeddedTabindex < 0) + if (query != null && query.getZoomTableName() != null && query.getZoomColumnName() != null + && query.getZoomValue() instanceof Integer && (Integer)query.getZoomValue() > 0) + { + if (!query.getZoomTableName().equalsIgnoreCase(gridWindow.getTab(0).getTableName())) + { + detailQuery = query; + query = new MQuery(); + query.addRestriction("1=2"); + query.setRecordCount(0); + } + } + + int tabSize = gridWindow.getTabCount(); + + for (int tab = 0; tab < tabSize; tab++) { - if (query != null && query.getZoomTableName() != null && query.getZoomColumnName() != null - && query.getZoomValue() instanceof Integer && (Integer)query.getZoomValue() > 0) - { - if (!query.getZoomTableName().equalsIgnoreCase(gridWindow.getTab(0).getTableName())) - { - detailQuery = query; - query = new MQuery(); - query.addRestriction("1=2"); - query.setRecordCount(0); - } - } - - int tabSize = gridWindow.getTabCount(); - - for (int tab = 0; tab < tabSize; tab++) - { - initTab(query, tab); - if (tab == 0 && curTab == null && m_findCancelled) - return false; - } - Env.setContext(ctx, curWindowNo, "WindowName", gridWindow.getName()); + initTab(query, tab); + if (tab == 0 && curTab == null && m_findCancelled) + return false; } - else - { - initEmbeddedTab(query, embeddedTabindex); - } - + Env.setContext(ctx, curWindowNo, "WindowName", gridWindow.getName()); + if (curTab != null) curTab.getTableModel().setChanged(false); - if (embeddedTabindex < 0) - { - curTabIndex = 0; + curTabIndex = 0; - adTab.setSelectedIndex(0); - // all fields context for window is clear at AbstractADTab.prepareContext, set IsSOTrx for window - Env.setContext(ctx, curWindowNo, "IsSOTrx", gridWindow.isSOTrx()); - toolbar.enableTabNavigation(adTab.getTabCount() > 1); - toolbar.enableFind(true); - adTab.evaluate(null); + adTab.setSelectedIndex(0); + // all fields context for window is clear at AbstractADTab.prepareContext, set IsSOTrx for window + Env.setContext(ctx, curWindowNo, "IsSOTrx", gridWindow.isSOTrx()); + toolbar.enableTabNavigation(adTab.getTabCount() > 1); + toolbar.enableFind(true); + adTab.evaluate(null); - if (detailQuery != null && zoomToDetailTab(detailQuery)) - { - return true; - } - } - else + if (detailQuery != null && zoomToDetailTab(detailQuery)) { - curTabIndex = embeddedTabindex; - toolbar.enableTabNavigation(false); - toolbar.enableFind(true); + return true; } updateToolbar(); @@ -471,15 +418,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To targetQuery.addRestriction(gTab.getLinkColumnName(), "=", parentId); gTab.setQuery(targetQuery); IADTabpanel gc = null; - if (!includedMap.containsKey(gTab.getAD_Tab_ID())) - { - gc = adTab.findADTabpanel(gTab); - } - else - { - ADTabpanel parent = (ADTabpanel)includedMap.get(gTab.getAD_Tab_ID()); - gc = parent.findEmbeddedPanel(gTab); - } + gc = adTab.findADTabpanel(gTab); gc.createUI(); gc.query(false, 0, 0); @@ -490,17 +429,7 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To int id = table.getKeyID(i); if (id == ((Integer)query.getZoomValue()).intValue()) { - if (!includedMap.containsKey(gTab.getAD_Tab_ID())) - { - setActiveTab(gridWindow.getTabIndex(gTab), null); - } - else - { - IADTabpanel parent = includedMap.get(gTab.getAD_Tab_ID()); - int pindex = gridWindow.getTabIndex(parent.getGridTab()); - if (pindex >= 0) - setActiveTab(pindex, null); - } + setActiveTab(gridWindow.getTabIndex(gTab), null); gTab.navigate(i); return true; } @@ -511,17 +440,6 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To return false; } - private void initEmbeddedTab(MQuery query, int tabIndex) { - GridTab gTab = gridWindow.getTab(tabIndex); - gTab.addDataStatusListener(this); - adTab.addTab(gTab, embeddedTabPanel); - if (gTab.isSortTab()) { - ((ADSortTab)embeddedTabPanel).registerAPanel(this); - } else { - ((ADTabpanel)embeddedTabPanel).init(this, curWindowNo, gTab, gridWindow); - } - } - private void initQueryOnNew(MQuery result) { if (curTab.isHighVolume() && m_findCreateNew) onNew(); @@ -583,57 +501,31 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To if (gTab.isSortTab()) { ADSortTab sortTab = new ADSortTab(curWindowNo, gTab); - if (includedMap.containsKey(gTab.getAD_Tab_ID())) - { - includedMap.get(gTab.getAD_Tab_ID()).embed(ctx, curWindowNo, gridWindow, gTab.getAD_Tab_ID(), tabIndex, sortTab); - } - else - { - adTab.addTab(gTab, sortTab); - sortTab.registerAPanel(this); - if (tabIndex == 0) { - curTabpanel = sortTab; - curTabpanel.createUI(); - if (!m_queryInitiating) - { - initFirstTabpanel(); - } + adTab.addTab(gTab, sortTab); + sortTab.registerAPanel(this); + if (tabIndex == 0) { + curTabpanel = sortTab; + curTabpanel.createUI(); + if (!m_queryInitiating) + { + initFirstTabpanel(); } - gTab.addDataStatusListener(this); } + gTab.addDataStatusListener(this); } else { - //build embedded tab map ADTabpanel fTabPanel = new ADTabpanel(); - GridField[] fields = gTab.getTableModel().getFields(); - for(int i = 0; i < fields.length; i++) - { - if (fields[i].getIncluded_Tab_ID() > 0) - { - includedMap.put(fields[i].getIncluded_Tab_ID(), fTabPanel); - includedFieldMap.put(fields[i].getIncluded_Tab_ID(), fields[i]); - } - } - - if (includedMap.containsKey(gTab.getAD_Tab_ID())) - { - includedMap.get(gTab.getAD_Tab_ID()).embed(ctx, curWindowNo, gridWindow, gTab.getAD_Tab_ID(), tabIndex, fTabPanel, - includedFieldMap.get(gTab.getAD_Tab_ID()).getDisplayLength()); - } - else - { - gTab.addDataStatusListener(this); - fTabPanel.init(this, curWindowNo, gTab, gridWindow); - adTab.addTab(gTab, fTabPanel); - if (tabIndex == 0) { - fTabPanel.createUI(); - curTabpanel = fTabPanel; - if (!m_queryInitiating) - { - initFirstTabpanel(); - } - } + gTab.addDataStatusListener(this); + fTabPanel.init(this, curWindowNo, gTab, gridWindow); + adTab.addTab(gTab, fTabPanel); + if (tabIndex == 0) { + fTabPanel.createUI(); + curTabpanel = fTabPanel; + if (!m_queryInitiating) + { + initFirstTabpanel(); + } } if (!m_queryInitiating && tabIndex == 0) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java index 0611c03704..8f899cec75 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/StatusBarPanel.java @@ -49,7 +49,7 @@ import org.zkoss.zul.Vbox; * @date Mar 12, 2007 * @version $Revision: 0.10 $ */ -public class StatusBarPanel extends Panel implements EventListener, IStatusBar +public class StatusBarPanel extends Panel implements EventListener, IStatusBar { /** * @@ -79,20 +79,10 @@ public class StatusBarPanel extends Panel implements EventListener, IStatusBar private Div popupContent; private String popupStyle; - private boolean embedded; public StatusBarPanel() { - this(false); - } - - /** - * @param embedded - */ - public StatusBarPanel(boolean embedded) - { super(); - this.embedded = embedded; init(); } @@ -109,16 +99,10 @@ public class StatusBarPanel extends Panel implements EventListener, IStatusBar hbox.appendChild(leftCell); Cell rightCell = new Cell(); hbox.appendChild(rightCell); - if (embedded) - { - leftCell.setWidth("90%"); - rightCell.setWidth("10%"); - } - else - { - leftCell.setWidth("50%"); - rightCell.setWidth("50%"); - } + + leftCell.setWidth("50%"); + rightCell.setWidth("50%"); + west = new Div(); west.setStyle("text-align: left; "); west.appendChild(statusLine); @@ -131,17 +115,13 @@ public class StatusBarPanel extends Panel implements EventListener, IStatusBar east = new Div(); east.setWidth("100%"); east.setStyle("text-align: right; "); - if (!embedded) - { - infoLine = new Label(); - east.appendChild(infoLine); - infoLine.setVisible(false); - } + infoLine = new Label(); + east.appendChild(infoLine); + infoLine.setVisible(false); east.appendChild(statusDB); LayoutUtils.addSclass("status-db", statusDB); - if (!embedded) - LayoutUtils.addSclass("status-info", infoLine); + LayoutUtils.addSclass("status-info", infoLine); vbox = new Vbox(); vbox.setAlign("stretch"); vbox.setPack("center"); @@ -306,15 +286,12 @@ public class StatusBarPanel extends Panel implements EventListener, IStatusBar */ public void setInfo (String text) { - if (!embedded) - { - infoLine.setValue(text != null ? text : ""); - infoLine.setTooltiptext(text); - if (text == null || text.trim().length() == 0) - infoLine.setVisible(false); - else - infoLine.setVisible(true); - } + infoLine.setValue(text != null ? text : ""); + infoLine.setTooltiptext(text); + if (text == null || text.trim().length() == 0) + infoLine.setVisible(false); + else + infoLine.setVisible(true); } // setInfo public void onEvent(Event event) throws Exception { From 951765ccd0ee3fd090826e896eacfe7b7e5f5070 Mon Sep 17 00:00:00 2001 From: Elaine Tan Date: Thu, 13 Sep 2012 16:29:23 +0800 Subject: [PATCH 2/4] IDEMPIERE-375 Implement Forgot my Password - add validation to check new password differ from old password and change the security question design --- .../oracle/910_IDEMPIERE-375.sql | 36 +++++ .../postgresql/910_IDEMPIERE-375.sql | 36 +++++ .../src/org/compiere/model/MSysConfig.java | 1 + .../src/org/compiere/apps/ALogin.java | 49 ++++--- .../webui/panel/ChangePasswordPanel.java | 37 +++-- .../webui/panel/ResetPasswordPanel.java | 136 ++++++++++++++---- 6 files changed, 221 insertions(+), 74 deletions(-) create mode 100644 migration/360lts-release/oracle/910_IDEMPIERE-375.sql create mode 100644 migration/360lts-release/postgresql/910_IDEMPIERE-375.sql diff --git a/migration/360lts-release/oracle/910_IDEMPIERE-375.sql b/migration/360lts-release/oracle/910_IDEMPIERE-375.sql new file mode 100644 index 0000000000..2468a24ef1 --- /dev/null +++ b/migration/360lts-release/oracle/910_IDEMPIERE-375.sql @@ -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 +; \ No newline at end of file diff --git a/migration/360lts-release/postgresql/910_IDEMPIERE-375.sql b/migration/360lts-release/postgresql/910_IDEMPIERE-375.sql new file mode 100644 index 0000000000..9a48a4c4e3 --- /dev/null +++ b/migration/360lts-release/postgresql/910_IDEMPIERE-375.sql @@ -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 +; \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 3fcab94481..12cb81d600 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -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_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 CHANGE_PASSWORD_MUST_DIFFER = "CHANGE_PASSWORD_MUST_DIFFER"; public static final String ProductUOMConversionUOMValidate = "ProductUOMConversionUOMValidate"; public static final String ProductUOMConversionRateValidate = "ProductUOMConversionRateValidate"; public static final String SYSTEM_INSERT_CHANGELOG = "SYSTEM_INSERT_CHANGELOG"; diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/ALogin.java b/org.adempiere.ui.swing/src/org/compiere/apps/ALogin.java index 25aaad2561..3d05870ddd 100644 --- a/org.adempiere.ui.swing/src/org/compiere/apps/ALogin.java +++ b/org.adempiere.ui.swing/src/org/compiere/apps/ALogin.java @@ -120,9 +120,6 @@ public final class ALogin extends CDialog private static final int CONNECTED_OK = 0; 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 CTabbedPane loginTabPane = new CTabbedPane(); private CPanel connectionPanel = new CPanel(); @@ -169,11 +166,11 @@ public final class ALogin extends CDialog private JPasswordField txtNewPassword = new JPasswordField(); private JPasswordField txtRetypeNewPassword = new JPasswordField(); // -/* private CLabel lblSecurityQuestion = new CLabel(); + private CLabel lblSecurityQuestion = new CLabel(); private CLabel lblAnswer = new CLabel(); - private VComboBox lstSecurityQuestion = new VComboBox(); + private CTextField txtSecurityQuestion = new CTextField(); private CTextField txtAnswer = new CTextField(); -*/ + /** Server Connection */ private CConnection m_cc; /** Application User */ @@ -382,22 +379,18 @@ public final class ALogin extends CDialog lblRetypeNewPassword.setHorizontalAlignment(SwingConstants.RIGHT); lblRetypeNewPassword.setText(Msg.getMsg(m_ctx, "New Password Confirm")); -/* lstSecurityQuestion.setName("lstSecurityQuestion"); + txtSecurityQuestion.setName("txtSecurityQuestion"); lblSecurityQuestion.setRequestFocusEnabled(false); - lblSecurityQuestion.setLabelFor(lstSecurityQuestion); + lblSecurityQuestion.setLabelFor(txtSecurityQuestion); lblSecurityQuestion.setHorizontalAlignment(SwingConstants.RIGHT); 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"); lblAnswer.setRequestFocusEnabled(false); lblAnswer.setLabelFor(txtAnswer); lblAnswer.setHorizontalAlignment(SwingConstants.RIGHT); lblAnswer.setText(Msg.getMsg(m_ctx, "Answer")); -*/ + changePasswordPanel.setLayout(changePasswordPanelLayout); 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)); 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)); -/* 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)); - 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)); 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)); 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)); -*/ loginTabPane.add(changePasswordPanel, res.getString("ChangePassword")); + loginTabPane.add(changePasswordPanel, res.getString("ChangePassword")); loginTabPane.setEnabledAt(TAB_CHANGE_PASSWORD, false); // @@ -656,12 +649,9 @@ public final class ALogin extends CDialog String newPassword = new String(txtNewPassword.getPassword()); String retypeNewPassword = new String(txtRetypeNewPassword.getPassword()); -/* String securityQuestion = null; - if (lstSecurityQuestion.getSelectedItem() != null) - securityQuestion = ((ValueNamePair) lstSecurityQuestion.getSelectedItem()).getValue(); - + String securityQuestion = txtSecurityQuestion.getText(); String answer = txtAnswer.getText(); -*/ + if (Util.isEmpty(oldPassword)) { statusBar.setStatusLine(Msg.getMsg(m_ctx, "OldPasswordMandatory"), true); @@ -680,7 +670,7 @@ public final class ALogin extends CDialog return; } -/* if (Util.isEmpty(securityQuestion)) + if (Util.isEmpty(securityQuestion)) { statusBar.setStatusLine(Msg.getMsg(m_ctx, "SecurityQuestionMandatory"), true); return; @@ -691,13 +681,22 @@ public final class ALogin extends CDialog statusBar.setStatusLine(Msg.getMsg(m_ctx, "AnswerMandatory"), true); return; } -*/ + String m_userPassword = new String(m_pwd); if (!oldPassword.equals(m_userPassword)) { statusBar.setStatusLine(Msg.getMsg(m_ctx, "OldPasswordNoMatch"), true); 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; try @@ -721,9 +720,9 @@ public final class ALogin extends CDialog user.setPassword(newPassword); user.setIsExpired(false); -/* user.setSecurityQuestion(securityQuestion); + user.setSecurityQuestion(securityQuestion); user.setAnswer(answer); -*/ if (!user.save(trx.getTrxName())) + if (!user.save(trx.getTrxName())) { trx.rollback(); statusBar.setStatusLine("Could not update user", true); 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 734e325eef..49a3609304 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 @@ -20,7 +20,6 @@ import java.util.Properties; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.LayoutUtils; -import org.adempiere.webui.component.Combobox; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; 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.ThemeManager; import org.adempiere.webui.window.LoginWindow; +import org.compiere.model.MSysConfig; import org.compiere.model.MUser; import org.compiere.util.CLogger; import org.compiere.util.Env; @@ -75,10 +75,10 @@ public class ChangePasswordPanel extends Window implements EventListener private Label lblRetypeNewPassword; private Label lblSecurityQuestion; private Label lblAnswer; - private Combobox lstSecurityQuestion; private Textbox txtOldPassword; private Textbox txtNewPassword; private Textbox txtRetypeNewPassword; + private Textbox txtSecurityQuestion; private Textbox txtAnswer; 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 td = new Td(); td.setSclass(ITheme.LOGIN_FIELD_CLASS); tr.appendChild(td); - td.appendChild(lstSecurityQuestion); + td.appendChild(txtSecurityQuestion); tr = new Tr(); tr.setId("rowAnswer"); @@ -215,18 +215,7 @@ public class ChangePasswordPanel extends Window implements EventListener lblAnswer = new Label(); lblAnswer.setId("lblAnswer"); 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.setId("txtOldPassword"); txtOldPassword.setType("password"); @@ -248,6 +237,12 @@ public class ChangePasswordPanel extends Window implements EventListener txtRetypeNewPassword.setCols(25); 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.setId("txtAnswer"); // txtAnswer.setType("password"); @@ -273,12 +268,8 @@ public class ChangePasswordPanel extends Window implements EventListener { String oldPassword = txtOldPassword.getValue(); String newPassword = txtNewPassword.getValue(); - String retypeNewPassword = txtRetypeNewPassword.getValue(); - - String securityQuestion = null; - if (lstSecurityQuestion.getSelectedItem() != null) - securityQuestion = (String) lstSecurityQuestion.getSelectedItem().getValue(); - + String retypeNewPassword = txtRetypeNewPassword.getValue(); + String securityQuestion = txtSecurityQuestion.getValue(); String answer = txtAnswer.getValue(); if (Util.isEmpty(oldPassword)) @@ -298,6 +289,12 @@ public class ChangePasswordPanel extends Window implements EventListener if (!oldPassword.equals(m_userPassword)) 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; try 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 dede9b63f2..868776173f 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 @@ -23,7 +23,6 @@ import java.util.Properties; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.LayoutUtils; -import org.adempiere.webui.component.Combobox; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Textbox; @@ -67,9 +66,7 @@ public class ResetPasswordPanel extends Window implements EventListener private static CLogger logger = CLogger.getCLogger(ResetPasswordPanel.class); - 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 int MAX_RESET_PASSWORD_TRIES = 3; private static final String RESET_PASSWORD_MAIL_TEXT_NAME = "Reset Password"; private LoginWindow wndLogin; @@ -86,9 +83,11 @@ public class ResetPasswordPanel extends Window implements EventListener private Label lblSecurityQuestion; private Label lblAnswer; private Label lblUserId; - private Combobox lstSecurityQuestion; + private Label lblEmail; + private Textbox txtSecurityQuestion; private Textbox txtAnswer; private Textbox txtUserId; + private Textbox txtEmail; public ResetPasswordPanel(Properties ctx, LoginWindow loginWindow, String userName, boolean noSecurityQuestion) { @@ -100,6 +99,8 @@ public class ResetPasswordPanel extends Window implements EventListener initComponents(); init(); this.setId("resetPasswordPanel"); + + loadData(); } private void init() @@ -145,6 +146,18 @@ public class ResetPasswordPanel extends Window implements EventListener } 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.setId("rowSecurityQuestion"); table.appendChild(tr); @@ -155,7 +168,7 @@ public class ResetPasswordPanel extends Window implements EventListener td = new Td(); td.setSclass(ITheme.LOGIN_FIELD_CLASS); tr.appendChild(td); - td.appendChild(lstSecurityQuestion); + td.appendChild(txtSecurityQuestion); tr = new Tr(); tr.setId("rowAnswer"); @@ -200,6 +213,10 @@ public class ResetPasswordPanel extends Window implements EventListener } else { + lblEmail = new Label(); + lblEmail.setId("lblEmail"); + lblEmail.setValue(Msg.getMsg(m_ctx, "EMail")); + lblSecurityQuestion = new Label(); lblSecurityQuestion.setId("lblSecurityQuestion"); lblSecurityQuestion.setValue(Msg.getMsg(m_ctx, "SecurityQuestion")); @@ -208,16 +225,19 @@ public class ResetPasswordPanel extends Window implements EventListener lblAnswer.setId("lblAnswer"); 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"); + txtEmail = new Textbox(); + txtEmail.setId("txtEmail"); + txtEmail.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtEmail.getId()); + txtEmail.setCols(25); + txtEmail.setWidth("220px"); + txtEmail.setReadonly(false); - lstSecurityQuestion.getItems().clear(); - for (int i = 1; i <= NO_OF_SECURITY_QUESTION; i++) - lstSecurityQuestion.appendItem(Msg.getMsg(m_ctx, SECURITY_QUESTION_PREFIX + i), SECURITY_QUESTION_PREFIX + i); + txtSecurityQuestion = new Textbox(); + txtSecurityQuestion.setId("txtSecurityQuestion"); + txtSecurityQuestion.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtSecurityQuestion.getId()); + txtSecurityQuestion.setCols(25); + txtSecurityQuestion.setWidth("220px"); + txtSecurityQuestion.setReadonly(true); txtAnswer = new Textbox(); txtAnswer.setId("txtAnswer"); @@ -225,14 +245,49 @@ public class ResetPasswordPanel extends Window implements EventListener txtAnswer.setAttribute(AdempiereIdGenerator.ZK_COMPONENT_PREFIX_ATTRIBUTE, "unq" + txtAnswer.getId()); txtAnswer.setCols(25); 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) { if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) { - validateResetPassword(); + if (txtAnswer.isReadonly()) + validateEmail(); + else + validateResetPassword(); } else if (event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { @@ -241,7 +296,36 @@ public class ResetPasswordPanel extends Window implements EventListener } } - 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 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 users = null; if (m_noSecurityQuestion) @@ -278,10 +362,8 @@ public class ResetPasswordPanel extends Window implements EventListener } else { - String securityQuestion = null; - if (lstSecurityQuestion.getSelectedItem() != null) - securityQuestion = (String) lstSecurityQuestion.getSelectedItem().getValue(); - + String email = txtEmail.getValue(); + String securityQuestion = txtSecurityQuestion.getValue(); String answer = txtAnswer.getValue(); if (Util.isEmpty(securityQuestion)) @@ -290,12 +372,8 @@ public class ResetPasswordPanel extends Window implements EventListener if (Util.isEmpty(answer)) 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 "); - if (email_login) - whereClause.append("EMail=?"); - else - whereClause.append("COALESCE(LDAPUser,Name)=?"); + whereClause.append("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)") @@ -308,7 +386,7 @@ public class ResetPasswordPanel extends Window implements EventListener .append(" AND AD_User.Answer=?"); 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) .list(); } @@ -358,7 +436,7 @@ public class ResetPasswordPanel extends Window implements EventListener if (errorMsg.length() > 0) errorMsg += ", "; errorMsg += user.getEMail(); - throw new AdempiereException("Failed to send email to user - " + user.getEMail()); + throw new AdempiereException(Msg.getMsg(m_ctx, "RequestActionEMailError") + ": " + user.getEMail()); } } From 4403c3bb68de0e0d6eb45fae66c6a4e661ad9460 Mon Sep 17 00:00:00 2001 From: Elaine Tan Date: Thu, 13 Sep 2012 17:19:11 +0800 Subject: [PATCH 3/4] IDEMPIERE-375 Implement Forgot my Password - fix NPE --- .../src/org/adempiere/webui/panel/ResetPasswordPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 868776173f..bfb591318d 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 @@ -284,7 +284,7 @@ public class ResetPasswordPanel extends Window implements EventListener { if (event.getTarget().getId().equals(ConfirmPanel.A_OK)) { - if (txtAnswer.isReadonly()) + if (txtAnswer != null && txtAnswer.isReadonly()) validateEmail(); else validateResetPassword(); From cdf2d1ef07f68496a2a95b7e8718b423c000f952 Mon Sep 17 00:00:00 2001 From: Elaine Tan Date: Thu, 13 Sep 2012 17:59:14 +0800 Subject: [PATCH 4/4] IDEMPIERE-375 Implement Forgot my Password - fix the query to load security question --- .../org/adempiere/webui/panel/ResetPasswordPanel.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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 bfb591318d..6b089d1d70 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 @@ -265,15 +265,20 @@ public class ResetPasswordPanel extends Window implements EventListener 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 + // TODO: Validation for 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' "); + boolean email_login = MSysConfig.getBooleanValue(MSysConfig.USE_EMAIL_FOR_LOGIN, false); + if (email_login) + sql.append("AND EMail=? "); + else + sql.append("AND COALESCE(LDAPUser,Name)=? "); sql.append("AND EMail=? "); - sql.append("AND SecurityQuestion IS NOT NULL "); + sql.append("AND SecurityQuestion IS NOT NULL "); sql.append("ORDER BY AD_Client_ID DESC"); - String securityQuestion = DB.getSQLValueString(null, sql.toString(), email); + String securityQuestion = DB.getSQLValueString(null, sql.toString(), m_userName, email); txtSecurityQuestion.setValue(securityQuestion); txtEmail.setReadonly(true);