From 236d4f8f0f62dcb6ac4598698c3d9f4ae5dd5118 Mon Sep 17 00:00:00 2001 From: Bruno Sinou Date: Tue, 16 Dec 2014 20:38:13 +0000 Subject: [PATCH] Work on user management page. git-svn-id: https://svn.argeo.org/commons/trunk@7578 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- org.argeo.cms/bnd.bnd | 1 + .../src/org/argeo/cms/users/UserPage.java | 13 +- .../src/org/argeo/cms/users/UserPart.java | 42 +++++++ .../org/argeo/cms/users/UserRolesPart.java | 41 +++---- .../src/org/argeo/cms/users/UserStyles.java | 1 + .../src/org/argeo/cms/users/Users.java | 113 ++++++++++++++---- .../ui/dialogs/ChangePasswordDialog.java | 10 +- .../ui/commands/OpenChangePasswordDialog.java | 2 +- 8 files changed, 172 insertions(+), 51 deletions(-) rename {org.argeo.security.ui/src/org/argeo/security => org.argeo.eclipse.ui/src/org/argeo/eclipse}/ui/dialogs/ChangePasswordDialog.java (91%) diff --git a/org.argeo.cms/bnd.bnd b/org.argeo.cms/bnd.bnd index 969fc94ac..ef86f4d8c 100644 --- a/org.argeo.cms/bnd.bnd +++ b/org.argeo.cms/bnd.bnd @@ -1,4 +1,5 @@ Import-Package: org.springframework.core,\ + org.springframework.dao,\ org.eclipse.core.commands,\ org.eclipse.swt,\ javax.jcr.security,\ diff --git a/org.argeo.cms/src/org/argeo/cms/users/UserPage.java b/org.argeo.cms/src/org/argeo/cms/users/UserPage.java index 2f4616d33..3d72ce74a 100644 --- a/org.argeo.cms/src/org/argeo/cms/users/UserPage.java +++ b/org.argeo.cms/src/org/argeo/cms/users/UserPage.java @@ -13,14 +13,14 @@ import org.argeo.security.jcr.JcrSecurityModel; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; /** Enable management of a given user */ public class UserPage implements CmsUiProvider { // Enable user CRUD // INJECTED private UserAdminService userAdminService; - private JcrSecurityModel jcrSecurityModel; + + // private JcrSecurityModel jcrSecurityModel; // public UserPage(UserAdminService userAdminService, // JcrSecurityModel jcrSecurityModel) { @@ -39,13 +39,12 @@ public class UserPage implements CmsUiProvider { Control control = userViewer.getControl(); Composite par = control.getParent(); - new Label(par, SWT.NONE).setText("Work in progress terminate."); - UserRolesPart rolesPart = new UserRolesPart(par, SWT.NO_FOCUS, context, true); rolesPart.setUserAdminService(userAdminService); rolesPart.createControl(rolesPart, UserStyles.USER_FORM_TEXT); rolesPart.refresh(); + rolesPart.setLayoutData(CmsUtils.fillWidth()); return page; } @@ -69,7 +68,7 @@ public class UserPage implements CmsUiProvider { this.userAdminService = userAdminService; } - public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) { - this.jcrSecurityModel = jcrSecurityModel; - } +// public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) { +// this.jcrSecurityModel = jcrSecurityModel; +// } } \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/users/UserPart.java b/org.argeo.cms/src/org/argeo/cms/users/UserPart.java index a422521e1..a3a107d01 100644 --- a/org.argeo.cms/src/org/argeo/cms/users/UserPart.java +++ b/org.argeo.cms/src/org/argeo/cms/users/UserPart.java @@ -15,15 +15,19 @@ import org.argeo.cms.viewers.NodePart; import org.argeo.cms.widgets.StyledControl; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.jcr.ArgeoNames; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Text; /** Display a single user main info once it has been created. */ @@ -79,8 +83,45 @@ public class UserPart extends StyledControl implements EditablePart, NodePart, GridLayout layout = new GridLayout(2, false); body.setLayout(layout); + // header + Label header = new Label(body, SWT.NONE); + header.setText(" General"); + header.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, + 1)); + CmsUtils.style(header, UserStyles.USER_FORM_TITLE); + + // form field createTexts(body, UserStyles.USER_FORM_TEXT); CmsUtils.style(body, UserStyles.USER_FORM_TEXT); + + // Change password link + // header + header = new Label(body, SWT.NONE); + header.setText(" Change password"); + header.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, + 1)); + CmsUtils.style(header, UserStyles.USER_FORM_TITLE); + + final Link link = new Link(body, SWT.NONE); + link.setText("Change password"); + link.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + + MessageDialog.openInformation(link.getShell(), + "Not implemented", "Implement This."); + + // ChangePasswordDialog dialog = new ChangePasswordDialog( + // link.getShell(), userDetailsManager); + // if (dialog.open() == Window.OK) { + // MessageDialog.openInformation(HandlerUtil.getActiveShell(event), + // "Password changed", "Password changed."); + // } + // return null; + + } + }); + return body; } @@ -115,6 +156,7 @@ public class UserPart extends StyledControl implements EditablePart, NodePart, for (Text txt : texts) { txt.setText(get(getNode(), (String) txt.getData(KEY_PROP_NAME))); txt.setEditable(isEditing()); + // txt.setEnabled(isEditing()); } } diff --git a/org.argeo.cms/src/org/argeo/cms/users/UserRolesPart.java b/org.argeo.cms/src/org/argeo/cms/users/UserRolesPart.java index be13ed8a2..e813a43d5 100644 --- a/org.argeo.cms/src/org/argeo/cms/users/UserRolesPart.java +++ b/org.argeo.cms/src/org/argeo/cms/users/UserRolesPart.java @@ -29,20 +29,19 @@ import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; import org.springframework.security.GrantedAuthority; /** Display a single user main info once it has been created. */ public class UserRolesPart extends StyledControl implements EditablePart, NodePart, FocusListener { - - // A static list of supported properties. - private List texts; - private final static String KEY_PROP_NAME = "jcr:propertyName"; + private static final long serialVersionUID = -6013980335975055846L; private CheckboxTableViewer rolesViewer; + private Table table; + private JcrUserDetails userDetails; private UserAdminService userAdminService; private List roles; @@ -64,9 +63,7 @@ public class UserRolesPart extends StyledControl implements EditablePart, public UserRolesPart(Composite parent, int style, Item item, boolean cacheImmediately) throws RepositoryException { super(parent, style, item, cacheImmediately); - // checked = new Image(parent, imageData); - } @Override @@ -74,19 +71,25 @@ public class UserRolesPart extends StyledControl implements EditablePart, return getNode(); } - // Experimental, remove public void setMouseListener(MouseListener mouseListener) { super.setMouseListener(mouseListener); - - for (Text txt : texts) - txt.addMouseListener(mouseListener); - + table.addMouseListener(mouseListener); } @Override protected Control createControl(Composite box, String style) { - Table table = new Table(box, SWT.CHECK | SWT.MULTI | SWT.H_SCROLL - | SWT.V_SCROLL); + box.setLayout(CmsUtils.noSpaceGridLayout()); + + Label header = new Label(box, SWT.NONE); + header.setText(" Groups"); + CmsUtils.style(header, UserStyles.USER_FORM_TITLE); + header.setLayoutData(CmsUtils.fillWidth()); + + int swtStyle = SWT.CHECK | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL; + if (!isEditing()) + swtStyle |= SWT.READ_ONLY; + + table = new Table(box, swtStyle); table.setLinesVisible(true); table.setHeaderVisible(false); CmsUtils.style(table, style); @@ -128,6 +131,9 @@ public class UserRolesPart extends StyledControl implements EditablePart, rolesViewer.setContentProvider(new RolesContentProvider()); rolesViewer.setInput(userAdminService.listEditableRoles().toArray()); + // try to prevent edition on read only nodes. Does not work. + // rolesViewer.setAllGrayed(!isEditing()); + rolesViewer.addCheckStateListener(new ICheckStateListener() { @Override @@ -136,7 +142,7 @@ public class UserRolesPart extends StyledControl implements EditablePart, boolean contained = roles.contains(name); boolean checked = event.getChecked(); if (checked != contained) { - if (contained) + if (!contained) roles.add(name); else roles.remove(name); @@ -148,11 +154,6 @@ public class UserRolesPart extends StyledControl implements EditablePart, return table; } - // void refresh() { - // for (Text txt : texts) { - // } - // } - // THE LISTENER @Override public void focusGained(FocusEvent e) { diff --git a/org.argeo.cms/src/org/argeo/cms/users/UserStyles.java b/org.argeo.cms/src/org/argeo/cms/users/UserStyles.java index 18501b238..533f5bbaf 100644 --- a/org.argeo.cms/src/org/argeo/cms/users/UserStyles.java +++ b/org.argeo.cms/src/org/argeo/cms/users/UserStyles.java @@ -5,6 +5,7 @@ public interface UserStyles { /** A text in a form */ public final static String USER_FORM_TEXT = "user_form_text"; + public final static String USER_FORM_TITLE = "user_form_title"; public final static String USER_FORM_TEXT_ALT = "user_form_text_alt"; } \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/users/Users.java b/org.argeo.cms/src/org/argeo/cms/users/Users.java index e7f09440d..58e0e8862 100644 --- a/org.argeo.cms/src/org/argeo/cms/users/Users.java +++ b/org.argeo.cms/src/org/argeo/cms/users/Users.java @@ -1,30 +1,41 @@ package org.argeo.cms.users; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.cms.CmsUiProvider; import org.argeo.cms.CmsUtils; import org.argeo.cms.maintenance.NonAdminPage; import org.argeo.eclipse.ui.dialogs.UserCreationWizard; import org.argeo.eclipse.ui.parts.UsersTable; +import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.JcrUtils; import org.argeo.security.UserAdminService; import org.argeo.security.jcr.JcrSecurityModel; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; @@ -36,6 +47,8 @@ import org.eclipse.swt.widgets.Control; */ public class Users implements CmsUiProvider { + private final static Log log = LogFactory.getLog(Users.class); + // Enable user CRUD // INJECTED private UserAdminService userAdminService; private JcrSecurityModel jcrSecurityModel; @@ -116,31 +129,20 @@ public class Users implements CmsUiProvider { // Delete final Button deleteBtn = new Button(buttonCmp, SWT.PUSH); deleteBtn.setText("Delete selected"); + deleteBtn + .setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); + // Add final Button addBtn = new Button(buttonCmp, SWT.PUSH); addBtn.setText("Create"); - addBtn.addSelectionListener(new SelectionListener() { - private static final long serialVersionUID = 9214984636836267786L; - - @Override - public void widgetSelected(SelectionEvent e) { - UserCreationWizard newUserWizard = new UserCreationWizard( - session, userAdminService, jcrSecurityModel); - WizardDialog dialog = new WizardDialog(addBtn.getShell(), - newUserWizard); - dialog.open(); - // TODO refresh list if user has been created - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); // Create the composite that displays the list and a filter - UsersTable userTableCmp = new UsersTable(parent, SWT.NO_FOCUS, session); + final UsersTable userTableCmp = new UsersTable(parent, SWT.NO_FOCUS, + session); userTableCmp.populate(true, false); userTableCmp.setLayoutData(CmsUtils.fillAll()); + + // The various listeners userTableCmp.addDisposeListener(new DisposeListener() { private static final long serialVersionUID = -8854052549807709846L; @@ -150,6 +152,77 @@ public class Users implements CmsUiProvider { } }); + deleteBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -7340611909297995666L; + + @Override + public void widgetSelected(SelectionEvent e) { + + TableViewer viewer = userTableCmp.getTableViewer(); + ISelection selection = viewer.getSelection(); + if (selection.isEmpty()) + return; + + Map toDelete = new TreeMap(); + @SuppressWarnings("unchecked") + Iterator it = ((IStructuredSelection) selection) + .iterator(); + nodes: while (it.hasNext()) { + Node profileNode = it.next(); + try { + String userName = profileNode.getProperty( + ArgeoNames.ARGEO_USER_ID).getString(); + if (userName.equals(profileNode.getSession() + .getUserID())) { + log.warn("Cannot delete its own user: " + userName); + continue nodes; + } + toDelete.put(userName, profileNode); + } catch (RepositoryException re) { + log.warn("Cannot interpred user " + profileNode); + } + } + + if (!MessageDialog.openQuestion( + userTableCmp.getShell(), + "Delete User", + "Are you sure that you want to delete users " + + toDelete.keySet() + + "?\n" + + "This may lead to inconsistencies in the application.")) + return; + + for (String username : toDelete.keySet()) { + Session session = null; + try { + Node profileNode = toDelete.get(username); + userAdminService.deleteUser(username); + profileNode.getParent().remove(); + session = profileNode.getSession(); + session.save(); + } catch (RepositoryException re) { + JcrUtils.discardQuietly(session); + throw new ArgeoException("Cannot list users", re); + } + } + userTableCmp.refresh(); + } + }); + + addBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 9214984636836267786L; + + @Override + public void widgetSelected(SelectionEvent e) { + UserCreationWizard newUserWizard = new UserCreationWizard( + session, userAdminService, jcrSecurityModel); + WizardDialog dialog = new WizardDialog(addBtn.getShell(), + newUserWizard); + if (dialog.open() == Window.OK) + userTableCmp.refresh(); + } + }); + // Configure // userTableCmp.getTableViewer().addDoubleClickListener( // new ViewDoubleClickListener()); @@ -267,6 +340,6 @@ public class Users implements CmsUiProvider { public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) { this.jcrSecurityModel = jcrSecurityModel; - userPage.setJcrSecurityModel(jcrSecurityModel); + // userPage.setJcrSecurityModel(jcrSecurityModel); } } \ No newline at end of file diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/ChangePasswordDialog.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/dialogs/ChangePasswordDialog.java similarity index 91% rename from org.argeo.security.ui/src/org/argeo/security/ui/dialogs/ChangePasswordDialog.java rename to org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/dialogs/ChangePasswordDialog.java index 3e3af5bf6..ea8c1aba7 100644 --- a/org.argeo.security.ui/src/org/argeo/security/ui/dialogs/ChangePasswordDialog.java +++ b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/dialogs/ChangePasswordDialog.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.argeo.security.ui.dialogs; +package org.argeo.eclipse.ui.dialogs; import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.workbench.ErrorFeedback; import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; @@ -32,6 +32,8 @@ import org.springframework.security.userdetails.UserDetailsManager; /** Dialog to change the current user password */ public class ChangePasswordDialog extends TitleAreaDialog { + private static final long serialVersionUID = -2447446550246803237L; + private Text currentPassword, newPassword1, newPassword2; private UserDetailsManager userDetailsManager; @@ -69,7 +71,9 @@ public class ChangePasswordDialog extends TitleAreaDialog { newPassword1.getText()); close(); } catch (Exception e) { - ErrorFeedback.show("Cannot change password", e); + MessageDialog.openError(newPassword1.getShell(), "Error", + "Cannot change password"); + e.printStackTrace(); } } diff --git a/org.argeo.security.ui/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java b/org.argeo.security.ui/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java index 3044e2c6c..f1bb093ec 100644 --- a/org.argeo.security.ui/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java +++ b/org.argeo.security.ui/src/org/argeo/security/ui/commands/OpenChangePasswordDialog.java @@ -15,7 +15,7 @@ */ package org.argeo.security.ui.commands; -import org.argeo.security.ui.dialogs.ChangePasswordDialog; +import org.argeo.eclipse.ui.dialogs.ChangePasswordDialog; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -- 2.30.2