jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r881215 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/ main/java/org/apache/jackrabbit/core/security/authorization/acl/ main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ main/java...
Date Tue, 17 Nov 2009 09:43:11 GMT
Author: angela
Date: Tue Nov 17 09:43:10 2009
New Revision: 881215

URL: http://svn.apache.org/viewvc?rev=881215&view=rev
Log:
JCR-2313 - Improvements to user management (2) [work in progress] 

- remove 'administrators' group from set of pre-installed users as it has no special meaning
   neither within the user administration nor within the ac-evaluation code.

- remove SystemUserManager and move the special admin-handling to the UserManagerImpl
- add explicit check for uuid-conflict to UserManagerImpl#createAuthorizableNode
- make sure the admin-user is properly recreated upon reconfiguration of the usersPath (UserManager
config) 
- make sure the admin-user is created in case of other uuid-conflict

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/DefaultSecurityManager.java
Tue Nov 17 09:43:10 2009
@@ -37,7 +37,6 @@
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.core.config.AccessManagerConfig;
 import org.apache.jackrabbit.core.config.LoginModuleConfig;
 import org.apache.jackrabbit.core.config.SecurityConfig;
@@ -58,7 +57,6 @@
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
 import org.apache.jackrabbit.core.security.principal.DefaultPrincipalProvider;
-import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.core.security.principal.PrincipalManagerImpl;
 import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
 import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
@@ -360,7 +358,7 @@
         }
 
         /*
-         Fallback szenario to retrieve userID from the subject:
+         Fallback scenario to retrieve userID from the subject:
          Since the subject may contain multiple principals and the principal
          name may not be equals to the UserID, the id is retrieved by
          searching for the corresponding authorizable and if this doesn't
@@ -453,21 +451,17 @@
         // only the system session assigned with that workspace will get the
         // system user manager (special implementation that asserts the existance
         // of the admin user).
-        if (session == systemSession) {
-            return new SystemUserManager(systemSession, params);
+        UserManagerImpl um;
+        if (umc != null) {
+            Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class,
Properties.class };
+            um = (UserManagerImpl) umc.getUserManager(UserManagerImpl.class, paramTypes,
(SessionImpl) session, adminId, params);
+            // TODO: should we make sure the implementation doesn't allow
+            // TODO: to change the autosave behavior? since the user manager
+            // TODO: writes to a separate workspace this would cause troubles.
         } else {
-            UserManagerImpl um;
-            if (umc != null) {
-                Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class,
Properties.class };
-                um = (UserManagerImpl) umc.getUserManager(UserManagerImpl.class, paramTypes,
(SessionImpl) session, adminId, params);
-                // TODO: should we make sure the implementation doesn't allow
-                // TODO: to change the autosave behavior? since the user manager
-                // TODO: writes to a separate workspace this would cause troubles.
-            } else {
-                um = new UserManagerImpl(session, adminId, params);
-            }
-            return um;
+            um = new UserManagerImpl(session, adminId, params);
         }
+        return um;
     }
 
     /**
@@ -569,8 +563,7 @@
     }
 
     /**
-     * Make sure the 'administrators' group exists and the user with the
-     * configured (or default) adminID is member of this user-group.
+     * Make sure the sytem users (admin and anonymous) exist.
      *
      * @param userManager Manager to create users/groups.
      * @param session
@@ -595,38 +588,20 @@
             }
         }
 
-        // assume administrators groupID and principalName are the same.
-        // and avoid retrieving group by principal.
-        Group admins = (Group) userManager.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME);
-        if (admins == null) {
-            admins = userManager.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME));
-            if (!userManager.isAutoSave()) {
-                session.save();
-            }
-            log.info("... created administrators group with name '"+SecurityConstants.ADMINISTRATORS_NAME+"'");
-        }
-
-        try {
-            if (admins != null && admins.addMember(admin)) {
-                if (!userManager.isAutoSave()) {
-                    session.save();
-                }
-                log.info("... added admin '" + adminId + "' as member of the administrators
group.");
-            }
-        } catch (RepositoryException e) {
-            // administrator has full permissions anyway. just log a
-            // warning and ignore the error.
-            log.warn("Unexpected error while adding admin to the administrators group", e);
-        }
-
         if (anonymousId != null) {
             Authorizable anonymous = userManager.getAuthorizable(anonymousId);
             if (anonymous == null) {
-                userManager.createUser(anonymousId, "");
-                if (!userManager.isAutoSave()) {
-                    session.save();
+                try {
+                    userManager.createUser(anonymousId, "");
+                    if (!userManager.isAutoSave()) {
+                        session.save();
+                    }
+                    log.info("... created anonymous user with id \'" + anonymousId + "\'
...");
+                } catch (RepositoryException e) {
+                    // exception while creating the anonymous user.
+                    // log an error but don't abort the repository start-up
+                    log.error("Failed to create anonymous user.", e);
                 }
-                log.info("... created anonymous-user with id \'" + anonymousId + "\' ...");
             }
         }
     }
@@ -662,39 +637,4 @@
             return prov.canAccessRoot(principals);
         }
     }
-
-    /**
-     * System user manager that (re) creates the admin user in case it doesn't
-     * exist yet (upon initial startup) or has been deleted.
-     */
-    protected final class  SystemUserManager extends UserManagerImpl {
-
-        private final SystemSession session;
-        private String adminPw;
-
-        protected SystemUserManager(SystemSession session, Properties config) throws RepositoryException
{
-            super(session, adminId, config);
-            this.session = session;
-            adminPw = adminId; // The default value as defined upon #createSystemUsers
-        }
-
-        @Override
-        public Authorizable getAuthorizable(String id) throws RepositoryException {
-            Authorizable a = super.getAuthorizable(id);
-            if (a == null && adminId.equals(id)) {
-                log.info("Admin user does not exist.");
-                a = createAdmin(adminId, adminPw);
-            }
-            return a;
-        }
-
-        private User createAdmin(String adminId, String pw) throws RepositoryException {
-            User admin = createUser(adminId, pw);
-            if (!isAutoSave()) {
-                session.save();
-            }
-            log.info("... created admin user with id \'" + adminId + "\' and default pw.");
-            return admin;
-        }
-    }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManager.java
Tue Nov 17 09:43:10 2009
@@ -57,7 +57,7 @@
  * a distinct pp-registry for each workspace.
  * </p>
  * NOTE: While this security manager asserts that a minimal set of system
