From dd3d0d60b62c99810eca8619a376b66dbca5e44d Mon Sep 17 00:00:00 2001 From: Bruno Sinou Date: Wed, 2 Sep 2015 19:44:06 +0000 Subject: [PATCH] First draft to adapt Security Admin UI to the new security model git-svn-id: https://svn.argeo.org/commons/trunk@8362 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../META-INF/spring/editors.xml | 11 +- .../META-INF/spring/osgi.xml | 4 + .../META-INF/spring/views.xml | 14 +- org.argeo.security.ui.admin/plugin.xml | 60 ++- .../ui/admin/SecurityAdminImages.java | 9 +- .../ui/admin/SecurityAdminPerspective.java | 15 +- .../security/ui/admin/UserAdminConstants.java | 10 + .../security/ui/admin/commands/AddRole.java | 12 +- .../ui/admin/commands/DeleteRole.java | 6 +- .../ui/admin/commands/DeleteUser.java | 4 +- .../admin/commands/OpenArgeoUserEditor.java | 4 +- .../ui/admin/commands/RefreshUsersList.java | 14 +- .../ui/admin/editors/GroupMainPage.java | 388 ++++++++++++++++++ ...serEditor.java => JcrArgeoUserEditor.java} | 10 +- .../security/ui/admin/editors/UserEditor.java | 119 ++++++ .../ui/admin/editors/UserEditorInput.java | 68 +++ .../ui/admin/editors/UserMainPage.java | 239 +++++++++++ .../security/ui/admin/views/GroupsView.java | 100 +++++ .../{RolesView.java => JcrRolesView.java} | 4 +- .../security/ui/admin/views/JcrUsersView.java | 157 +++++++ .../security/ui/admin/views/UsersView.java | 353 ++++++++++++---- 21 files changed, 1461 insertions(+), 140 deletions(-) create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/UserAdminConstants.java create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java rename org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/{ArgeoUserEditor.java => JcrArgeoUserEditor.java} (95%) create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditorInput.java create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/GroupsView.java rename org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/{RolesView.java => JcrRolesView.java} (98%) create mode 100644 org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrUsersView.java diff --git a/org.argeo.security.ui.admin/META-INF/spring/editors.xml b/org.argeo.security.ui.admin/META-INF/spring/editors.xml index 740792a61..ac7441b93 100644 --- a/org.argeo.security.ui.admin/META-INF/spring/editors.xml +++ b/org.argeo.security.ui.admin/META-INF/spring/editors.xml @@ -4,8 +4,17 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + - + + + + + + diff --git a/org.argeo.security.ui.admin/META-INF/spring/osgi.xml b/org.argeo.security.ui.admin/META-INF/spring/osgi.xml index 2fa51446c..b4c52fc4f 100644 --- a/org.argeo.security.ui.admin/META-INF/spring/osgi.xml +++ b/org.argeo.security.ui.admin/META-INF/spring/osgi.xml @@ -11,4 +11,8 @@ + + + + \ No newline at end of file diff --git a/org.argeo.security.ui.admin/META-INF/spring/views.xml b/org.argeo.security.ui.admin/META-INF/spring/views.xml index 655b0c8e3..86168e0a8 100644 --- a/org.argeo.security.ui.admin/META-INF/spring/views.xml +++ b/org.argeo.security.ui.admin/META-INF/spring/views.xml @@ -4,11 +4,21 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - + + + + + + + + + - diff --git a/org.argeo.security.ui.admin/plugin.xml b/org.argeo.security.ui.admin/plugin.xml index f7c18f5e9..c9dacd420 100644 --- a/org.argeo.security.ui.admin/plugin.xml +++ b/org.argeo.security.ui.admin/plugin.xml @@ -10,33 +10,61 @@ name="Security"> + + point="org.eclipse.ui.views"> + + + + + + - - - - - + + + + + + + + + + + + - + + \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminImages.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminImages.java index f7ffa9c8d..e7cd5df46 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminImages.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminImages.java @@ -26,8 +26,15 @@ */ package org.argeo.security.ui.admin; +import org.eclipse.swt.graphics.Image; + /** Shared icons that must be declared programmatically . */ public class SecurityAdminImages { - @SuppressWarnings("unused") private final static String PREFIX = "icons/"; + + public final static Image ICON_USER = SecurityAdminPlugin + .getImageDescriptor(PREFIX + "user.gif").createImage(); + public final static Image ICON_GROUP = SecurityAdminPlugin + .getImageDescriptor(PREFIX + "users.gif").createImage(); + } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java index c743f56bd..082fba909 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java @@ -15,12 +15,15 @@ */ package org.argeo.security.ui.admin; -import org.argeo.security.ui.admin.views.RolesView; +import org.argeo.security.ui.admin.views.GroupsView; +import org.argeo.security.ui.admin.views.JcrUsersView; +import org.argeo.security.ui.admin.views.JcrRolesView; import org.argeo.security.ui.admin.views.UsersView; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; +/** Default perspective to manage users and groups */ public class SecurityAdminPerspective implements IPerspectiveFactory { public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); @@ -28,9 +31,13 @@ public class SecurityAdminPerspective implements IPerspectiveFactory { layout.setFixed(false); IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, - 0.65f, editorArea); + 0.25f, editorArea); left.addView(UsersView.ID); - left.addView(RolesView.ID); - } + left.addView(JcrUsersView.ID); + left.addView(JcrRolesView.ID); + IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, + 0.70f, editorArea); + right.addView(GroupsView.ID); + } } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/UserAdminConstants.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/UserAdminConstants.java new file mode 100644 index 000000000..f17800bad --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/UserAdminConstants.java @@ -0,0 +1,10 @@ +package org.argeo.security.ui.admin; + +/** Temporary centralization of the user admin constants */ +public interface UserAdminConstants { + + public final static String KEY_UID = "uid"; + public final static String KEY_CN = "cn"; + public final static String KEY_MAIL = "mail"; + +} diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/AddRole.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/AddRole.java index a1008f699..56946e76b 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/AddRole.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/AddRole.java @@ -17,8 +17,8 @@ package org.argeo.security.ui.admin.commands; import org.argeo.ArgeoException; import org.argeo.security.UserAdminService; -import org.argeo.security.ui.admin.editors.ArgeoUserEditor; -import org.argeo.security.ui.admin.views.RolesView; +import org.argeo.security.ui.admin.editors.JcrArgeoUserEditor; +import org.argeo.security.ui.admin.views.JcrRolesView; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -33,9 +33,9 @@ public class AddRole extends AbstractHandler { private String rolePrefix = "ROLE_"; public Object execute(ExecutionEvent event) throws ExecutionException { - RolesView rolesView = (RolesView) HandlerUtil + JcrRolesView rolesView = (JcrRolesView) HandlerUtil .getActiveWorkbenchWindow(event).getActivePage() - .findView(RolesView.ID); + .findView(JcrRolesView.ID); String role = rolesView.getNewRole(); if (role.trim().equals("")) return null; @@ -52,9 +52,9 @@ public class AddRole extends AbstractHandler { // refresh editors IEditorReference[] refs = HandlerUtil.getActiveWorkbenchWindow(event) .getActivePage() - .findEditors(null, ArgeoUserEditor.ID, IWorkbenchPage.MATCH_ID); + .findEditors(null, JcrArgeoUserEditor.ID, IWorkbenchPage.MATCH_ID); for (IEditorReference ref : refs) { - ArgeoUserEditor userEditor = (ArgeoUserEditor) ref.getEditor(false); + JcrArgeoUserEditor userEditor = (JcrArgeoUserEditor) ref.getEditor(false); if (userEditor != null) { userEditor.refresh(); } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteRole.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteRole.java index 6cba11eb9..7648e2618 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteRole.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteRole.java @@ -20,7 +20,7 @@ import java.util.Iterator; import java.util.List; import org.argeo.security.UserAdminService; -import org.argeo.security.ui.admin.views.RolesView; +import org.argeo.security.ui.admin.views.JcrRolesView; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -59,9 +59,9 @@ public class DeleteRole extends AbstractHandler { userAdminService.deleteRole(role); } - RolesView view = (RolesView) HandlerUtil + JcrRolesView view = (JcrRolesView) HandlerUtil .getActiveWorkbenchWindow(event).getActivePage() - .findView(RolesView.ID); + .findView(JcrRolesView.ID); view.refresh(); return null; } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUser.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUser.java index ccf360fd0..dbff6e576 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUser.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUser.java @@ -91,9 +91,9 @@ public class DeleteUser extends AbstractHandler { } userAdminService.synchronize(); - // UsersView view = (UsersView) HandlerUtil + // JcrUsersView view = (JcrUsersView) HandlerUtil // .getActiveWorkbenchWindow(event).getActivePage() - // .findView(UsersView.ID); + // .findView(JcrUsersView.ID); // view.refresh(); return null; } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/OpenArgeoUserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/OpenArgeoUserEditor.java index bae928c22..fe8cefa5f 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/OpenArgeoUserEditor.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/OpenArgeoUserEditor.java @@ -15,7 +15,7 @@ */ package org.argeo.security.ui.admin.commands; -import org.argeo.security.ui.admin.editors.ArgeoUserEditor; +import org.argeo.security.ui.admin.editors.JcrArgeoUserEditor; import org.argeo.security.ui.admin.editors.ArgeoUserEditorInput; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -34,7 +34,7 @@ public class OpenArgeoUserEditor extends AbstractHandler { event.getParameter(PARAM_USERNAME)); IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow( event).getActivePage(); - activePage.openEditor(editorInput, ArgeoUserEditor.ID); + activePage.openEditor(editorInput, JcrArgeoUserEditor.ID); } catch (Exception e) { throw new ExecutionException("Cannot open editor", e); } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/RefreshUsersList.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/RefreshUsersList.java index e4c14ab21..fd98e718f 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/RefreshUsersList.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/RefreshUsersList.java @@ -29,7 +29,7 @@ import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.ArgeoTypes; import org.argeo.jcr.JcrUtils; import org.argeo.security.UserAdminService; -import org.argeo.security.ui.admin.views.UsersView; +import org.argeo.security.ui.admin.views.JcrUsersView; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -72,17 +72,17 @@ public class RefreshUsersList extends AbstractHandler { } userAdminService.synchronize(); - // FIXME try to refresh views that extend the UsersView and have another + // FIXME try to refresh views that extend the JcrUsersView and have another // ID IWorkbenchPart part = HandlerUtil.getActiveWorkbenchWindow(event) .getActivePage().getActivePart(); - if (part instanceof UsersView) - ((UsersView) part).refresh(); + if (part instanceof JcrUsersView) + ((JcrUsersView) part).refresh(); - // Try to refresh UsersView if opened - UsersView view = (UsersView) HandlerUtil + // Try to refresh JcrUsersView if opened + JcrUsersView view = (JcrUsersView) HandlerUtil .getActiveWorkbenchWindow(event).getActivePage() - .findView(UsersView.ID); + .findView(JcrUsersView.ID); if (view != null) view.refresh(); diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java new file mode 100644 index 000000000..3d75b56fd --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java @@ -0,0 +1,388 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.editors; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.utils.ViewerUtils; +import org.argeo.jcr.ArgeoNames; +import org.argeo.security.ui.admin.SecurityAdminImages; +import org.argeo.security.ui.admin.UserAdminConstants; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.SectionPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Display/edit the properties of the groups */ +public class GroupMainPage extends FormPage implements ArgeoNames { + final static String ID = "GroupEditor.mainPage"; + + private final UserEditor editor; + + private UserAdmin userAdmin; + + public GroupMainPage(FormEditor editor, UserAdmin userAdmin) { + super(editor, ID, "Main"); + this.editor = (UserEditor) editor; + this.userAdmin = userAdmin; + } + + protected void createFormContent(final IManagedForm mf) { + try { + ScrolledForm form = mf.getForm(); + refreshFormTitle(form); + GridLayout mainLayout = new GridLayout(1, true); + form.getBody().setLayout(mainLayout); + + createGeneralPart(form.getBody()); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot create form content", e); + } + } + + /** Creates the general section */ + protected void createGeneralPart(Composite parent) + throws RepositoryException { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + section.setText("Members of " + + editor.getProperty(UserAdminConstants.KEY_CN)); + Composite body = tk.createComposite(section, SWT.WRAP); + section.setClient(body); + body.setLayoutData(EclipseUiUtils.fillAll()); + + body.setLayout(new GridLayout()); + new Label(body, SWT.NONE) + .setText("Display a table with members for this group"); + + // final Text firstName = createLT(body, "First name", + // getProperty(ARGEO_FIRST_NAME)); + // final Text lastName = createLT(body, "Last name", + // getProperty(ARGEO_LAST_NAME)); + // final Text email = createLT(body, "Email", + // editor.getProperty(UserAdminConstants.KEY_MAIL)); + // // final Text description = createLMT(body, "Description", + // getProperty(Property.JCR_DESCRIPTION)); + + // create form part (controller) + AbstractFormPart part = new SectionPart(section) { + public void commit(boolean onSave) { + // TODO check mail validity + // editor.setProperty(UserAdminConstants.KEY_MAIL, + // email.getText()); + + // userProfile.getSession().getWorkspace().getVersionManager() + // .checkout(userProfile.getPath()); + // userProfile.setProperty(Property.JCR_TITLE, + // commonName.getText()); + // userProfile.setProperty(ARGEO_FIRST_NAME, + // firstName.getText()); + // userProfile + // .setProperty(ARGEO_LAST_NAME, lastName.getText()); + // userProfile.setProperty(ARGEO_PRIMARY_EMAIL, + // email.getText()); + // userProfile.setProperty(Property.JCR_DESCRIPTION, + // description.getText()); + // userProfile.getSession().save(); + // userProfile.getSession().getWorkspace().getVersionManager() + // .checkin(userProfile.getPath()); + super.commit(onSave); + } + }; + // if (username != null) + // username.addModifyListener(new FormPartML(part)); + // commonName.addModifyListener(new FormPartML(part)); + // firstName.addModifyListener(new FormPartML(part)); + // lastName.addModifyListener(new FormPartML(part)); + + // email.addModifyListener(new FormPartML(part)); + getManagedForm().addPart(part); + } + + private void refreshFormTitle(ScrolledForm form) throws RepositoryException { + // form.setText(getProperty(Property.JCR_TITLE) + // + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? "" + // : " [DISABLED]")); + } + + // /** @return the property, or the empty string if not set */ + // protected String getProperty(String name) throws RepositoryException { + // return userProfile.hasProperty(name) ? userProfile.getProperty(name) + // .getString() : ""; + // } + + /** Creates label and text. */ + protected Text createLT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + /** Creates label and multiline text. */ + protected Text createLMT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + return text; + } + + private class FormPartML implements ModifyListener { + private static final long serialVersionUID = 6299808129505381333L; + private AbstractFormPart formPart; + + public FormPartML(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + formPart.markDirty(); + } + } + + // Manage the user table + public List getColumnsDef() { + List columnDefs = new ArrayList(); + + // Icon + columnDefs.add(new ColumnDefinition(new UserNameLP(), "", 0, 26)); + // Distinguished Name + columnDefs.add(new ColumnDefinition(new CommonNameLP(), + "Distinguished Name", 150)); + // Displayed name + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + return columnDefs; + } + + private void createUserTable(Composite parent) { + + // Main Layout + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + parent.setLayout(layout); + + // usersViewer = createTableViewer(parent); + // usersViewer.setContentProvider(new UsersContentProvider()); + + // Really? + refreshFilteredList(null); + + // Configure + // usersViewer.addDoubleClickListener(new ViewDoubleClickListener()); + // getViewSite().setSelectionProvider(usersViewer); + } + + private TableViewer createTableViewer(final Composite parent) { + int style = SWT.H_SCROLL | SWT.V_SCROLL; + + Composite tableCmp = new Composite(parent, SWT.NO_FOCUS); + tableCmp.setLayoutData(EclipseUiUtils.fillAll()); + + Table table = new Table(tableCmp, style); + TableViewer viewer = new TableViewer(table); + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumnLayout tableColumnLayout = new TableColumnLayout(); + TableViewerColumn column; + + // Create other columns + List colDefs = getColumnsDef(); + for (ColumnDefinition colDef : colDefs) { + column = ViewerUtils.createTableViewerColumn(viewer, colDef.label, + SWT.NONE, colDef.weight); + column.setLabelProvider(colDef.provider); + tableColumnLayout.setColumnData(column.getColumn(), + new ColumnWeightData(colDef.weight, colDef.minWidth, true)); + } + + tableCmp.setLayout(tableColumnLayout); + return viewer; + } + + @Override + public void dispose() { + super.dispose(); + } + + private class UsersContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = 1L; + + public Object[] getElements(Object inputElement) { + return (Object[]) inputElement; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + /** + * Refresh the user list: caller might overwrite in order to display a + * subset of all users, typically to remove current user from the list + */ + protected void refreshFilteredList(String filter) { + // try { + // // Role[] roles = userAdmin.getRoles(filter); + // // List users = new ArrayList(); + // // for (Role role : roles) + // // if (role.getType() == Role.USER && role.getType() != Role.GROUP) + // // users.add((User) role); + // // usersViewer.setInput(users.toArray()); + // } catch (InvalidSyntaxException e) { + // throw new ArgeoException("Unable to get roles with filter: " + // + filter, e); + // } + } + + // Local helpers + + private abstract class UseradminAbstractLP extends ColumnLabelProvider { + private static final long serialVersionUID = 137336765024922368L; + + @Override + public Font getFont(Object element) { + // TODO manage fonts + // // self + // String username = getProperty(elem, ARGEO_USER_ID); + // if (username.equals(session.getUserID())) + // return bold; + // // disabled + // try { + // Node userProfile = (Node) elem; + // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + // return italic; + // else + // return null; + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot get font for " + username, e); + // } + // } + + return super.getFont(element); + } + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + } + + public abstract String getText(User user); + } + + private class IconLP extends UseradminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return ""; + } + + @Override + public Image getImage(Object element) { + User user = (User) element; + if (user.getType() == Role.GROUP) + return SecurityAdminImages.ICON_GROUP; + else + return SecurityAdminImages.ICON_USER; + } + } + + private class UserNameLP extends UseradminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return user.getName(); + } + } + + private class CommonNameLP extends UseradminAbstractLP { + private static final long serialVersionUID = 5256703081044911941L; + + @Override + public String getText(User user) { + Object obj = user.getProperties().get(UserAdminConstants.KEY_CN); + if (obj != null) + return (String) obj; + else + return ""; + } + } + + protected class ColumnDefinition { + protected ColumnLabelProvider provider; + protected String label; + protected int weight; + protected int minWidth; + + public ColumnDefinition(ColumnLabelProvider provider, String label, + int weight) { + this.provider = provider; + this.label = label; + this.weight = weight; + this.minWidth = weight; + } + + public ColumnDefinition(ColumnLabelProvider provider, String label, + int weight, int minWidth) { + this.provider = provider; + this.label = label; + this.weight = weight; + this.minWidth = minWidth; + + } + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/JcrArgeoUserEditor.java similarity index 95% rename from org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java rename to org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/JcrArgeoUserEditor.java index d82292988..83d59e63c 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/JcrArgeoUserEditor.java @@ -28,7 +28,7 @@ import org.argeo.jcr.UserJcrUtils; import org.argeo.security.UserAdminService; import org.argeo.security.jcr.JcrUserDetails; import org.argeo.security.ui.admin.SecurityAdminPlugin; -import org.argeo.security.ui.admin.views.UsersView; +import org.argeo.security.ui.admin.views.JcrUsersView; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; @@ -38,7 +38,7 @@ import org.eclipse.ui.forms.editor.FormEditor; import org.springframework.security.core.GrantedAuthority; /** Editor for an Argeo user. */ -public class ArgeoUserEditor extends FormEditor { +public class JcrArgeoUserEditor extends FormEditor { private static final long serialVersionUID = 1933296330339252869L; public final static String ID = SecurityAdminPlugin.PLUGIN_ID @@ -125,12 +125,14 @@ public class ArgeoUserEditor extends FormEditor { // view. // refresh users view IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench(); - UsersView usersView = (UsersView) iw.getActiveWorkbenchWindow() - .getActivePage().findView(UsersView.ID); + JcrUsersView usersView = (JcrUsersView) iw.getActiveWorkbenchWindow() + .getActivePage().findView(JcrUsersView.ID); if (usersView != null) usersView.refresh(); } + + @Override public void doSaveAs() { } diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java new file mode 100644 index 000000000..7518b8084 --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.editors; + +import org.argeo.ArgeoException; +import org.argeo.security.ui.admin.SecurityAdminImages; +import org.argeo.security.ui.admin.SecurityAdminPlugin; +import org.argeo.security.ui.admin.UserAdminConstants; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.editor.FormEditor; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; + +/** Editor for an Argeo user. */ +public class UserEditor extends FormEditor implements UserAdminConstants { + private static final long serialVersionUID = 8357851520380820241L; + + public final static String ID = SecurityAdminPlugin.PLUGIN_ID + + ".userEditor"; + + /* DEPENDENCY INJECTION */ + private UserAdmin userAdmin; + + // Context + private User user; + private String username; + + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + super.init(site, input); + username = ((UserEditorInput) getEditorInput()).getUsername(); + user = (User) userAdmin.getRole(username); + + String commonName = getProperty(KEY_CN); + // this.setPartProperty("name", commonName != null ? commonName + // : "username"); + + // if (user.getType() == Role.GROUP) { + // this.setPartProperty("icon", "icons/users.gif"); + // firePartPropertyChanged("icon", "icons/user.gif", "icons/users.gif"); + // } + setPartName(commonName != null ? commonName : "username"); + } + + protected void addPages() { + try { + + if (user.getType() == Role.GROUP) + addPage(new GroupMainPage(this, userAdmin)); + else + addPage(new UserMainPage(this)); + + + + } catch (Exception e) { + throw new ArgeoException("Cannot add pages", e); + } + } + + protected String getProperty(String key) { + Object obj = user.getProperties().get(key); + if (obj != null) + return (String) obj; + else + return ""; + } + + /** The property is directly updated!!! */ + @SuppressWarnings("unchecked") + protected void setProperty(String key, String value) { + user.getProperties().put(key, value); + } + + @Override + public void doSave(IProgressMonitor monitor) { + commitPages(true); + firePropertyChange(PROP_DIRTY); + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + public void refresh() { + + } + + @Override + public void dispose() { + super.dispose(); + } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditorInput.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditorInput.java new file mode 100644 index 000000000..7f078276e --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditorInput.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.editors; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * Editor input for an user defined by unique name (usually a distinguished + * name). + */ +public class UserEditorInput implements IEditorInput { + private final String username; + + public UserEditorInput(String username) { + this.username = username; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return username != null; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + public String getName() { + return username != null ? username : ""; + } + + public IPersistableElement getPersistable() { + return null; + } + + public String getToolTipText() { + return username != null ? username : ""; + } + + public boolean equals(Object obj) { + if (!(obj instanceof UserEditorInput)) + return false; + if (((UserEditorInput) obj).getUsername() == null) + return false; + return ((UserEditorInput) obj).getUsername().equals(username); + } + + public String getUsername() { + return username; + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java new file mode 100644 index 000000000..812cbe9ed --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.editors; + +import java.util.Arrays; + +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.jcr.ArgeoNames; +import org.argeo.security.ui.admin.UserAdminConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.AbstractFormPart; +import org.eclipse.ui.forms.IManagedForm; +import org.eclipse.ui.forms.SectionPart; +import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.FormPage; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; + +/** Display/edit the properties common to all users */ +public class UserMainPage extends FormPage implements ArgeoNames { + final static String ID = "argeoUserEditor.mainPage"; + + // private final static Log log = LogFactory.getLog(UserMainPage.class); + + private final UserEditor editor; + private char[] newPassword; + + public UserMainPage(FormEditor editor) { + super(editor, ID, "Main"); + this.editor = (UserEditor) editor; + } + + protected void createFormContent(final IManagedForm mf) { + try { + ScrolledForm form = mf.getForm(); + refreshFormTitle(form); + GridLayout mainLayout = new GridLayout(1, true); + form.getBody().setLayout(mainLayout); + + createGeneralPart(form.getBody()); + // createPassworPart(form.getBody()); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot create form content", e); + } + } + + /** Creates the general section */ + protected void createGeneralPart(Composite parent) + throws RepositoryException { + FormToolkit tk = getManagedForm().getToolkit(); + Section section = tk.createSection(parent, Section.TITLE_BAR); + section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + section.setText("General"); + Composite body = tk.createComposite(section, SWT.WRAP); + section.setClient(body); + GridLayout layout = new GridLayout(2, false); + body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + body.setLayout(layout); + + final Text commonName = createLT(body, "Common Name", + editor.getProperty(UserAdminConstants.KEY_CN)); + commonName.setEnabled(false); + + // final Text firstName = createLT(body, "First name", + // getProperty(ARGEO_FIRST_NAME)); + // final Text lastName = createLT(body, "Last name", + // getProperty(ARGEO_LAST_NAME)); + final Text email = createLT(body, "Email", + editor.getProperty(UserAdminConstants.KEY_MAIL)); + // final Text description = createLMT(body, "Description", + // getProperty(Property.JCR_DESCRIPTION)); + + // create form part (controller) + AbstractFormPart part = new SectionPart(section) { + public void commit(boolean onSave) { + // TODO check mail validity + editor.setProperty(UserAdminConstants.KEY_MAIL, email.getText()); + + // userProfile.getSession().getWorkspace().getVersionManager() + // .checkout(userProfile.getPath()); + // userProfile.setProperty(Property.JCR_TITLE, + // commonName.getText()); + // userProfile.setProperty(ARGEO_FIRST_NAME, + // firstName.getText()); + // userProfile + // .setProperty(ARGEO_LAST_NAME, lastName.getText()); + // userProfile.setProperty(ARGEO_PRIMARY_EMAIL, + // email.getText()); + // userProfile.setProperty(Property.JCR_DESCRIPTION, + // description.getText()); + // userProfile.getSession().save(); + // userProfile.getSession().getWorkspace().getVersionManager() + // .checkin(userProfile.getPath()); + super.commit(onSave); + } + }; + // if (username != null) + // username.addModifyListener(new FormPartML(part)); + // commonName.addModifyListener(new FormPartML(part)); + // firstName.addModifyListener(new FormPartML(part)); + // lastName.addModifyListener(new FormPartML(part)); + + email.addModifyListener(new FormPartML(part)); + getManagedForm().addPart(part); + } + + private void refreshFormTitle(ScrolledForm form) throws RepositoryException { + // form.setText(getProperty(Property.JCR_TITLE) + // + (userProfile.getProperty(ARGEO_ENABLED).getBoolean() ? "" + // : " [DISABLED]")); + } + + // /** @return the property, or the empty string if not set */ + // protected String getProperty(String name) throws RepositoryException { + // return userProfile.hasProperty(name) ? userProfile.getProperty(name) + // .getString() : ""; + // } + + /** Creates the password section */ + // protected void createPassworPart(Composite parent) { + // FormToolkit tk = getManagedForm().getToolkit(); + // Section section = tk.createSection(parent, Section.TITLE_BAR); + // section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + // section.setText("Password"); + // + // Composite body = tk.createComposite(section, SWT.WRAP); + // section.setClient(body); + // GridLayout layout = new GridLayout(2, false); + // body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + // body.setLayout(layout); + // + // // add widgets (view) + // final Text password1 = createLP(body, "New password", ""); + // final Text password2 = createLP(body, "Repeat password", ""); + // // create form part (controller) + // AbstractFormPart part = new SectionPart(section) { + // + // public void commit(boolean onSave) { + // if (!password1.getText().equals("") + // || !password2.getText().equals("")) { + // if (password1.getText().equals(password2.getText())) { + // newPassword = password1.getText().toCharArray(); + // password1.setText(""); + // password2.setText(""); + // super.commit(onSave); + // } else { + // password1.setText(""); + // password2.setText(""); + // throw new ArgeoException("Passwords are not equals"); + // } + // } + // } + // + // }; + // password1.addModifyListener(new FormPartML(part)); + // password2.addModifyListener(new FormPartML(part)); + // getManagedForm().addPart(part); + // } + + /** Creates label and text. */ + protected Text createLT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + /** Creates label and multiline text. */ + protected Text createLMT(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.MULTI); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); + return text; + } + + /** Creates label and password. */ + protected Text createLP(Composite body, String label, String value) { + FormToolkit toolkit = getManagedForm().getToolkit(); + Label lbl = toolkit.createLabel(body, label); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Text text = toolkit.createText(body, value, SWT.BORDER | SWT.PASSWORD); + text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return text; + } + + private class FormPartML implements ModifyListener { + private static final long serialVersionUID = 6299808129505381333L; + private AbstractFormPart formPart; + + public FormPartML(AbstractFormPart generalPart) { + this.formPart = generalPart; + } + + public void modifyText(ModifyEvent e) { + formPart.markDirty(); + } + + } + + public String getNewPassword() { + if (newPassword != null) + return new String(newPassword); + else + return null; + } + + public void resetNewPassword() { + if (newPassword != null) + Arrays.fill(newPassword, 'x'); + newPassword = null; + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/GroupsView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/GroupsView.java new file mode 100644 index 000000000..34bda0e69 --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/GroupsView.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.views; + +import java.util.ArrayList; +import java.util.List; + +import org.argeo.ArgeoException; +import org.argeo.jcr.ArgeoNames; +import org.argeo.security.ui.admin.SecurityAdminPlugin; +import org.argeo.security.ui.admin.UserAdminConstants; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; + +/** List all groups with filter */ +public class GroupsView extends UsersView implements ArgeoNames { + public final static String ID = SecurityAdminPlugin.PLUGIN_ID + + ".groupsView"; + + // The displayed columns + /** Overwrite to display other columns */ + public List getColumnsDef() { + List columnDefs = new ArrayList(); + // Group ID + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 200)); + // Displayed name + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + return columnDefs; + } + + /** + * Refresh the user list: caller might overwrite in order to display a + * subset of all users, typically to remove current user from the list + */ + protected void refreshFilteredList(String filter) { + try { + Role[] roles = userAdmin().getRoles(filter); + List users = new ArrayList(); + for (Role role : roles) + if (role.getType() == Role.GROUP) + users.add((User) role); + getViewer().setInput(users.toArray()); + } catch (InvalidSyntaxException e) { + throw new ArgeoException("Unable to get roles with filter: " + + filter, e); + } + } + + private abstract class GroupAdminAbstractLP extends ColumnLabelProvider { + private static final long serialVersionUID = 137336765024922368L; + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + } + + public abstract String getText(User user); + } + + private class UserNameLP extends GroupAdminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return user.getName(); + } + } + + private class CommonNameLP extends GroupAdminAbstractLP { + private static final long serialVersionUID = 5256703081044911941L; + + @Override + public String getText(User user) { + Object obj = user.getProperties().get(UserAdminConstants.KEY_CN); + if (obj != null) + return (String) obj; + else + return ""; + } + } + +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/RolesView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrRolesView.java similarity index 98% rename from org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/RolesView.java rename to org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrRolesView.java index c35e1045e..a87454352 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/RolesView.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrRolesView.java @@ -38,9 +38,9 @@ import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.part.ViewPart; /** List all roles. */ -public class RolesView extends ViewPart { +public class JcrRolesView extends ViewPart { public final static String ID = SecurityAdminPlugin.PLUGIN_ID - + ".adminRolesView"; + + ".jcrRolesView"; private Text newRole; diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrUsersView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrUsersView.java new file mode 100644 index 000000000..1c4224d02 --- /dev/null +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrUsersView.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.security.ui.admin.views; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventIterator; +import javax.jcr.observation.EventListener; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.parts.UsersTable; +import org.argeo.eclipse.ui.workbench.CommandUtils; +import org.argeo.jcr.ArgeoJcrConstants; +import org.argeo.jcr.ArgeoNames; +import org.argeo.jcr.ArgeoTypes; +import org.argeo.jcr.JcrUtils; +import org.argeo.security.ui.admin.SecurityAdminPlugin; +import org.argeo.security.ui.admin.commands.OpenArgeoUserEditor; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.part.ViewPart; + +/** List all users with filter. */ +public class JcrUsersView extends ViewPart implements ArgeoNames { + public final static String ID = SecurityAdminPlugin.PLUGIN_ID + + ".jcrUsersView"; + + /* DEPENDENCY INJECTION */ + private Session session; + + private UsersTable userTableCmp; + private JcrUserListener userStructureListener; + private JcrUserListener userPropertiesListener; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new FillLayout()); + + // Create the composite that displays the list and a filter + userTableCmp = new UsersTable(parent, SWT.NO_FOCUS, session); + userTableCmp.populate(true, false); + + // Configure + userTableCmp.getTableViewer().addDoubleClickListener( + new ViewDoubleClickListener()); + getViewSite().setSelectionProvider(userTableCmp.getTableViewer()); + + // Add listener to refresh the list when something changes + userStructureListener = new JcrUserListener(getSite().getShell() + .getDisplay()); + JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED + | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null); + userPropertiesListener = new JcrUserListener(getSite().getShell() + .getDisplay()); + JcrUtils.addListener(session, userStructureListener, + Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED + | Event.PROPERTY_REMOVED, + ArgeoJcrConstants.PEOPLE_BASE_PATH, + ArgeoTypes.ARGEO_USER_PROFILE); + } + + @Override + public void setFocus() { + userTableCmp.setFocus(); + } + + @Override + public void dispose() { + JcrUtils.removeListenerQuietly(session, userStructureListener); + JcrUtils.removeListenerQuietly(session, userPropertiesListener); + JcrUtils.logoutQuietly(session); + super.dispose(); + } + + // public void setSession(Session session) { + // this.session = session; + // } + + public void refresh() { + this.getSite().getShell().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + userTableCmp.refresh(); + } + }); + } + + private class JcrUserListener implements EventListener { + private final Display display; + + public JcrUserListener(Display display) { + super(); + this.display = display; + } + + @Override + public void onEvent(EventIterator events) { + display.asyncExec(new Runnable() { + @Override + public void run() { + userTableCmp.refresh(); + } + }); + } + } + + class ViewDoubleClickListener implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent evt) { + if (evt.getSelection().isEmpty()) + return; + + Object obj = ((IStructuredSelection) evt.getSelection()) + .getFirstElement(); + if (obj instanceof Node) { + try { + String username = ((Node) obj).getProperty(ARGEO_USER_ID) + .getString(); + String commandId = OpenArgeoUserEditor.COMMAND_ID; + String paramName = OpenArgeoUserEditor.PARAM_USERNAME; + CommandUtils.callCommand(commandId, paramName, username); + } catch (RepositoryException e) { + throw new ArgeoException("Cannot open user editor", e); + } + } + } + } + + /* DEPENDENCY INJECTION */ + public void setRepository(Repository repository) { + try { + session = repository.login(); + } catch (RepositoryException re) { + throw new ArgeoException("Unable to initialise local session", re); + } + } +} \ No newline at end of file diff --git a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java index ac9792401..73f6a19d6 100644 --- a/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java +++ b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java @@ -15,144 +15,315 @@ */ package org.argeo.security.ui.admin.views; -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.observation.Event; -import javax.jcr.observation.EventIterator; -import javax.jcr.observation.EventListener; +import java.util.ArrayList; +import java.util.List; import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.parts.UsersTable; -import org.argeo.eclipse.ui.workbench.CommandUtils; -import org.argeo.jcr.ArgeoJcrConstants; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.utils.ViewerUtils; import org.argeo.jcr.ArgeoNames; -import org.argeo.jcr.ArgeoTypes; -import org.argeo.jcr.JcrUtils; import org.argeo.security.ui.admin.SecurityAdminPlugin; -import org.argeo.security.ui.admin.commands.OpenArgeoUserEditor; +import org.argeo.security.ui.admin.editors.UserEditor; +import org.argeo.security.ui.admin.editors.UserEditorInput; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.User; +import org.osgi.service.useradmin.UserAdmin; -/** List all users with filter. */ +/** List all users with filter - based on Ldif userAdmin */ public class UsersView extends ViewPart implements ArgeoNames { public final static String ID = SecurityAdminPlugin.PLUGIN_ID - + ".adminUsersView"; + + ".usersView"; /* DEPENDENCY INJECTION */ - private Session session; + private UserAdmin userAdmin; - private UsersTable userTableCmp; - private JcrUserListener userStructureListener; - private JcrUserListener userPropertiesListener; + // UI Objects + private TableViewer usersViewer; + private Text filterTxt; + private Font italic; + private Font bold; - @Override - public void createPartControl(Composite parent) { - parent.setLayout(new FillLayout()); - - // Create the composite that displays the list and a filter - userTableCmp = new UsersTable(parent, SWT.NO_FOCUS, session); - userTableCmp.populate(true, false); + // The displayed columns + /** Overwrite to display other columns */ + public List getColumnsDef() { + List columnDefs = new ArrayList(); - // Configure - userTableCmp.getTableViewer().addDoubleClickListener( - new ViewDoubleClickListener()); - getViewSite().setSelectionProvider(userTableCmp.getTableViewer()); - - // Add listener to refresh the list when something changes - userStructureListener = new JcrUserListener(getSite().getShell() - .getDisplay()); - JcrUtils.addListener(session, userStructureListener, Event.NODE_ADDED - | Event.NODE_REMOVED, ArgeoJcrConstants.PEOPLE_BASE_PATH, null); - userPropertiesListener = new JcrUserListener(getSite().getShell() - .getDisplay()); - JcrUtils.addListener(session, userStructureListener, - Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED - | Event.PROPERTY_REMOVED, - ArgeoJcrConstants.PEOPLE_BASE_PATH, - ArgeoTypes.ARGEO_USER_PROFILE); + // User ID + columnDefs.add(new ColumnDefinition(new UserNameLP(), + "Distinguished Name", 200)); + // Displayed name + columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", + 150)); + // E-mail + columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); + return columnDefs; } @Override public void setFocus() { - userTableCmp.setFocus(); + // TODO Auto-generated method stub } - @Override - public void dispose() { - JcrUtils.removeListenerQuietly(session, userStructureListener); - JcrUtils.removeListenerQuietly(session, userPropertiesListener); - JcrUtils.logoutQuietly(session); - super.dispose(); + protected Viewer getViewer() { + return usersViewer; } - // public void setSession(Session session) { - // this.session = session; - // } + @Override + public void createPartControl(Composite parent) { + // cache UI Objects + italic = EclipseUiUtils.getItalicFont(parent); + bold = EclipseUiUtils.getBoldFont(parent); + + // Main Layout + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + parent.setLayout(layout); + + usersViewer = createTableViewer(parent); + usersViewer.setContentProvider(new UsersContentProvider()); + + // Really? + refreshFilteredList(null); + + // Configure + usersViewer.addDoubleClickListener(new ViewDoubleClickListener()); + getViewSite().setSelectionProvider(usersViewer); + } public void refresh() { this.getSite().getShell().getDisplay().asyncExec(new Runnable() { @Override public void run() { - userTableCmp.refresh(); + refreshFilteredList(null); } }); } - private class JcrUserListener implements EventListener { - private final Display display; - - public JcrUserListener(Display display) { - super(); - this.display = display; - } - - @Override - public void onEvent(EventIterator events) { - display.asyncExec(new Runnable() { - @Override - public void run() { - userTableCmp.refresh(); - } - }); - } - } - class ViewDoubleClickListener implements IDoubleClickListener { public void doubleClick(DoubleClickEvent evt) { if (evt.getSelection().isEmpty()) return; - Object obj = ((IStructuredSelection) evt.getSelection()) .getFirstElement(); - if (obj instanceof Node) { - try { - String username = ((Node) obj).getProperty(ARGEO_USER_ID) - .getString(); - String commandId = OpenArgeoUserEditor.COMMAND_ID; - String paramName = OpenArgeoUserEditor.PARAM_USERNAME; - CommandUtils.callCommand(commandId, paramName, username); - } catch (RepositoryException e) { - throw new ArgeoException("Cannot open user editor", e); - } + User user = (User) obj; + IWorkbenchWindow iww = UsersView.this.getSite() + .getWorkbenchWindow(); + IWorkbenchPage iwp = iww.getActivePage(); + UserEditorInput uei = new UserEditorInput(user.getName()); + + try { + // IEditorPart editor = + iwp.openEditor(uei, UserEditor.ID); + } catch (PartInitException pie) { + throw new ArgeoException("Unable to open UserEditor for " + + user, pie); } } } - /* DEPENDENCY INJECTION */ - public void setRepository(Repository repository) { + private TableViewer createTableViewer(final Composite parent) { + int style = SWT.H_SCROLL | SWT.V_SCROLL; + + Composite tableCmp = new Composite(parent, SWT.NO_FOCUS); + tableCmp.setLayoutData(EclipseUiUtils.fillAll()); + + Table table = new Table(tableCmp, style); + TableViewer viewer = new TableViewer(table); + table.setLinesVisible(true); + table.setHeaderVisible(true); + + TableColumnLayout tableColumnLayout = new TableColumnLayout(); + TableViewerColumn column; + + // Create other columns + List colDefs = getColumnsDef(); + for (ColumnDefinition colDef : colDefs) { + column = ViewerUtils.createTableViewerColumn(viewer, colDef.label, + SWT.NONE, colDef.weight); + column.setLabelProvider(colDef.provider); + tableColumnLayout.setColumnData(column.getColumn(), + new ColumnWeightData(colDef.weight, colDef.minWidth, true)); + } + + tableCmp.setLayout(tableColumnLayout); + return viewer; + } + + @Override + public void dispose() { + super.dispose(); + } + + private class UsersContentProvider implements IStructuredContentProvider { + private static final long serialVersionUID = 1L; + + public Object[] getElements(Object inputElement) { + return (Object[]) inputElement; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + // /* MANAGE FILTER */ + // private void createFilterPart(Composite parent) { + // // Text Area for the filter + // filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH + // | SWT.ICON_CANCEL); + // filterTxt.setMessage(filterHelpMsg); + // filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + // | GridData.HORIZONTAL_ALIGN_FILL)); + // filterTxt.addModifyListener(new ModifyListener() { + // private static final long serialVersionUID = 1L; + // + // public void modifyText(ModifyEvent event) { + // refreshFilteredList(); + // } + // }); + // } + + /** + * Refresh the user list: caller might overwrite in order to display a + * subset of all users, typically to remove current user from the list + */ + protected void refreshFilteredList(String filter) { try { - session = repository.login(); - } catch (RepositoryException re) { - throw new ArgeoException("Unable to initialise local session", re); + Role[] roles = userAdmin.getRoles(filter); + List users = new ArrayList(); + for (Role role : roles) + if (role.getType() == Role.USER && role.getType() != Role.GROUP) + users.add((User) role); + usersViewer.setInput(users.toArray()); + } catch (InvalidSyntaxException e) { + throw new ArgeoException("Unable to get roles with filter: " + + filter, e); + } + } + + // Local helpers + + private abstract class UseradminAbstractLP extends ColumnLabelProvider { + private static final long serialVersionUID = 137336765024922368L; + + @Override + public Font getFont(Object element) { + // TODO manage fonts + // // self + // String username = getProperty(elem, ARGEO_USER_ID); + // if (username.equals(session.getUserID())) + // return bold; + // // disabled + // try { + // Node userProfile = (Node) elem; + // if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean()) + // return italic; + // else + // return null; + // } catch (RepositoryException e) { + // throw new ArgeoException("Cannot get font for " + username, e); + // } + // } + + return super.getFont(element); + } + + @Override + public String getText(Object element) { + User user = (User) element; + return getText(user); + } + + public abstract String getText(User user); + } + + private class UserNameLP extends UseradminAbstractLP { + private static final long serialVersionUID = 6550449442061090388L; + + @Override + public String getText(User user) { + return user.getName(); } } + private class CommonNameLP extends UseradminAbstractLP { + private static final long serialVersionUID = 5256703081044911941L; + + @Override + public String getText(User user) { + Object obj = user.getProperties().get("cn"); + if (obj != null) + return (String) obj; + else + return ""; + } + } + + private class MailLP extends UseradminAbstractLP { + private static final long serialVersionUID = 8329764452141982707L; + + @Override + public String getText(User user) { + Object obj = user.getProperties().get("mail"); + if (obj != null) + return (String) obj; + else + return ""; + } + } + + protected class ColumnDefinition { + protected ColumnLabelProvider provider; + protected String label; + protected int weight; + protected int minWidth; + + // public ColumnDefinition(ColumnLabelProvider provider, String label, + // int weight, int minimumWidth) { + // this.provider = provider; + // this.label = label; + // this.weight = weight; + // this.minWidth = minimumWidth; + // } + + public ColumnDefinition(ColumnLabelProvider provider, String label, + int weight) { + this.provider = provider; + this.label = label; + this.weight = weight; + this.minWidth = weight; + } + } + + protected UserAdmin userAdmin() { + return userAdmin; + } + + /* DEPENDENCY INJECTION */ + public void setUserAdmin(UserAdmin userAdmin) { + this.userAdmin = userAdmin; + } } \ No newline at end of file -- 2.39.2