You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2013/12/02 11:45:42 UTC
svn commit: r1546953 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/
main/java/org/apache/jackrabbit/core/security/user/
test/java/org/apache/jackrabbit/core/security/user/
Author: angela
Date: Mon Dec 2 10:45:41 2013
New Revision: 1546953
URL: http://svn.apache.org/r1546953
Log:
JCR-3702 : NPE if user w/o read permission on admin user node removes any node
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.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/security/user/AdministratorTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=1546953&r1=1546952&r2=1546953&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java Mon Dec 2 10:45:41 2013
@@ -43,7 +43,6 @@ import org.apache.jackrabbit.core.nodety
import org.apache.jackrabbit.core.retention.RetentionRegistry;
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.authorization.Permission;
-import org.apache.jackrabbit.core.security.user.UserManagerImpl;
import org.apache.jackrabbit.core.session.SessionContext;
import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.state.ItemState;
@@ -934,10 +933,6 @@ public class BatchedItemOperations exten
throw new RepositoryException("Unable to perform removal. Node is affected by a retention.");
}
}
-
- if (UserManagerImpl.includesAdmin(context.getSessionImpl().getItemManager().getNode(targetPath))) {
- throw new RepositoryException("Attempt to remove/move the admin user.");
- }
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java?rev=1546953&r1=1546952&r2=1546953&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemValidator.java Mon Dec 2 10:45:41 2013
@@ -33,7 +33,6 @@ import org.apache.jackrabbit.core.nodety
import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.security.authorization.Permission;
-import org.apache.jackrabbit.core.security.user.UserManagerImpl;
import org.apache.jackrabbit.core.session.SessionContext;
import org.apache.jackrabbit.core.session.SessionOperation;
import org.apache.jackrabbit.core.state.NodeState;
@@ -303,10 +302,6 @@ public class ItemValidator {
throw new RepositoryException("Unable to perform operation. Node is affected by a retention.");
}
}
-
- if (isRemoval && item.isNode() && UserManagerImpl.includesAdmin((NodeImpl) item)) {
- throw new RepositoryException("Attempt to remove/move the admin user.");
- }
}
public synchronized boolean canModify(
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=1546953&r1=1546952&r2=1546953&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 Mon Dec 2 10:45:41 2013
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.core.security.user;
-import org.apache.jackrabbit.api.JackrabbitRepository;
import org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
@@ -1154,20 +1153,6 @@ public class UserManagerImpl extends Pro
}
}
- //--------------------------------------------------------------------------
- public static boolean includesAdmin(NodeImpl node) throws RepositoryException {
- SessionImpl s = (SessionImpl) node.getSession();
- if (s.getRepository().getDescriptorValue(JackrabbitRepository.OPTION_USER_MANAGEMENT_SUPPORTED).getBoolean()) {
- UserManager uMgr = s.getUserManager();
- if (uMgr instanceof UserManagerImpl) {
- UserManagerImpl uMgrImpl = (UserManagerImpl) uMgr;
- AuthorizableImpl admin = (AuthorizableImpl) uMgrImpl.getAuthorizable(uMgrImpl.adminId);
- return Text.isDescendantOrEqual(node.getPath(), admin.getNode().getPath());
- }
- }
- return false;
- }
-
//------------------------------------------------------< inner classes >---
/**
* Inner class
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=1546953&r1=1546952&r2=1546953&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 Mon Dec 2 10:45:41 2013
@@ -16,13 +16,20 @@
*/
package org.apache.jackrabbit.core.security.user;
+import java.util.Properties;
+import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.jackrabbit.api.security.user.AbstractUserTest;
import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
import org.apache.jackrabbit.test.NotExecutableException;
/**
@@ -65,6 +72,13 @@ public class AdministratorTest extends A
}
}
+ /**
+ * 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);
@@ -72,98 +86,141 @@ public class AdministratorTest extends A
throw new NotExecutableException();
}
- Session s = null;
- try {
- NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
- 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();
- fail();
- } catch (RepositoryException e) {
- // success
+ // access the node corresponding to the admin user and remove it
+ NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+ 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();
+
+ // after removing the node the admin user doesn't exist any more
+ assertNull(userMgr.getAuthorizable(adminId));
+
+ // login must succeed as system user mgr recreates the admin user
+ Session s2 = getHelper().getSuperuserSession();
+ try {
+ admin = userMgr.getAuthorizable(adminId);
+ assertNotNull(admin);
+ assertNotNull(getUserManager(s2).getAuthorizable(adminId));
} finally {
- if (s != null) {
- s.refresh(false);
- }
+ s2.logout();
}
}
- public void testSessionRemoveItem() throws RepositoryException, NotExecutableException {
+ /**
+ * Test for collisions that would prevent from recreate the admin user.
+ * - an intermediate rep:AuthorizableFolder node with the same name
+ */
+ public void testAdminNodeCollidingWithAuthorizableFolder() throws RepositoryException, NotExecutableException {
Authorizable admin = userMgr.getAuthorizable(adminId);
if (admin == null || !(admin instanceof AuthorizableImpl)) {
throw new NotExecutableException();
}
- Session s = null;
- try {
- NodeImpl parent = (NodeImpl) ((AuthorizableImpl) admin).getNode().getParent();
- s = parent.getSession();
- s.removeItem(parent.getPath());
+ // access the node corresponding to the admin user and remove it
+ NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+ String adminPath = adminNode.getPath();
+ String adminNodeName = adminNode.getName();
+ Node parentNode = adminNode.getParent();
+
+ 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 {
+ // now create a colliding node:
+ Node n = parentNode.addNode(adminNodeName, "rep:AuthorizableFolder");
+ collidingPath = n.getPath();
s.save();
- fail();
- } catch (RepositoryException e) {
- // success
+
+ // force recreation of admin user.
+ s2 = getHelper().getSuperuserSession();
+
+ admin = userMgr.getAuthorizable(adminId);
+ assertNotNull(admin);
+ assertEquals(adminNodeName, ((AuthorizableImpl) admin).getNode().getName());
+ assertFalse(adminPath.equals(((AuthorizableImpl) admin).getNode().getPath()));
+
} finally {
- if (s != null) {
- s.refresh(false);
+ if (s2 != null) {
+ s2.logout();
+ }
+ // remove the extra folder and the admin user (created underneath) again.
+ if (collidingPath != null) {
+ s.getNode(collidingPath).remove();
+ s.save();
}
}
}
- public void testSessionMoveAdminNode() throws RepositoryException, NotExecutableException {
+ /**
+ * Test for collisions that would prevent from recreate the admin user.
+ * - a colliding node somewhere else with the same jcr:uuid.
+ *
+ * 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();
}
- Session s = null;
- try {
- NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
- s = adminNode.getSession();
- s.move(adminNode.getPath(), "/somewhereelse");
- // use session obtained from the node as usermgr may point to a dedicated
- // system workspace different from the superusers workspace.
+ // access the node corresponding to the admin user and remove it
+ NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+ NodeId nid = adminNode.getNodeId();
+
+ 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;
+ // NOTE: testRootNode will not be present if users are stored in a distinct wsp.
+ // therefore use root node as start...
+ NodeImpl tr = (NodeImpl) s.getRootNode();
+ Node n = tr.addNode(nr.getQName("tmpNode"), nr.getQName(testNodeType), nid);
+ collidingPath = n.getPath();
s.save();
- fail();
- } catch (RepositoryException e) {
- // success
- } finally {
- if (s != null) {
- s.refresh(false);
- }
- }
- }
- public void testSessionMoveParentNode() throws RepositoryException, NotExecutableException {
- Authorizable admin = userMgr.getAuthorizable(adminId);
+ // force recreation of admin user.
+ s2 = getHelper().getSuperuserSession();
- if (admin == null || !(admin instanceof AuthorizableImpl)) {
- throw new NotExecutableException();
- }
+ admin = userMgr.getAuthorizable(adminId);
+ assertNotNull(admin);
+ // the colliding node must have been removed.
+ assertFalse(s2.nodeExists(collidingPath));
- Session s = null;
- try {
- NodeImpl parent = (NodeImpl) ((AuthorizableImpl) admin).getNode().getParent();
- s = parent.getSession();
- s.move(parent.getPath(), "/somewhereelse");
- // use session obtained from the node as usermgr may point to a dedicated
- // system workspace different from the superusers workspace.
- s.save();
- fail();
- } catch (RepositoryException e) {
- // success
} finally {
- if (s != null) {
- s.refresh(false);
+ if (s2 != null) {
+ s2.logout();
+ }
+ if (collidingPath != null && s.nodeExists(collidingPath)) {
+ s.getNode(collidingPath).remove();
+ s.save();
}
}
}
- public void testWorkspaceMoveAdminNode() throws RepositoryException, NotExecutableException {
+ /**
+ * 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)) {
@@ -171,13 +228,41 @@ public class AdministratorTest extends A
}
// access the node corresponding to the admin user and remove it
- try {
- NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
- Session s = adminNode.getSession();
- s.getWorkspace().move(adminNode.getPath(), "/somewhereelse");
- fail();
- } catch (RepositoryException e) {
- // success
+ NodeImpl adminNode = ((AuthorizableImpl) admin).getNode();
+
+ 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();
+ }
}
}
}