- * users (admin, administrators group and anonymous) is present in each workspace
+ * users (admin and anonymous) is present in each workspace
  * it doesn't make any attempt to set or define the access permissions on the
  * tree containing user related information. 
  */
@@ -224,16 +224,12 @@
         
         // in contrast to the DefaultSecurityManager users are not retrieved
         // from a dedicated workspace: the system session of each workspace must
-        // get a system user manager that asserts the existance of the admin user.
-        if (session instanceof SystemSession) {
-            return new SystemUserManager((SystemSession) session, params);
+        // get a system user manager that asserts the existence of the admin user.
+        if (umc != null) {
+            Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class,
Properties.class };
+            return (UserPerWorkspaceUserManager) umc.getUserManager(UserPerWorkspaceUserManager.class,
paramTypes, (SessionImpl) session, adminId, params);
         } else {
-            if (umc != null) {
-                Class<?>[] paramTypes = new Class[] { SessionImpl.class, String.class,
Properties.class };
-                return (UserPerWorkspaceUserManager) umc.getUserManager(UserPerWorkspaceUserManager.class,
paramTypes, (SessionImpl) session, adminId, params);
-            } else {
-                return new UserPerWorkspaceUserManager(session, adminId, params);
-            }
+            return new UserPerWorkspaceUserManager(session, adminId, params);
         }
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
Tue Nov 17 09:43:10 2009
@@ -56,7 +56,6 @@
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.security.authorization.UnmodifiableAccessControlList;
-import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
 import org.apache.jackrabbit.util.Text;
@@ -288,27 +287,25 @@
                 PrincipalManager pMgr = session.getPrincipalManager();
                 AccessControlManager acMgr = session.getAccessControlManager();
 
-                log.debug("... Privilege.ALL for administrators.");
-                Principal administrators;
                 String pName = SecurityConstants.ADMINISTRATORS_NAME;
                 if (pMgr.hasPrincipal(pName)) {
-                    administrators = pMgr.getPrincipal(pName);
+                    Principal administrators = pMgr.getPrincipal(pName);
+                    log.debug("... Privilege.ALL for administrators.");
+                    Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_ALL)};
+                    acl.addAccessControlEntry(administrators, privs);
                 } else {
-                    log.warn("Administrators principal group is missing.");
-                    administrators = new PrincipalImpl(pName);
+                    log.info("Administrators principal group is missing -> omitting initialization
of default permissions.");
                 }
-                Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_ALL)};
-                acl.addAccessControlEntry(administrators, privs);
 
                 Principal everyone = pMgr.getEveryone();
                 log.debug("... Privilege.READ for everyone.");
