First draft to adapt Security Admin UI to the new security model
authorBruno Sinou <bsinou@argeo.org>
Wed, 2 Sep 2015 19:44:06 +0000 (19:44 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 2 Sep 2015 19:44:06 +0000 (19:44 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@8362 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

23 files changed:
org.argeo.security.ui.admin/META-INF/spring/editors.xml
org.argeo.security.ui.admin/META-INF/spring/osgi.xml
org.argeo.security.ui.admin/META-INF/spring/views.xml
org.argeo.security.ui.admin/plugin.xml
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminImages.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/SecurityAdminPerspective.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/UserAdminConstants.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/AddRole.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteRole.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/DeleteUser.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/OpenArgeoUserEditor.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/commands/RefreshUsersList.java
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java [deleted file]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/GroupMainPage.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/JcrArgeoUserEditor.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditor.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserEditorInput.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/UserMainPage.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/GroupsView.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrRolesView.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrUsersView.java [new file with mode: 0644]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/RolesView.java [deleted file]
org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/UsersView.java

index 740792a61b3c16a0b0860c89504a25e8b47c8f00..ac7441b939d4546d4f8192db5cd94210e7feb3f3 100644 (file)
@@ -4,8 +4,17 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
+
        <!-- Editors -->
-       <bean id="adminArgeoUserEditor" class="org.argeo.security.ui.admin.editors.ArgeoUserEditor"
+       <bean id="userEditor" class="org.argeo.security.ui.admin.editors.UserEditor"
+               scope="prototype">
+               <property name="userAdmin" ref="userAdmin" />
+       </bean>
+
+       <!-- <bean id="groupEditor" class="org.argeo.security.ui.admin.editors.GroupEditor" 
+               scope="prototype"> <property name="userAdmin" ref="userAdmin" /> </bean> -->
+       <!-- LEGACY -->
+       <bean id="adminArgeoUserEditor" class="org.argeo.security.ui.admin.editors.JcrArgeoUserEditor"
                scope="prototype">
                <property name="userAdminService" ref="userAdminService" />
                <property name="repository" ref="nodeRepository" />
index 2fa51446ccf2625aadfc3dfcc68d72fedfb6ee73..b4c52fc4f18a8e084b8ad01d7b805dd9c3849794 100644 (file)
@@ -11,4 +11,8 @@
        <reference id="nodeRepository" interface="javax.jcr.Repository"\r
                filter="(argeo.jcr.repository.alias=node)" />\r
        <reference id="userAdminService" interface="org.argeo.security.UserAdminService" />\r
+       \r
+       <!-- new useradmin -->\r
+       <reference id="userAdmin" interface="org.osgi.service.useradmin.UserAdmin" />\r
+\r
 </beans:beans>
\ No newline at end of file
index 655b0c8e34468cf2c8ea58cd7b00b0993bf32bb1..86168e0a803123e76d55bb16a00f1fbda8db91b9 100644 (file)
@@ -4,11 +4,21 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
-       <bean id="adminUsersView" class="org.argeo.security.ui.admin.views.UsersView"
+       <bean id="usersView" class="org.argeo.security.ui.admin.views.UsersView"
+               scope="prototype">
+               <property name="userAdmin" ref="userAdmin" />
+       </bean>
+
+       <bean id="groupsView" class="org.argeo.security.ui.admin.views.GroupsView"
+               scope="prototype">
+               <property name="userAdmin" ref="userAdmin" />
+       </bean>
+
+       <!-- LEGACY. TODO: Remove -->
+       <bean id="jcrUsersView" class="org.argeo.security.ui.admin.views.JcrUsersView"
                scope="prototype">
                <property name="repository" ref="nodeRepository" />
        </bean>
-       
        <bean id="adminRolesView" class="org.argeo.security.ui.admin.views.RolesView"
                scope="prototype">
                <property name="userAdminService" ref="userAdminService" />
index f7c18f5e9fb1265fb8b219d679844a4fede2673d..c9dacd420f775f59af7e06756cc7f570b8ea03db 100644 (file)
             name="Security">
       </perspective>
    </extension>
+   
    <extension
-         point="org.eclipse.ui.views">
+               point="org.eclipse.ui.views">
       <view
             class="org.argeo.eclipse.spring.SpringExtensionFactory"
             icon="icons/users.gif"
-            id="org.argeo.security.ui.admin.adminUsersView"
+            id="org.argeo.security.ui.admin.usersView"
+            name="Users"
+            restorable="true">
+      </view>
+      <view
+            class="org.argeo.eclipse.spring.SpringExtensionFactory"
+            icon="icons/role.gif"
+            id="org.argeo.security.ui.admin.groupsView"
+            name="Groups"
+            restorable="false">
+      </view>
+      
+      <!-- Legacy -->
+      <view
+            class="org.argeo.eclipse.spring.SpringExtensionFactory"
+            icon="icons/users.gif"
+            id="org.argeo.security.ui.admin.jcrUsersView"
             name="Users"
             restorable="false">
       </view>
       <view
             class="org.argeo.eclipse.spring.SpringExtensionFactory"
             icon="icons/role.gif"
-            id="org.argeo.security.ui.admin.adminRolesView"
+            id="org.argeo.security.ui.admin.jcrRolesView"
             name="Roles"
             restorable="false">
       </view>
-   </extension>
-   <extension
-           point="org.eclipse.ui.editors">
-               <editor
-                 class="org.argeo.eclipse.spring.SpringExtensionFactory"
-              id="org.argeo.security.ui.admin.adminArgeoUserEditor"
-              name="User"
-              icon="icons/user.gif"
-              default="false">
-        </editor>
-     </extension>
+       </extension>
+       
+       <!-- Editors -->
+       <extension
+               point="org.eclipse.ui.editors">
+               <editor
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+            id="org.argeo.security.ui.admin.userEditor"
+            name="User"
+            icon="icons/user.gif"
+            default="false">
+               </editor>
+               <!-- Legacy -->
+               <editor
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+            id="org.argeo.security.ui.admin.adminArgeoUserEditor"
+            name="User"
+            icon="icons/user.gif"
+                       default="false">
+               </editor>
+       </extension>
+    
     <extension
          point="org.eclipse.ui.commands">
       <command
             </command>
         </menuContribution>
   </extension>
+  
   <extension
            point="org.eclipse.ui.activities">
        <activityPatternBinding
               pattern="org.argeo.security.ui.admin/org.argeo.security.ui.admin.adminRolesView">
         </activityPatternBinding>
      </extension>
- </plugin>
+ </plugin>
\ No newline at end of file
index f7ffa9c8dbb145edc477bf6fd3638706ddf491e1..e7cd5df464190440032759528eabf264fffedff1 100644 (file)
  */
 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();
+
 }
index c743f56bd27d4b2237c11baf104873622a6f2964..082fba9098f2c7e7c1d78411221ed757125ae307 100644 (file)
  */
 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 (file)
index 0000000..f17800b
--- /dev/null
@@ -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";
+       
+}
index a1008f6994e83a0e7293f2b5ea407e66c5fe447b..56946e76b48d191c4d94cd1fb046571216042d15 100644 (file)
@@ -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();
                        }
