Introduce ROLE_USER_ADMIN and ROLE_GROUP_ADMIN
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 14 Feb 2015 21:04:53 +0000 (21:04 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 14 Feb 2015 21:04:53 +0000 (21:04 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@7881 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

18 files changed:
org.argeo.cms/bnd.bnd
org.argeo.cms/src/org/argeo/cms/CmsLogin.java
org.argeo.cms/src/org/argeo/cms/KernelHeader.java
org.argeo.cms/src/org/argeo/cms/internal/auth/AnonymousLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/auth/JcrSecurityModel.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
org.argeo.cms/src/org/argeo/cms/internal/useradmin/SimpleJcrSecurityModel.java
org.argeo.cms/src/org/argeo/cms/internal/useradmin/jackrabbit/JackrabbitUserAdminService.java
org.argeo.security.core/src/org/argeo/security/SystemAuthentication.java
org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java
org.argeo.security.core/src/org/argeo/security/core/InternalAuthentication.java
org.argeo.security.ui.admin/plugin.xml
org.argeo.security.ui/plugin.xml
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java

index 459d3e094f5c9a09592ffe64db672752158c68d0..af1220832d27623b4ec5e3086d2f9c95fb4ebd0a 100644 (file)
@@ -8,6 +8,7 @@ org.springframework.context,\
 org.springframework.security.authentication.jaas,\
 org.apache.jackrabbit.api,\
 org.apache.jackrabbit.commons,\
+org.apache.jackrabbit.core.security.user,\
 org.eclipse.*;resolution:=optional,\
 org.eclipse.core.commands;resolution:=optional,\
 org.eclipse.swt;resolution:=optional,\
index e8a2e48fd0523d6417f86514540e13d8e71c78c2..d93a952254d1aa3c233bc3b0c1845b14bc276d3d 100644 (file)
@@ -31,7 +31,7 @@ public class CmsLogin {
                try {
                        List<SimpleGrantedAuthority> anonAuthorities = Collections
                                        .singletonList(new SimpleGrantedAuthority(
-                                                       KernelConstants.ANONYMOUS_USER));
+                                                       KernelHeader.USERNAME_ANONYMOUS));
                        UserDetails anonUser = new User("anonymous", "", true, true, true,
                                        true, anonAuthorities);
                        AnonymousAuthenticationToken anonToken = new AnonymousAuthenticationToken(
index db1034a9051a159f2d84eb63eeb558ddf9772b37..c72a410f078aef4a3fb8356418d2cabdbd13ed5e 100644 (file)
@@ -2,7 +2,19 @@ package org.argeo.cms;
 
 /** Public properties of the CMS Kernel */
 public interface KernelHeader {
+       // LOGIN CONTEXTS
        final static String LOGIN_CONTEXT_USER = "USER";
        final static String LOGIN_CONTEXT_ANONYMOUS = "ANONYMOUS";
        final static String LOGIN_CONTEXT_SYSTEM = "SYSTEM";
+
+       // RESERVED ROLES
+       public final static String ROLE_ADMIN = "ROLE_ADMIN";
+       public final static String ROLE_GROUP_ADMIN = "ROLE_GROUP_ADMIN";
+       public final static String ROLE_USER_ADMIN = "ROLE_USER_ADMIN";
+       public final static String ROLE_USER = "ROLE_USER";
+       public final static String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
+
+       // RESERVED USERNAMES
+       public final static String USERNAME_ADMIN = "root";
+       public final static String USERNAME_ANONYMOUS = "anonymous";
 }
index 6078b8f2bb55b8e993eedd9564278acd6eac474d..372f27e60bc0205ff54d77c8cc729b4430e2bf4d 100644 (file)
@@ -25,16 +25,15 @@ import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginException;
 
+import org.argeo.cms.KernelHeader;
 import org.argeo.cms.internal.kernel.Activator;
 import org.argeo.util.LocaleCallback;
 import org.argeo.util.LocaleUtils;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
 /** Login module which caches one subject per thread. */
 public class AnonymousLoginModule extends AbstractLoginModule {
-       private String anonymousRole = "ROLE_ANONYMOUS";
        /** Comma separated list of locales */
        private String availableLocales = null;
 
@@ -52,8 +51,9 @@ public class AnonymousLoginModule extends AbstractLoginModule {
                        callbackHandler.handle(new Callback[] {});
                }
 
-               List<SimpleGrantedAuthority> authorities = Collections
-                               .singletonList(new SimpleGrantedAuthority(anonymousRole));
+               List<GrantedAuthorityPrincipal> authorities = Collections
+                               .singletonList(new GrantedAuthorityPrincipal(
+                                               KernelHeader.ROLE_ANONYMOUS));
                AnonymousAuthenticationToken anonymousToken = new AnonymousAuthenticationToken(
                                Activator.getSystemKey(), null, authorities);
 
index 2cf1e241a6b1842b793e8e3b601f5a634fd74ea2..ad769222bf90302142898c5a7721b53289d31a2f 100644 (file)
@@ -18,6 +18,7 @@ package org.argeo.cms.internal.auth;
 import java.util.List;
 
 import javax.jcr.Node;
+import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 /**
@@ -25,6 +26,9 @@ import javax.jcr.Session;
  * profile.
  */
 public interface JcrSecurityModel {
+       /** Initialize the JCR security model */
+       public void init(Session adminSession) throws RepositoryException;
+
        /**
         * To be called before user details are loaded. Make sure than any logged in
         * user has a home directory with full access and a profile with information
index 5ec9f5087649474b1fc9284a502a8956070412ef..9a31d089b39c45b6f3d25720571617698165c84d 100644 (file)
@@ -2,6 +2,7 @@ package org.argeo.cms.internal.kernel;
 
 import java.util.UUID;
 
+import org.argeo.security.SystemAuthentication;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
@@ -10,7 +11,11 @@ import org.osgi.framework.BundleContext;
  * access to kernel information for the rest of the bundle (and only it)
  */
 public class Activator implements BundleActivator {
-       private final static String systemKey = UUID.randomUUID().toString();
+       private final static String systemKey;
+       static {
+               systemKey = UUID.randomUUID().toString();
+               System.setProperty(SystemAuthentication.SYSTEM_KEY_PROPERTY, systemKey);
+       }
 
        private static BundleContext bundleContext;
        private Kernel kernel;
@@ -34,7 +39,9 @@ public class Activator implements BundleActivator {
 
        /**
         * Singleton interface to the {@link BundleContext} related to the calling
-        * thread. Can be used only within the CMS bundle.
+        * thread.
+        * 
+        * @BundleScope
         */
        public static BundleContext getBundleContext() {
                return bundleContext;
@@ -43,9 +50,9 @@ public class Activator implements BundleActivator {
        /**
         * @return a String which is guaranteed to be unique between and constant
         *         within a Java static context (typically a VM launch)
+        * @BundleScope
         */
        public final static String getSystemKey() {
                return systemKey;
        }
-
 }
index f2d3995d3e06a101b38d535f4d21f7b07d773a5b..62efa364de3d470cd48b26b976f7be9033375efd 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.cms.internal.kernel;
 
+import java.lang.management.ManagementFactory;
+
 import javax.jcr.RepositoryFactory;
 
 import org.apache.commons.logging.Log;
@@ -24,7 +26,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
  */
 final class Kernel {
        private final static Log log = LogFactory.getLog(Kernel.class);
-//     private static final String PROP_WORKBENCH_AUTOSTART = "org.eclipse.rap.workbenchAutostart";
+       // private static final String PROP_WORKBENCH_AUTOSTART =
+       // "org.eclipse.rap.workbenchAutostart";
 
        private final BundleContext bundleContext;
 
@@ -60,10 +63,13 @@ final class Kernel {
                        throw new ArgeoException("Cannot initialize", e);
                }
 
-               long duration = System.currentTimeMillis() - begin;
-               log.info("## ARGEO CMS UP in " + (duration / 1000) + "."
-                               + (duration % 1000) + "s ##");
-               directorsCut();
+               long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
+               log.info("## ARGEO CMS UP in " + (jvmUptime / 1000) + "."
+                               + (jvmUptime % 1000) + "s ##");
+               long initDuration = System.currentTimeMillis() - begin;
+               if (log.isTraceEnabled())
+                       log.trace("Kernel initialization took " + initDuration + "ms");
+               directorsCut(initDuration);
        }
 
        void destroy() {
@@ -75,25 +81,15 @@ final class Kernel {
 
                // Clean hanging threads from Jackrabbit
                TransientFileFactory.shutdown();
-               
+
                long duration = System.currentTimeMillis() - begin;
                log.info("## ARGEO CMS DOWN in " + (duration / 1000) + "."
                                + (duration % 1000) + "s ##");
        }
 
-//     private void registerWorkbench(final WorkbenchApplicationConfiguration wac) {
-//             new Thread("Worbench Launcher") {
-//                     public void run() {
-//                             Hashtable<String, String> props = new Hashtable<String, String>();
-//                             props.put(ApplicationLauncher.PROPERTY_CONTEXT_NAME, "ui");
-//                             workbenchReg = bundleContext.registerService(
-//                                             ApplicationConfiguration.class, wac, props);
-//                     }
-//             }.start();
-//     }
-
-       private void directorsCut() {
-               final long ms = 128l + (long) (Math.random() * 128d);
+       private void directorsCut(long initDuration) {
+               // final long ms = 128l + (long) (Math.random() * 128d);
+               long ms = initDuration / 10;
                log.info("Spend " + ms + "ms"
                                + " reflecting on the progress brought to mankind"
                                + " by Free Software...");
index eab67785e9da8eef436e15a4ab5ae7323e085dec..79fd1f77a40b086e733ae4c0c5ce39ad3d7b0c0d 100644 (file)
@@ -18,15 +18,8 @@ public interface KernelConstants {
 
        // Security
        final static String DEFAULT_SECURITY_KEY = "argeo";
-       final static String ANONYMOUS_USER = "anonymous";
-       final static String ADMIN_USER = "root";
        final static String JAAS_CONFIG = "/org/argeo/cms/internal/kernel/jaas.cfg";
 
-       // Roles
-       final static String ROLE_USER = "ROLE_USER";
-       final static String ROLE_ADMIN = "ROLE_ADMIN";
-       final static String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
-
        // DAV
        final static String WEBDAV_CONFIG = "/org/argeo/cms/internal/kernel/webdav-config.xml";
        final static String PATH_DATA = "/data";
index ba2a352a74dd334f14bd55edc1b22bb0fcfbc95b..80c166e0a9db33fddfe94594ac842adbc1df4c59 100644 (file)
@@ -13,17 +13,19 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.logging.Log;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.KernelHeader;
+import org.argeo.cms.internal.auth.GrantedAuthorityPrincipal;
 import org.osgi.framework.BundleContext;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 
+/** Package utilities */
 class KernelUtils implements KernelConstants {
-       final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
+       private final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
 
        static Dictionary<String, ?> asDictionary(Properties props) {
                Hashtable<String, Object> hashtable = new Hashtable<String, Object>();
@@ -52,10 +54,11 @@ class KernelUtils implements KernelConstants {
        // Security
        static void anonymousLogin(AuthenticationManager authenticationManager) {
                try {
-                       List<SimpleGrantedAuthority> anonAuthorities = Collections
-                                       .singletonList(new SimpleGrantedAuthority(ROLE_ANONYMOUS));
-                       UserDetails anonUser = new User(ANONYMOUS_USER, "", true, true,
-                                       true, true, anonAuthorities);
+                       List<GrantedAuthorityPrincipal> anonAuthorities = Collections
+                                       .singletonList(new GrantedAuthorityPrincipal(
+                                                       KernelHeader.ROLE_ANONYMOUS));
+                       UserDetails anonUser = new User(KernelHeader.USERNAME_ANONYMOUS,
+                                       "", true, true, true, true, anonAuthorities);
                        AnonymousAuthenticationToken anonToken = new AnonymousAuthenticationToken(
                                        DEFAULT_SECURITY_KEY, anonUser, anonAuthorities);
                        Authentication authentication = authenticationManager
index f0fbe461a1dfc8ecc5d5c5be3862c60587d48983..f3a90ebfdb76b60a57b3df2613ae1332b125f423 100644 (file)
@@ -8,7 +8,6 @@ import java.util.StringTokenizer;
 import javax.servlet.FilterChain;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -22,7 +21,6 @@ import org.argeo.jackrabbit.servlet.RemotingServlet;
 import org.argeo.jackrabbit.servlet.WebdavServlet;
 import org.argeo.jcr.ArgeoJcrConstants;
 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
-import org.eclipse.jetty.servlets.DoSFilter;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.http.NamespaceException;
 import org.osgi.util.tracker.ServiceTracker;
@@ -295,19 +293,19 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                }
        }
 
-       class CustomDosFilter extends DoSFilter {
-               @Override
-               protected String extractUserId(ServletRequest request) {
-                       HttpSession httpSession = ((HttpServletRequest) request)
-                                       .getSession();
-                       if (isSessionAuthenticated(httpSession)) {
-                               String userId = ((SecurityContext) httpSession
-                                               .getAttribute(SPRING_SECURITY_CONTEXT_KEY))
-                                               .getAuthentication().getName();
-                               return userId;
-                       }
-                       return super.extractUserId(request);
-
-               }
-       }
+       // class CustomDosFilter extends DoSFilter {
+       // @Override
+       // protected String extractUserId(ServletRequest request) {
+       // HttpSession httpSession = ((HttpServletRequest) request)
+       // .getSession();
+       // if (isSessionAuthenticated(httpSession)) {
+       // String userId = ((SecurityContext) httpSession
+       // .getAttribute(SPRING_SECURITY_CONTEXT_KEY))
+       // .getAuthentication().getName();
+       // return userId;
+       // }
+       // return super.extractUserId(request);
+       //
+       // }
+       // }
 }
index c39f9e56d105c9b15b249eb02b24ba0eb8a5d5bc..7c4685304b0d16bd67909b74f4616e153f5fa145 100644 (file)
@@ -25,6 +25,7 @@ import javax.jcr.security.Privilege;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.core.security.user.UserAccessControlProvider;
 import org.argeo.ArgeoException;
 import org.argeo.cms.internal.auth.JcrSecurityModel;
 import org.argeo.jcr.ArgeoJcrConstants;
@@ -45,6 +46,20 @@ public class SimpleJcrSecurityModel implements JcrSecurityModel {
 
        /** The home base path. */
        private String homeBasePath = "/home";
+       private String peopleBasePath = ArgeoJcrConstants.PEOPLE_BASE_PATH;
+
+       @Override
+       public void init(Session adminSession) throws RepositoryException {
+               JcrUtils.mkdirs(adminSession, homeBasePath);
+
+               JcrUtils.mkdirs(adminSession, peopleBasePath);
+               JcrUtils.addPrivilege(adminSession, peopleBasePath,
+                               UserAccessControlProvider.USER_ADMIN_GROUP_NAME,
+                               Privilege.JCR_ALL);
+               // JcrUtils.addPrivilege(adminSession, "/",
+               // UserAccessControlProvider.USER_ADMIN_GROUP_NAME,
+               // Privilege.JCR_READ);
+       }
 
        public synchronized Node sync(Session session, String username,
                        List<String> roles) {
@@ -79,8 +94,7 @@ public class SimpleJcrSecurityModel implements JcrSecurityModel {
                        Node userProfile = UserJcrUtils.getUserProfile(session, username);
                        // new user
                        if (userProfile == null) {
-                               String personPath = generateUserPath(
-                                               ArgeoJcrConstants.PEOPLE_BASE_PATH, username);
+                               String personPath = generateUserPath(peopleBasePath, username);
                                Node personBase = JcrUtils.mkdirs(session, personPath);
                                userProfile = personBase.addNode(ArgeoNames.ARGEO_PROFILE);
                                userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE);
index e7f44943b08501bb43b5daab506c8ea3a01859af..d35f996f49e7e78b074119748fa5ed70d2545f8e 100644 (file)
@@ -20,7 +20,9 @@ import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
+import org.apache.jackrabbit.core.security.user.UserAccessControlProvider;
 import org.argeo.ArgeoException;
+import org.argeo.cms.KernelHeader;
 import org.argeo.cms.internal.auth.GrantedAuthorityPrincipal;
 import org.argeo.cms.internal.auth.JcrSecurityModel;
 import org.argeo.jcr.JcrUtils;
@@ -46,15 +48,14 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
  */
 public class JackrabbitUserAdminService implements UserAdminService,
                AuthenticationProvider {
-       final static String userRole = "ROLE_USER";
-       final static String adminRole = "ROLE_ADMIN";
+       private final static String JACKR_ADMINISTRATORS = "administrators";
+       private final static String REP_PRINCIPAL_NAME = "rep:principalName";
 
        private Repository repository;
        private JcrSecurityModel securityModel;
 
        private JackrabbitSession adminSession = null;
 
-       private String superUsername = "root";
        private String superUserInitialPassword = "demo";
 
        public void init() throws RepositoryException {
@@ -62,18 +63,20 @@ public class JackrabbitUserAdminService implements UserAdminService,
                                .getAuthentication();
                authentication.getName();
                adminSession = (JackrabbitSession) repository.login();
-               Authorizable adminGroup = getUserManager().getAuthorizable(adminRole);
+               securityModel.init(adminSession);
+               Authorizable adminGroup = getUserManager().getAuthorizable(
+                               KernelHeader.ROLE_ADMIN);
                if (adminGroup == null) {
-                       adminGroup = getUserManager().createGroup(adminRole);
+                       adminGroup = getUserManager().createGroup(KernelHeader.ROLE_ADMIN);
                        adminSession.save();
                }
-               Authorizable superUser = getUserManager()
-                               .getAuthorizable(superUsername);
+               Authorizable superUser = getUserManager().getAuthorizable(
+                               KernelHeader.USERNAME_ADMIN);
                if (superUser == null) {
-                       superUser = getUserManager().createUser(superUsername,
-                                       superUserInitialPassword);
+                       superUser = getUserManager().createUser(
+                                       KernelHeader.USERNAME_ADMIN, superUserInitialPassword);
                        ((Group) adminGroup).addMember(superUser);
-                       securityModel.sync(adminSession, superUsername, null);
+                       securityModel.sync(adminSession, KernelHeader.USERNAME_ADMIN, null);
                        adminSession.save();
                }
        }
@@ -131,27 +134,49 @@ public class JackrabbitUserAdminService implements UserAdminService,
 
                        List<String> roles = new ArrayList<String>();
                        for (GrantedAuthority ga : userDetails.getAuthorities()) {
-                               if (ga.getAuthority().equals(userRole))
+                               if (ga.getAuthority().equals(KernelHeader.ROLE_USER))
                                        continue;
                                roles.add(ga.getAuthority());
                        }
 
-                       for (Iterator<Group> it = user.memberOf(); it.hasNext();) {
+                       groups: for (Iterator<Group> it = user.memberOf(); it.hasNext();) {
                                Group group = it.next();
-                               if (roles.contains(group.getPrincipal().getName()))
-                                       roles.remove(group.getPrincipal().getName());
-                               else
+                               String groupName = group.getPrincipal().getName();
+                               String role = groupNameToRole(groupName);
+                               if (role == null)
+                                       continue groups;
+
+                               if (roles.contains(role))
+                                       roles.remove(role);
+                               else {
                                        group.removeMember(user);
+                                       if (role.equals(KernelHeader.ROLE_ADMIN)) {
+                                               Group administratorsGroup = ((Group) getUserManager()
+                                                               .getAuthorizable(JACKR_ADMINISTRATORS));
+                                               if (administratorsGroup.isDeclaredMember(user))
+                                                       administratorsGroup.removeMember(user);
+                                       }
+                               }
                        }
 
-                       // remaining (new ones)
+                       // remaining (new memberships)
                        for (String role : roles) {
-                               Group group = (Group) getUserManager().getAuthorizable(role);
+                               String groupName = roleToGroupName(role);
+                               Group group = (Group) getUserManager().getAuthorizable(
+                                               groupName);
                                if (group == null)
                                        throw new ArgeoException("Group " + role
                                                        + " does not exist,"
                                                        + " whereas it was granted to user " + userDetails);
                                group.addMember(user);
+
+                               // add to Jackrabbit administrators
+                               if (role.equals(KernelHeader.ROLE_ADMIN)) {
+                                       Group administratorsGroup = (Group) getUserManager()
+                                                       .getAuthorizable(JACKR_ADMINISTRATORS);
+                                       administratorsGroup.addMember(user);
+                               }
+
                        }
                } catch (Exception e) {
                        throw new ArgeoException("Cannot update user details", e);
@@ -252,9 +277,13 @@ public class JackrabbitUserAdminService implements UserAdminService,
                LinkedHashSet<String> res = new LinkedHashSet<String>();
                try {
                        Iterator<Authorizable> groups = getUserManager().findAuthorizables(
-                                       "rep:principalName", null, UserManager.SEARCH_TYPE_GROUP);
+                                       REP_PRINCIPAL_NAME, null, UserManager.SEARCH_TYPE_GROUP);
                        while (groups.hasNext()) {
-                               res.add(groups.next().getPrincipal().getName());
+                               Group group = (Group) groups.next();
+                               String groupName = group.getPrincipal().getName();
+                               String role = groupNameToRole(groupName);
+                               if (role != null && !role.equals(KernelHeader.ROLE_GROUP_ADMIN))
+                                       res.add(role);
                        }
                        return res;
                } catch (RepositoryException e) {
@@ -271,6 +300,32 @@ public class JackrabbitUserAdminService implements UserAdminService,
                }
        }
 
+       protected String roleToGroupName(String role) {
+               String groupName;
+               if (role.equals(KernelHeader.ROLE_USER_ADMIN))
+                       groupName = UserAccessControlProvider.USER_ADMIN_GROUP_NAME;
+               else if (role.equals(KernelHeader.ROLE_GROUP_ADMIN))
+                       groupName = UserAccessControlProvider.GROUP_ADMIN_GROUP_NAME;
+               else
+                       groupName = role;
+               return groupName;
+       }
+
+       protected String groupNameToRole(String groupName) {
+               String role;
+               if (groupName.equals(UserAccessControlProvider.USER_ADMIN_GROUP_NAME)) {
+                       role = KernelHeader.ROLE_USER_ADMIN;
+               } else if (groupName
+                               .equals(UserAccessControlProvider.GROUP_ADMIN_GROUP_NAME)) {
+                       role = KernelHeader.ROLE_GROUP_ADMIN;
+               } else if (groupName.equals(JACKR_ADMINISTRATORS)) {
+                       return null;
+               } else {
+                       role = groupName;
+               }
+               return role;
+       }
+
        @Override
        public UserDetails loadUserByUsername(String username)
                        throws UsernameNotFoundException, DataAccessException {
@@ -290,16 +345,28 @@ public class JackrabbitUserAdminService implements UserAdminService,
                if (username == null)
                        username = session.getUserID();
                User user = (User) getUserManager().getAuthorizable(username);
+
                ArrayList<GrantedAuthorityPrincipal> authorities = new ArrayList<GrantedAuthorityPrincipal>();
-               // FIXME make it more generic
-               authorities.add(new GrantedAuthorityPrincipal("ROLE_USER"));
-               Iterator<Group> groups = user.declaredMemberOf();
+               authorities.add(new GrantedAuthorityPrincipal(KernelHeader.ROLE_USER));
+
+               Group adminGroup = (Group) getUserManager().getAuthorizable(
+                               KernelHeader.ROLE_ADMIN);
+
+               Iterator<? extends Authorizable> groups;
+               if (username.equals(KernelHeader.USERNAME_ADMIN)
+                               || adminGroup.isDeclaredMember(user)) {
+                       groups = getUserManager().findAuthorizables(REP_PRINCIPAL_NAME,
+                                       null, UserManager.SEARCH_TYPE_GROUP);
+               } else {
+                       groups = user.declaredMemberOf();
+               }
+
                while (groups.hasNext()) {
-                       Group group = groups.next();
-                       // String role = "ROLE_"
-                       // + group.getPrincipal().getName().toUpperCase();
-                       String role = group.getPrincipal().getName();
-                       authorities.add(new GrantedAuthorityPrincipal(role));
+                       Authorizable group = groups.next();
+                       String groupName = group.getPrincipal().getName();
+                       String role = groupNameToRole(groupName);
+                       if (role != null)
+                               authorities.add(new GrantedAuthorityPrincipal(role));
                }
 
                Node userProfile = UserJcrUtils.getUserProfile(session, username);
index 2722c1f7d1339249de3622db96e84aa89ac4bdb3..d489761e5ed210f32189906240eba6c7f07ecf25 100644 (file)
@@ -19,5 +19,8 @@ package org.argeo.security;
  * Marks a system authentication, that is which did not require a login process.
  */
 public interface SystemAuthentication {
-
+       /** 'admin' for consistency with JCR */
+       public final static String USERNAME_SYSTEM = "admin";
+       public final static String ROLE_SYSTEM = "ROLE_SYSTEM";
+       public final static String SYSTEM_KEY_PROPERTY = "argeo.security.systemKey";
 }
index bdd110da97ac2b44a6f8570cf61de9f5af601b44..3acf26c8a1d3097f0336aea0d1c0051556d477dc 100644 (file)
@@ -73,7 +73,7 @@ public abstract class AbstractSystemExecution {
 
                String key = systemAuthenticationKey != null ? systemAuthenticationKey
                                : System.getProperty(
-                                               InternalAuthentication.SYSTEM_KEY_PROPERTY,
+                                               SystemAuthentication.SYSTEM_KEY_PROPERTY,
                                                InternalAuthentication.SYSTEM_KEY_DEFAULT);
                if (key == null)
                        throw new ArgeoException("No system key defined");
index ee5e145bacb6b5a80492e86d5c14b748dff15756..31e29d18d773f6d338559af2397ae7f8990b2f10 100644 (file)
@@ -25,10 +25,6 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
 public class InternalAuthentication extends UsernamePasswordAuthenticationToken
                implements SystemAuthentication {
        private static final long serialVersionUID = -6783376375615949315L;
-       /** 'admin' for consistency with JCR */
-       public final static String DEFAULT_SYSTEM_USERNAME = "admin";
-       public final static String DEFAULT_SYSTEM_ROLE = "ROLE_SYSTEM";
-       public final static String SYSTEM_KEY_PROPERTY = "argeo.security.systemKey";
        public final static String SYSTEM_KEY_DEFAULT = "argeo";
 
        public InternalAuthentication(String key, String systemUsername,
@@ -38,7 +34,7 @@ public class InternalAuthentication extends UsernamePasswordAuthenticationToken
        }
 
        public InternalAuthentication(String key) {
-               this(key, DEFAULT_SYSTEM_USERNAME, DEFAULT_SYSTEM_ROLE);
+               this(key, SystemAuthentication.USERNAME_SYSTEM, SystemAuthentication.ROLE_SYSTEM);
        }
 
 }
index e260bdea40c18e9ab7a9ca6a11c5b87a44edf66b..f7c18f5e9fb1265fb8b219d679844a4fede2673d 100644 (file)
   </extension>
   <extension
            point="org.eclipse.ui.activities">
-        <!-- TODO: find a way to exclude evrything -->
-        <activityPatternBinding
-              activityId="org.argeo.security.ui.adminActivity"
+       <activityPatternBinding
+              activityId="org.argeo.security.ui.userAdminActivity"
               isEqualityPattern="true"
               pattern="org.argeo.security.ui.admin/org.argeo.security.ui.admin.adminSecurityPerspective">
         </activityPatternBinding>
+        <activityPatternBinding
+              activityId="org.argeo.security.ui.groupAdminActivity"
+              isEqualityPattern="true"
+              pattern="org.argeo.security.ui.admin/org.argeo.security.ui.admin.adminRolesView">
+        </activityPatternBinding>
      </extension>
  </plugin>
index 24fb40a44df7a6bcaa709c975955a737398703fc..7d18541af3589eeaee7f194791e3ce4316997c22 100644 (file)
                    </with>
                  </enabledWhen>
         </activity>
+        <activity
+              description="User Admins"
+              id="org.argeo.security.ui.userAdminActivity"
+              name="User Admin">
+                 <enabledWhen>
+                   <with variable="roles">
+                     <iterate ifEmpty="false" operator="or">
+                       <equals value="ROLE_USER_ADMIN" />
+                     </iterate>
+                   </with>
+                 </enabledWhen>
+        </activity>
+        <activity
+              description="Group Admins"
+              id="org.argeo.security.ui.groupAdminActivity"
+              name="User Admin">
+                 <enabledWhen>
+                   <with variable="roles">
+                     <iterate ifEmpty="false" operator="or">
+                       <equals value="ROLE_GROUP_ADMIN" />
+                     </iterate>
+                   </with>
+                 </enabledWhen>
+        </activity>
         <activity
               description="Non admins"
               id="org.argeo.security.ui.notAdminActivity"
index c1addf1622a873a2f888f828e58a771e151083d3..a9f97d44eb0bacd9bcfa651812eda5265b60591e 100644 (file)
@@ -28,7 +28,6 @@ import java.util.Map;
 import javax.jcr.Credentials;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;