-                privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_READ)};
+                Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_READ)};
                 acl.addAccessControlEntry(everyone, privs);
 
                 editor.setPolicy(rootPath, acl);
                 session.save();
             } else {
-                log.warn("No applicable ACL available for the root node -> skip initialization
of the root node's ACL.");
+                log.info("No applicable ACL available for the root node -> skip initialization
of the root node's ACL.");
             }
         } catch (RepositoryException e) {
             log.error("Failed to set-up minimal access control for root node of workspace
" + session.getWorkspace().getName());

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
Tue Nov 17 09:43:10 2009
@@ -128,15 +128,14 @@
                 AccessControlManager acMgr = session.getAccessControlManager();
 
                 // initial default permissions for the administrators group             
  
-                Principal administrators;
                 String pName = SecurityConstants.ADMINISTRATORS_NAME;
                 if (pMgr.hasPrincipal(pName)) {
-                    administrators = pMgr.getPrincipal(pName);
+                    Principal administrators = pMgr.getPrincipal(pName);
                     installDefaultPermissions(administrators,
                         new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_ALL)},
                         restrictions, editor);
                 } else {
-                    log.warn("Administrators principal group is missing -> Not adding
default permissions.");
+                    log.info("Administrators principal group is missing -> Not adding
default permissions.");
                 }
 
                 // initialize default permissions for the everyone group

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
Tue Nov 17 09:43:10 2009
@@ -28,6 +28,7 @@
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.SessionListener;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.core.security.SystemPrincipal;
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.util.Text;
@@ -232,6 +233,11 @@
     private final boolean compatibleJR16;
 
     /**
+     * boolean flag indicating whether the editing session is a system session.
+     */
+    private final boolean isSystemUserManager;
+
+    /**
      * Create a new <code>UserManager</code> with the default configuration.
      *
      * @param session The editing/reading session.
@@ -285,6 +291,17 @@
         }
         authResolver = nr;
         authResolver.setSearchRoots(usersPath, groupsPath);
+
+        /**
+         * evaluate if the editing session is a system session. since the
+         * SystemSession class is package protected the session object cannot
+         * be checked for the property instance.
+         * 
+         * workaround: compare the class name and check if the subject contains
+         * the system principal.
+         */
+        isSystemUserManager = "org.apache.jackrabbit.core.SystemSession".equals(session.getClass().getName())
&& 
+                !session.getSubject().getPrincipals(SystemPrincipal.class).isEmpty();
     }
     
     /**
@@ -317,7 +334,21 @@
         if (id == null || id.length() == 0) {
             throw new IllegalArgumentException("Invalid authorizable name '" + id + "'");
         }
-        return internalGetAuthorizable(id);
+        Authorizable a = internalGetAuthorizable(id);
+        /**
+         * Extra check for the existance of the administrator user that must
+         * always exist.
+         * In case it got removed if must be recreated using a system session.
+         * Since a regular session may lack read permission on the admin-user's
+         * node an explicit test for the current editing session being
+         * a system session is performed.
+         */
+        if (a == null && adminId.equals(id) && isSystemUserManager) {
+            log.info("Admin user does not exist.");
+            a = createAdmin();
+        }
+
+        return a;
     }
 
     /**
@@ -711,6 +742,53 @@
     }
 
     /**
+     * Create the administrator user. If the node to be created collides
+     * with an existing node (ItemExistsException) the existing node gets removed
+     * and the admin user node is (re)created.
+     * <p/>
+     * Collision with an existing node may occur under the following circumstances:
+     *
+     * <ul>
+     * <li>The <code>usersPath</code> has been modified in the user manager
+     * configuration after a successful repository start that already created
+     * the administrator user.</li>
+     * <li>The NodeId created by {@link #buildNodeId(String)} by conincidence
+     * collides with another NodeId created during the regular node creation
+     * process.</li>
+     * </ul>
+     *
+     * @param adminId
+     * @param pw
+     * @return
+     * @throws RepositoryException
+     */
+    private User createAdmin() throws RepositoryException {
+        User admin;
+        try {
+            admin = createUser(adminId, adminId);
+            if (!isAutoSave()) {
+                session.save();
+            }
+            log.info("... created admin user with id \'" + adminId + "\' and default pw.");
+        } catch (ItemExistsException e) {
+            NodeImpl conflictingNode = session.getNodeById(buildNodeId(adminId));
+            String conflictPath = conflictingNode.getPath();
+            log.error("Detected conflicting node " + conflictPath + " of node type " + conflictingNode.getPrimaryNodeType().getName()
+ ".");
+
+            // TODO move conflicting node of type rep:User instead of removing and recreating.
+            conflictingNode.remove();
+            log.info("Removed conflicting node at " + conflictPath);
+
+            admin = createUser(adminId, adminId);
+            if (!isAutoSave()) {
+                session.save();
+            }
+            log.info("Resolved conflict and (re)created admin user with id \'" + adminId
+ "\' and default pw.");          
+        }
+        return admin;
+    }
+
+    /**
      * Creates a UUID from the given <code>id</code> String that is converted
      * to lower case before.
      *
@@ -1022,7 +1100,6 @@
                 folder = createIntermediateFolderNodes(id, escapedId, folder);
             }
 
-            // finally create the authorizable node
             Name nodeName = session.getQName(escapedId);
             Name ntName = (isGroup) ? NT_REP_GROUP : NT_REP_USER;
             NodeId nid = buildNodeId(id);
@@ -1038,11 +1115,20 @@
                     // asserts that only rep:authorizable folders exist.
                     // similarly collisions with existing authorizable have been
                     // checked.
-                    String msg = "Failed to create authorizable node: Detected conflicting
node of unexpected nodetype '" + colliding.getPrimaryNodeType().getName() + "'.";
+                    String msg = "Failed to create authorizable with id '" + id + "' : Detected
conflicting node of unexpected nodetype '" + colliding.getPrimaryNodeType().getName() + "'.";
                     log.error(msg);
                     throw new ConstraintViolationException(msg);
                 }
             }
+
+            // check for collision with existing node outside of the user/group tree
+            if (session.getItemManager().itemExists(nid)) {
+                String msg = "Failed to create authorizable with id '" + id + "' : Detected
conflict with existing node (NodeID: " + nid + ")";
+                log.error(msg);
+                throw new ItemExistsException(msg);
+            }
+
+            // finally create the authorizable node
             return addNode((NodeImpl) folder, nodeName, ntName, nid);
         }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/UserPerWorkspaceSecurityManagerTest.java
Tue Nov 17 09:43:10 2009
@@ -22,7 +22,6 @@
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.apache.jackrabbit.api.security.user.Authorizable;
 import org.apache.jackrabbit.core.security.JackrabbitSecurityManager;
-import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 import org.apache.jackrabbit.test.NotExecutableException;
 import org.apache.jackrabbit.util.Text;
@@ -89,14 +88,13 @@
         // must therefore succeed.
         Session s = getHelper().getSuperuserSession(altWsp);
         try {
-            // admin/anonymous/administrators must be present
+            // admin/anonymous must be present
             String adminId = ((UserPerWorkspaceSecurityManager) secMgr).adminId;
             assertEquals(adminId, s.getUserID());
 
             UserManager umgr = ((JackrabbitSession) s).getUserManager();
             assertNotNull(umgr.getAuthorizable(adminId));
             assertNotNull(umgr.getAuthorizable(((UserPerWorkspaceSecurityManager) secMgr).anonymousId));
-            assertNotNull(umgr.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME));
 
         } finally {
             s.logout();

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/AdministratorTest.java
Tue Nov 17 09:43:10 2009
@@ -18,15 +18,21 @@
 
 import org.apache.jackrabbit.api.security.user.AbstractUserTest;
 import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.api.security.user.User;
 import org.apache.jackrabbit.core.NodeImpl;
-import org.apache.jackrabbit.core.security.SecurityConstants;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
 import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
+import org.apache.jackrabbit.spi.Name;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import java.util.Properties;
 
 /**
  * <code>AdministratorTest</code>...
@@ -55,13 +61,6 @@
         assertTrue(admin.getPrincipal() instanceof AdminPrincipal);
     }
 
-    public void testMemberOfAdministrators() throws RepositoryException {
-        Authorizable admins = userMgr.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME);
-        if (admins != null && admins.isGroup()) {
-            assertTrue(((Group) admins).isMember(userMgr.getAuthorizable(adminId)));
-        }
-    }
-
     public void testRemoveSelf() throws RepositoryException, NotExecutableException {
         Authorizable admin = userMgr.getAuthorizable(adminId);
         if (admin == null) {
@@ -75,6 +74,13 @@
         }
     }
 
+    /**
+     * Test if the administrator is recreated upon login if the corresponding
+     * node gets removed.
+     *
+     * @throws RepositoryException
+     * @throws NotExecutableException
+     */
     public void testRemoveAdminNode() throws RepositoryException, NotExecutableException
{
         Authorizable admin = userMgr.getAuthorizable(adminId);
 
@@ -106,11 +112,11 @@
 
     /**
      * Test for collisions that would prevent from recreate the admin user.
-     * 
+     *
      * @throws RepositoryException
      * @throws NotExecutableException
      */
-    public void testCollidingAdminNode() throws RepositoryException, NotExecutableException
{
+    public void testAdminNodeCollidingWithAuthorizableFolder() throws RepositoryException,
NotExecutableException {
         Authorizable admin = userMgr.getAuthorizable(adminId);
 
         if (admin == null || !(admin instanceof AuthorizableImpl)) {
@@ -131,7 +137,7 @@
 
         Session s2 = null;
         try {
-            // no create a colliding node:
+            // now create a colliding node:
             parentNode.addNode(adminNodeName, "rep:AuthorizableFolder");
             s.save();
 
@@ -156,4 +162,110 @@
             }
         }
     }
+
+    /**
+     * Test if creation of the administrator user forces the removal of some
+     * other node in the repository that by change happens to have the same
+     * jcr:uuid and thus inhibits the creation of the admininstrator user.
+     */
+    public void testAdminNodeCollidingWithRandomNode() throws RepositoryException, NotExecutableException
{
+        Authorizable admin = userMgr.getAuthorizable(adminId);
+
+        if (admin == null || !(admin instanceof AuthorizableImpl)) {
+            throw new NotExecutableException();
+        }
+
+        // access the node corresponding to the admin user and remove it
+        NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+        NodeId nid = adminNode.getNodeId();
+        String adminPath = adminNode.getPath();
+
+        Session s = adminNode.getSession();
+        adminNode.remove();
+        // use session obtained from the node as usermgr may point to a dedicated
+        // system workspace different from the superusers workspace.
+        s.save();
+
+        Session s2 = null;
+        String collidingPath = null;
+        try {
+            // create a colliding node outside of the user tree
+            NameResolver nr = (SessionImpl) s;
+            NodeImpl tr = (NodeImpl) s.getRootNode();
+            Node n = tr.addNode(nr.getQName(nodeName1), nr.getQName(testNodeType), nid);
+            collidingPath = n.getPath();
+            s.save();
+
+            // force recreation of admin user.
+            s2 = getHelper().getSuperuserSession();
+
+            admin = userMgr.getAuthorizable(adminId);
+            assertNotNull(admin);
+            // the colliding node must have been removed.
+            assertFalse(s2.nodeExists(collidingPath));
+
+        } finally {
+            if (s2 != null) {
+                s2.logout();
+            }
+            if (collidingPath != null && s.nodeExists(collidingPath)) {
+                s.getNode(collidingPath).remove();
+                s.save();
+            }
+        }
+    }
+
+    /**
+     * Reconfiguration of the user-root-path will result in node collision
+     * upon initialization of the built-in repository users. Test if the
+     * UserManagerImpl in this case removes the colliding admin-user node.
+     */
+    public void testChangeUserRootPath() throws RepositoryException, NotExecutableException
{
+        Authorizable admin = userMgr.getAuthorizable(adminId);
+
+        if (admin == null || !(admin instanceof AuthorizableImpl)) {
+            throw new NotExecutableException();
+        }
+
+        // access the node corresponding to the admin user and remove it
+        NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+        NodeId nid = adminNode.getNodeId();
+        Name nName = adminNode.getQName();
+        Name ntName = ((NodeTypeImpl) adminNode.getPrimaryNodeType()).getQName();
+
+        Session s = adminNode.getSession();
+        adminNode.remove();
+        // use session obtained from the node as usermgr may point to a dedicated
+        // system workspace different from the superusers workspace.
+        s.save();
+
+        Session s2 = null;
+        String collidingPath = null;
+        try {
+            // create a colliding user node outside of the user tree
+            Properties props = new Properties();
+            props.setProperty("usersPath", "/testPath");
+            UserManager um = new UserManagerImpl((SessionImpl) s, adminId, props);
+            User collidingUser = um.createUser(adminId, adminId);
+            collidingPath = ((AuthorizableImpl) collidingUser).getNode().getPath();
+            s.save();
+
+            // force recreation of admin user.
+            s2 = getHelper().getSuperuserSession();
+
+            admin = userMgr.getAuthorizable(adminId);
+            assertNotNull(admin);
+            // the colliding node must have been removed.
+            assertFalse(s2.nodeExists(collidingPath));
+
+        } finally {
+            if (s2 != null) {
+                s2.logout();
+            }
+            if (collidingPath != null && s.nodeExists(collidingPath)) {
+                s.getNode(collidingPath).remove();
+                s.save();
+            }
+        }
+    }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserImporterTest.java
Tue Nov 17 09:43:10 2009
@@ -30,6 +30,7 @@
 import org.apache.jackrabbit.core.config.ImportConfig;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.core.security.user.UserImporter.ImportBehavior;
+import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.core.util.ReferenceChangeTracker;
 import org.apache.jackrabbit.core.xml.ProtectedPropertyImporter;
 import org.apache.jackrabbit.core.xml.SessionImporter;
@@ -89,6 +90,8 @@
     private SessionImpl sImpl;
     private UserManagerImpl umgr;
 
+    private String groupIdToRemove;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -121,6 +124,14 @@
             sImpl.getNode(path).remove();
         }
         sImpl.save();
+
+        Authorizable administrators = umgr.getAuthorizable(SecurityConstants.ADMINISTRATORS_NAME);
+        if (administrators == null) {
+            groupIdToRemove = umgr.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME)).getID();
+            sImpl.save();
+        } else if (!administrators.isGroup()) {
+            throw new NotExecutableException("Expected " + administrators.getID() + " to
be a group.");
+        }
     }
 
     @Override