index 6cba11eb9078e5ded33dcb631cb6ee442dbe3296..7648e26180caa216b6c26499a3583a3e935fe5a4 100644 (file)
@@ -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;
        }
index ccf360fd045adcf9a38a026fa5484975bbb5ba50..dbff6e57672a7a6304f6239a0d03178b9be776d8 100644 (file)
@@ -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;
        }
index bae928c221abfe5770fdf61ae1b48c6e5540efa6..fe8cefa5f5011046537bcca0e310b58370d5f894 100644 (file)
@@ -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);
                }
index e4c14ab21b6ad0b3c2fe9aa83e11a5b7cbb9cf63..fd98e718f2d453359b891bd686979425c1b30e30 100644 (file)
@@ -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/ArgeoUserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/ArgeoUserEditor.java
deleted file mode 100644 (file)
index d822929..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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 javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
-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.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.forms.editor.FormEditor;
-import org.springframework.security.core.GrantedAuthority;
-
-/** Editor for an Argeo user. */
-public class ArgeoUserEditor extends FormEditor {
-       private static final long serialVersionUID = 1933296330339252869L;
-
-       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
-                       + ".adminArgeoUserEditor";
-
-       /* DEPENDENCY INJECTION */
-       private Session session;
-       private UserAdminService userAdminService;
-
-       // private Node userHome;
-       private Node userProfile;
-       private JcrUserDetails userDetails;
-
-       public void init(IEditorSite site, IEditorInput input)
-                       throws PartInitException {
-               super.init(site, input);
-               String username = ((ArgeoUserEditorInput) getEditorInput())
-                               .getUsername();
-               userProfile = UserJcrUtils.getUserProfile(session, username);
-
-               if (userAdminService.userExists(username)) {
-                       try {
-                               userDetails = (JcrUserDetails) userAdminService
-                                               .loadUserByUsername(username);
-                       } catch (Exception e) {
-                               throw new ArgeoException("Cannot retrieve userDetails for "
-                                               + username, e);
-                       }
-               } else {
-                       try {
-                               userDetails = new JcrUserDetails(session, username, null,
-                                               new ArrayList<GrantedAuthority>());
-                       } catch (RepositoryException e) {
-                               throw new ArgeoException("Cannot retrieve disabled JCR profile");
-                       }
-               }
-
-               this.setPartProperty("name", username != null ? username : "<new user>");
-               setPartName(username != null ? username : "<new user>");
-       }
-
-       protected void addPages() {
-               try {
-                       addPage(new DefaultUserMainPage(this, userProfile));
-                       addPage(new UserRolesPage(this, userDetails, userAdminService));
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot add pages", e);
-               }
-       }
-
-       @Override
-       public void doSave(IProgressMonitor monitor) {
-               // list pages
-               // TODO: make it more generic
-               DefaultUserMainPage defaultUserMainPage = (DefaultUserMainPage) findPage(DefaultUserMainPage.ID);
-               if (defaultUserMainPage.isDirty()) {
-                       defaultUserMainPage.doSave(monitor);
-                       String newPassword = defaultUserMainPage.getNewPassword();
-                       defaultUserMainPage.resetNewPassword();
-                       if (newPassword != null)
-                               userDetails = userDetails.cloneWithNewPassword(newPassword);
-               }
-
-               UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
-               if (userRolesPage.isDirty()) {
-                       userRolesPage.doSave(monitor);
-                       userDetails = userDetails.cloneWithNewRoles(userRolesPage
-                                       .getRoles());
-               }
-
-               userAdminService.updateUser(userDetails);
-
-               // if (userAdminService.userExists(user.getUsername()))
-               // userAdminService.updateUser(user);
-               // else {
-               // userAdminService.newUser(user);
-               // setPartName(user.getUsername());
-               // }
-               firePropertyChange(PROP_DIRTY);
-
-               userRolesPage.setUserDetails(userDetails);
-
-               // FIXME rather use a refresh command. Fails when called by another
-               // view.
-               // refresh users view
-               IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
-               UsersView usersView = (UsersView) iw.getActiveWorkbenchWindow()
-                               .getActivePage().findView(UsersView.ID);
-               if (usersView != null)
-                       usersView.refresh();
-       }
-
-       @Override
-       public void doSaveAs() {
-       }
-
-       @Override
-       public boolean isSaveAsAllowed() {
-               return false;
-       }
-
-       public void refresh() {
-               UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
-               userRolesPage.refresh();
-       }
-
-       @Override
-       public void dispose() {
-               JcrUtils.logoutQuietly(session);
-               super.dispose();
-       }
-
-       /* DEPENDENCY INJECTION */
-       public void setUserAdminService(UserAdminService userAdminService) {
-               this.userAdminService = userAdminService;
-       }
-
-       public void setRepository(Repository repository) {
-               try {
-                       session = repository.login();
-               } catch (RepositoryException re) {
-                       throw new ArgeoException("Unable to initialise local session", re);
-               }
-       }
-}
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 (file)
index 0000000..3d75b56
--- /dev/null
@@ -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<ColumnDefinition> getColumnsDef() {
+               List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+
+               // 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<ColumnDefinition> 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<User> users = new ArrayList<User>();
+               // // 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/JcrArgeoUserEditor.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/editors/JcrArgeoUserEditor.java
new file mode 100644 (file)
index 0000000..83d59e6
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * 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 javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+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.JcrUsersView;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.springframework.security.core.GrantedAuthority;
+
+/** Editor for an Argeo user. */
+public class JcrArgeoUserEditor extends FormEditor {
+       private static final long serialVersionUID = 1933296330339252869L;
+
+       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+                       + ".adminArgeoUserEditor";
+
+       /* DEPENDENCY INJECTION */
+       private Session session;
+       private UserAdminService userAdminService;
+
+       // private Node userHome;
+       private Node userProfile;
+       private JcrUserDetails userDetails;
+
+       public void init(IEditorSite site, IEditorInput input)
+                       throws PartInitException {
+               super.init(site, input);
+               String username = ((ArgeoUserEditorInput) getEditorInput())
+                               .getUsername();
+               userProfile = UserJcrUtils.getUserProfile(session, username);
+
+               if (userAdminService.userExists(username)) {
+                       try {
+                               userDetails = (JcrUserDetails) userAdminService
+                                               .loadUserByUsername(username);
+                       } catch (Exception e) {
+                               throw new ArgeoException("Cannot retrieve userDetails for "
+                                               + username, e);
+                       }
+               } else {
+                       try {
+                               userDetails = new JcrUserDetails(session, username, null,
+                                               new ArrayList<GrantedAuthority>());
+                       } catch (RepositoryException e) {
+                               throw new ArgeoException("Cannot retrieve disabled JCR profile");
+                       }
+               }
+
+               this.setPartProperty("name", username != null ? username : "<new user>");
+               setPartName(username != null ? username : "<new user>");
+       }
+
+       protected void addPages() {
+               try {
+                       addPage(new DefaultUserMainPage(this, userProfile));
+                       addPage(new UserRolesPage(this, userDetails, userAdminService));
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot add pages", e);
+               }
+       }
+
+       @Override
+       public void doSave(IProgressMonitor monitor) {
+               // list pages
+               // TODO: make it more generic
+               DefaultUserMainPage defaultUserMainPage = (DefaultUserMainPage) findPage(DefaultUserMainPage.ID);
+               if (defaultUserMainPage.isDirty()) {
+                       defaultUserMainPage.doSave(monitor);
+                       String newPassword = defaultUserMainPage.getNewPassword();
+                       defaultUserMainPage.resetNewPassword();
+                       if (newPassword != null)
+                               userDetails = userDetails.cloneWithNewPassword(newPassword);
+               }
+
+               UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
+               if (userRolesPage.isDirty()) {
+                       userRolesPage.doSave(monitor);
+                       userDetails = userDetails.cloneWithNewRoles(userRolesPage
+                                       .getRoles());
+               }
+
+               userAdminService.updateUser(userDetails);
+
+               // if (userAdminService.userExists(user.getUsername()))
+               // userAdminService.updateUser(user);
+               // else {
+               // userAdminService.newUser(user);
+               // setPartName(user.getUsername());
+               // }
+               firePropertyChange(PROP_DIRTY);
+
+               userRolesPage.setUserDetails(userDetails);
+
+               // FIXME rather use a refresh command. Fails when called by another
+               // view.
+               // refresh users view
+               IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
+               JcrUsersView usersView = (JcrUsersView) iw.getActiveWorkbenchWindow()
+                               .getActivePage().findView(JcrUsersView.ID);
+               if (usersView != null)
+                       usersView.refresh();
+       }
+
+       
+       
+       @Override
+       public void doSaveAs() {
+       }
+
+       @Override
+       public boolean isSaveAsAllowed() {
+               return false;
+       }
+
+       public void refresh() {
+               UserRolesPage userRolesPage = (UserRolesPage) findPage(UserRolesPage.ID);
+               userRolesPage.refresh();
+       }
+
+       @Override
+       public void dispose() {
+               JcrUtils.logoutQuietly(session);
+               super.dispose();
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setUserAdminService(UserAdminService userAdminService) {
+               this.userAdminService = userAdminService;
+       }
+
+       public void setRepository(Repository repository) {
+               try {
+                       session = repository.login();
+               } catch (RepositoryException re) {
+                       throw new ArgeoException("Unable to initialise local session", re);
+               }
+       }
+}
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 (file)
index 0000000..7518b80
--- /dev/null
@@ -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 (file)
index 0000000..7f07827
--- /dev/null
@@ -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 : "<new user>";
+       }
+
+       public IPersistableElement getPersistable() {
+               return null;
+       }
+
+       public String getToolTipText() {
+               return username != null ? username : "<new user>";
+       }
+
+       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 (file)
index 0000000..812cbe9
--- /dev/null
@@ -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 (file)
index 0000000..34bda0e
--- /dev/null
@@ -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<ColumnDefinition> getColumnsDef() {
+               List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+               // 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<User> users = new ArrayList<User>();
+                       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/JcrRolesView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/JcrRolesView.java
new file mode 100644 (file)
index 0000000..a874543
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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 org.argeo.ArgeoException;
+import org.argeo.security.UserAdminService;
+import org.argeo.security.ui.admin.SecurityAdminPlugin;
+import org.argeo.security.ui.admin.commands.AddRole;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+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.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.part.ViewPart;
+
+/** List all roles. */
+public class JcrRolesView extends ViewPart {
+       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
+                       + ".jcrRolesView";
+
+       private Text newRole;
+
+       private TableViewer viewer;
+       private UserAdminService userAdminService;
+
+       private String addNewRoleText = "<add new role here>";
+
+       @Override
+       public void createPartControl(Composite parent) {
+               parent.setLayout(new GridLayout(1, false));
+
+               // new role text field
+               newRole = new Text(parent, SWT.BORDER);
+               newRole.setText(addNewRoleText);
+               newRole.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               // default action is add role
+               newRole.addListener(SWT.DefaultSelection, new Listener() {
+                       private static final long serialVersionUID = -2367261849260929505L;
+
+                       public void handleEvent(Event evt) {
+                               IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
+                               IHandlerService handlerService = (IHandlerService) iw
+                                               .getService(IHandlerService.class);
+                               try {
+                                       handlerService.executeCommand(AddRole.COMMAND_ID, evt);
+                               } catch (Exception e) {
+                                       throw new ArgeoException("Cannot execute add role command",
+                                                       e);
+                               }
+                       }
+               });
+               // select all on focus
+               newRole.addListener(SWT.FocusIn, new Listener() {
+                       private static final long serialVersionUID = 2612811281477034356L;
+
+                       public void handleEvent(Event e) {
+                               newRole.selectAll();
+                       }
+               });
+
+               // roles table
+               Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
+               table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               table.setLinesVisible(false);
+               table.setHeaderVisible(false);
+               viewer = new TableViewer(table);
+               viewer.setContentProvider(new RolesContentProvider());
+               viewer.setLabelProvider(new UsersLabelProvider());
+               getViewSite().setSelectionProvider(viewer);
+               viewer.setInput(getViewSite());
+       }
+
+       @Override
+       public void setFocus() {
+               viewer.getTable().setFocus();
+       }
+
+       public void setUserAdminService(UserAdminService userAdminService) {
+               this.userAdminService = userAdminService;
+       }
+
+       public String getAddNewRoleText() {
+               return addNewRoleText;
+       }
+
+       private class RolesContentProvider implements IStructuredContentProvider {
+               private static final long serialVersionUID = 7446442682717419289L;
+
+               public Object[] getElements(Object inputElement) {
+                       return userAdminService.listEditableRoles().toArray();
+               }
+
+               public void dispose() {
+               }
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               }
+
+       }
+
+       private class UsersLabelProvider extends LabelProvider implements
+                       ITableLabelProvider {
+               private static final long serialVersionUID = -1886204791002421430L;
+
+               public String getColumnText(Object element, int columnIndex) {
+                       return element.toString();
+               }
+
+               public Image getColumnImage(Object element, int columnIndex) {
+                       return null;
+               }
+
+       }
+
+       public String getNewRole() {
+               return newRole.getText();
+       }
+
+       public void refresh() {
+               viewer.refresh();
+               newRole.setText(addNewRoleText);
+       }
+}
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 (file)
index 0000000..1c4224d
--- /dev/null
@@ -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/RolesView.java b/org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/views/RolesView.java
deleted file mode 100644 (file)
index c35e104..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 org.argeo.ArgeoException;
-import org.argeo.security.UserAdminService;
-import org.argeo.security.ui.admin.SecurityAdminPlugin;
-import org.argeo.security.ui.admin.commands.AddRole;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-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.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.handlers.IHandlerService;
-import org.eclipse.ui.part.ViewPart;
-
-/** List all roles. */
-public class RolesView extends ViewPart {
-       public final static String ID = SecurityAdminPlugin.PLUGIN_ID
-                       + ".adminRolesView";
-
-       private Text newRole;
-
-       private TableViewer viewer;
-       private UserAdminService userAdminService;
-
-       private String addNewRoleText = "<add new role here>";
-
-       @Override
-       public void createPartControl(Composite parent) {
-               parent.setLayout(new GridLayout(1, false));
-
-               // new role text field
-               newRole = new Text(parent, SWT.BORDER);
-               newRole.setText(addNewRoleText);
-               newRole.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-               // default action is add role
-               newRole.addListener(SWT.DefaultSelection, new Listener() {
-                       private static final long serialVersionUID = -2367261849260929505L;
-
-                       public void handleEvent(Event evt) {
-                               IWorkbench iw = SecurityAdminPlugin.getDefault().getWorkbench();
-                               IHandlerService handlerService = (IHandlerService) iw
-                                               .getService(IHandlerService.class);
-                               try {
-                                       handlerService.executeCommand(AddRole.COMMAND_ID, evt);
-                               } catch (Exception e) {
-                                       throw new ArgeoException("Cannot execute add role command",
-                                                       e);
-                               }
-                       }
-               });
-               // select all on focus
-               newRole.addListener(SWT.FocusIn, new Listener() {
-                       private static final long serialVersionUID = 2612811281477034356L;
-
-                       public void handleEvent(Event e) {
-                               newRole.selectAll();
-                       }
-               });
-
-               // roles table
-               Table table = new Table(parent, SWT.V_SCROLL | SWT.BORDER);
-               table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-               table.setLinesVisible(false);
-               table.setHeaderVisible(false);
-               viewer = new TableViewer(table);
-               viewer.setContentProvider(new RolesContentProvider());
-               viewer.setLabelProvider(new UsersLabelProvider());
-               getViewSite().setSelectionProvider(viewer);
-               viewer.setInput(getViewSite());
-       }
-
-       @Override
-       public void setFocus() {
-               viewer.getTable().setFocus();
-       }
-
-       public void setUserAdminService(UserAdminService userAdminService) {
-               this.userAdminService = userAdminService;
-       }
-
-       public String getAddNewRoleText() {
-               return addNewRoleText;
-       }
-
-       private class RolesContentProvider implements IStructuredContentProvider {
-               private static final long serialVersionUID = 7446442682717419289L;
-
-               public Object[] getElements(Object inputElement) {
-                       return userAdminService.listEditableRoles().toArray();
-               }
-
-               public void dispose() {
-               }
-
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-               }
-
-       }
-
-       private class UsersLabelProvider extends LabelProvider implements
-                       ITableLabelProvider {
-               private static final long serialVersionUID = -1886204791002421430L;
-
-               public String getColumnText(Object element, int columnIndex) {
-                       return element.toString();
-               }
-
-               public Image getColumnImage(Object element, int columnIndex) {
-                       return null;
-               }
-
-       }
-
-       public String getNewRole() {
-               return newRole.getText();
-       }
-
-       public void refresh() {
-               viewer.refresh();
-               newRole.setText(addNewRoleText);
-       }
-}
index ac979240183a07825c56be5e7dd91b746cd5f5a5..73f6a19d6f1417315ef98da5fbc1105e4ae5fd9f 100644 (file)
  */
 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<ColumnDefinition> getColumnsDef() {
+               List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
 
-               // 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<ColumnDefinition> 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<User> users = new ArrayList<User>();
+                       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