@@ -136,6 +147,12 @@
             if (sImpl.nodeExists(path)) {
                 sImpl.getNode(path).remove();
             }
+            if (groupIdToRemove != null) {
+                Authorizable a = umgr.getAuthorizable(groupIdToRemove);
+                if (a != null) {
+                    a.remove();
+                }
+            }
             sImpl.save();
         }
         super.tearDown();
@@ -770,7 +787,7 @@
             NodeImpl target = (NodeImpl) sImpl.getNode(umgr.getGroupsPath());
             try {
                 doImport(target, xml, UserImporter.ImportBehavior.ABORT);
-                // importbehavior ABORT -> should throw.
+                // import behavior ABORT -> should throw.
                 fail("importing invalid members -> must throw.");
             } catch (SAXException e) {
                 // success as well

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/user/UserManagerImplTest.java
Tue Nov 17 09:43:10 2009
@@ -470,7 +470,6 @@
         }
     }
 
-
     public void testCreateWithRelativePath() throws Exception {
         Principal p = getTestPrincipal();
         String uid = p.getName();

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java?rev=881215&r1=881214&r2=881215&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/xml/AccessControlImporterTest.java
Tue Nov 17 09:43:10 2009
@@ -19,12 +19,16 @@
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.commons.xml.ParsingContentHandler;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.config.ImportConfig;
 import org.apache.jackrabbit.core.security.authorization.AccessControlConstants;
 import org.apache.jackrabbit.core.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.core.security.SecurityConstants;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 import org.apache.jackrabbit.test.NotExecutableException;
 import org.xml.sax.SAXException;
@@ -545,6 +549,18 @@
             throw new NotExecutableException();
         }
 
+        PrincipalManager pmgr = sImpl.getPrincipalManager();
+        if (!pmgr.hasPrincipal(SecurityConstants.ADMINISTRATORS_NAME)) {
+            UserManager umgr = sImpl.getUserManager();
+            umgr.createGroup(new PrincipalImpl(SecurityConstants.ADMINISTRATORS_NAME));
+            if (!umgr.isAutoSave()) {
+                sImpl.save();
+            }
+            if (pmgr.hasPrincipal(SecurityConstants.ADMINISTRATORS_NAME)) {
+                throw new NotExecutableException();
+            }
+        }
+
 
         NodeImpl target;
         NodeImpl root = (NodeImpl) sImpl.getRootNode();



Mime
View raw message