Author: sergiykarpenko
Date: 2010-12-01 10:00:37 -0500 (Wed, 01 Dec 2010)
New Revision: 3585
Added:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccessChildNodes.java
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccess.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestUserAccess.java
Log:
JCR-1533: fixed remove permission on child nodes
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-12-01
14:59:21 UTC (rev 3584)
+++
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-12-01
15:00:37 UTC (rev 3585)
@@ -1542,58 +1542,78 @@
*/
private void validateAccessPermissions(ItemState changedItem) throws
RepositoryException, AccessDeniedException
{
- NodeData parent =
(NodeData)getItemData(changedItem.getData().getParentIdentifier());
- if (parent != null)
+ if (changedItem.isDeleted())
{
-
- // Remove propery or node
- if (changedItem.isDeleted())
+ validateRemoveAccessPermission(changedItem);
+ }
+ else
+ {
+ NodeData parent =
(NodeData)getItemData(changedItem.getData().getParentIdentifier());
+ if (parent != null)
{
- if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.REMOVE}, session
- .getUserState().getIdentity()))
+ if (changedItem.getData().isNode())
{
- throw new AccessDeniedException("Access denied: REMOVE "
- + changedItem.getData().getQPath().getAsString() + " for: " +
session.getUserID() + " item owner "
- + parent.getACL().getOwner());
- }
- }
- else if (changedItem.getData().isNode())
- {
- // add node
- if (changedItem.isAdded())
- {
- if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.ADD_NODE}, session
- .getUserState().getIdentity()))
+ // add node
+ if (changedItem.isAdded())
{
- throw new AccessDeniedException("Access denied: ADD_NODE "
- + changedItem.getData().getQPath().getAsString() + " for:
" + session.getUserID() + " item owner "
- + parent.getACL().getOwner());
+ if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.ADD_NODE}, session
+ .getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: ADD_NODE
"
+ + changedItem.getData().getQPath().getAsString() + " for:
" + session.getUserID()
+ + " item owner " + parent.getACL().getOwner());
+ }
}
+ else if (changedItem.isMixinChanged())
+ {
+ if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.ADD_NODE,
+ PermissionType.SET_PROPERTY},
session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: ADD_NODE or
SET_PROPERTY"
+ + changedItem.getData().getQPath().getAsString() + " for:
" + session.getUserID()
+ + " item owner " + parent.getACL().getOwner());
+ }
+ }
+
}
- else if (changedItem.isMixinChanged())
+ else if (changedItem.isAdded() || changedItem.isUpdated())
{
- if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.ADD_NODE,
- PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ // add or update property
+ if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.SET_PROPERTY}, session
+ .getUserState().getIdentity()))
{
- throw new AccessDeniedException("Access denied: ADD_NODE or
SET_PROPERTY"
+ throw new AccessDeniedException("Access denied: SET_PROPERTY
"
+ changedItem.getData().getQPath().getAsString() + " for:
" + session.getUserID() + " item owner "
+ parent.getACL().getOwner());
}
}
+ } // else - parent not found, deleted in this session or from another
+ }
+ }
- }
- else if (changedItem.isAdded() || changedItem.isUpdated())
+ private void validateRemoveAccessPermission(ItemState changedItem) throws
RepositoryException, AccessDeniedException
+ {
+ NodeData nodeData = null;
+ // if changedItem is node - check its ACL, if property - check parent node ACL
+ if (changedItem.isNode())
+ {
+ nodeData = (NodeData)changedItem.getData();
+ }
+ else
+ {
+ nodeData = (NodeData)getItemData(changedItem.getData().getParentIdentifier());
+ if (nodeData == null)
{
- // add or update property
- if (!accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.SET_PROPERTY}, session
- .getUserState().getIdentity()))
- {
- throw new AccessDeniedException("Access denied: SET_PROPERTY "
- + changedItem.getData().getQPath().getAsString() + " for: " +
session.getUserID() + " item owner "
- + parent.getACL().getOwner());
- }
+ return;
}
- } // else - parent not found, deleted in this session or from another
+ }
+
+ if (!accessManager.hasPermission(nodeData.getACL(), new
String[]{PermissionType.REMOVE}, session.getUserState()
+ .getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: REMOVE " +
changedItem.getData().getQPath().getAsString()
+ + " for: " + session.getUserID() + " item owner " +
nodeData.getACL().getOwner());
+ }
}
/**
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccess.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccess.java 2010-12-01
14:59:21 UTC (rev 3584)
+++
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccess.java 2010-12-01
15:00:37 UTC (rev 3585)
@@ -741,17 +741,10 @@
{
fail("AccessControlException should not have been thrown ");
}
- try
- {
- testByOwnerNode.remove();
- session1.save();
- fail();
- }
- catch (AccessDeniedException e)
- {
- // fail("AccessControlException should not have been thrown ");
- }
+ //john is node owner so he can remove no matter what permission are assigned to
node
+ testByOwnerNode.remove();
+ session1.save();
}
public void testRemoveExoOwnable() throws Exception
Added:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccessChildNodes.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccessChildNodes.java
(rev 0)
+++
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestAccessChildNodes.java 2010-12-01
15:00:37 UTC (rev 3585)
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.access;
+
+import org.exoplatform.services.jcr.BaseStandaloneTest;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.core.CredentialsImpl;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * <br/>Date:
+ *
+ * @author <a href="karpenko.sergiy(a)gmail.com">Karpenko Sergiy</a>
+ * @version $Id: TestAccessChildNodes.java 111 2008-11-11 11:11:11Z serg $
+ */
+public class TestAccessChildNodes extends BaseStandaloneTest
+{
+
+ @Override
+ public String getRepositoryName()
+ {
+ return "db1";
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ //create nodes with "john" user
+ Session sessJohn = repository.login(new CredentialsImpl("john",
"exo".toCharArray()));
+ Node testRoot = sessJohn.getRootNode().addNode("testRoot");
+ testRoot.addMixin("exo:privilegeable");
+ testRoot.setProperty("prop", "value");
+ sessJohn.save();
+ sessJohn.logout();
+ }
+
+ public void tearDown() throws Exception
+ {
+ Session sysSession =
this.repository.getSystemSession(session.getWorkspace().getName());
+ if (sysSession.getRootNode().hasNode("testRoot"))
+ {
+ Node testRoot = sysSession.getRootNode().getNode("testRoot");
+ testRoot.remove();
+ sysSession.save();
+ }
+ super.tearDown();
+ }
+
+ /**
+ * Remove the parent and child node with a user that can remove the parent node but
not the sub node,
+ * and check that an AccessDeniedException occurs.
+ * @throws Exception
+ */
+ public void testUserCanRemoveParentButCanNotRemoveChild() throws Exception
+ {
+ // login as Mary and create subNode
+ Session sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ Node testRoot = sessMary.getRootNode().getNode("testRoot");
+ NodeImpl subNode = (NodeImpl)testRoot.addNode("subNode");
+ subNode.addMixin("exo:privilegeable");
+ sessMary.save();
+
+ subNode.setPermission("mary", PermissionType.ALL);
+ subNode.removePermission("john");
+ subNode.removePermission(SystemIdentity.ANY);
+ sessMary.save();
+ sessMary.logout();
+
+ // login as John and try remove subnode
+ Session sessJohn = repository.login(new CredentialsImpl("john",
"exo".toCharArray()));
+ try
+ {
+ subNode =
(NodeImpl)sessJohn.getRootNode().getNode("testRoot").getNode("subNode");
+ subNode.remove();
+ sessJohn.save();
+ fail("There must be AccessDeniedException");
+ }
+ catch (AccessDeniedException e)
+ {
+ //Ok
+ }
+
+ // try to remove parent node node
+ sessJohn.refresh(false);
+ try
+ {
+ testRoot = sessJohn.getRootNode().getNode("testRoot");
+ testRoot.remove();
+ sessJohn.save();
+ fail("There must be AccessDeniedException");
+ }
+ catch (AccessDeniedException e)
+ {
+ //Ok
+ }
+ finally
+ {
+ sessJohn.logout();
+ }
+
+ // now try with all permissions
+ sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ testRoot = sessMary.getRootNode().getNode("testRoot");
+ subNode = (NodeImpl)testRoot.getNode("subNode");
+ subNode.setPermission(SystemIdentity.ANY, PermissionType.ALL);
+ sessMary.save();
+ sessMary.logout();
+
+ sessJohn = repository.login(new CredentialsImpl("john",
"exo".toCharArray()));
+ testRoot = sessJohn.getRootNode().getNode("testRoot");
+ testRoot.remove();
+ sessJohn.save();
+ sessJohn.logout();
+ }
+
+ /**
+ * Remove the sub node with a user that can remove the sub node (but not the parent
node),
+ * and check that the remove operation was successful.
+ * @throws Exception
+ */
+ public void testUserCanNotRemoveParentButCanRemoveChild() throws Exception
+ {
+ // login as Mary and create subNode
+ Session sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ NodeImpl testRoot =
(NodeImpl)sessMary.getRootNode().getNode("testRoot");
+ NodeImpl subNode = (NodeImpl)testRoot.addNode("subNode");
+ subNode.addMixin("exo:privilegeable");
+ sessMary.save();
+
+ //set permissions
+ subNode.setPermission("mary", PermissionType.ALL);
+ subNode.removePermission("john");
+ subNode.removePermission(SystemIdentity.ANY);
+ sessMary.save();
+
+ testRoot.setPermission("john", PermissionType.ALL);
+ testRoot.removePermission("mary");
+ testRoot.setPermission("mary", new String[]{PermissionType.READ});
+ testRoot.removePermission(SystemIdentity.ANY);
+ sessMary.save();
+ sessMary.logout();
+
+ //try to remove parent as Mary - must fail
+ sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ try
+ {
+ testRoot = (NodeImpl)sessMary.getRootNode().getNode("testRoot");
+ testRoot.remove();
+ sessMary.save();
+ fail("There must be AccessDeniedException");
+ }
+ catch (AccessDeniedException e)
+ {
+ //Ok
+ }
+ sessMary.refresh(false);
+
+ // remove subnode as mary
+ subNode =
(NodeImpl)sessMary.getRootNode().getNode("testRoot").getNode("subNode");
+ subNode.remove();
+ sessMary.save();
+
assertFalse(sessMary.getRootNode().getNode("testRoot").hasNode("subNode"));
+ sessMary.logout();
+ }
+
+ /**
+ * Remove the property with a user that cannot remove the parent node, and check that
an AccessDeniedException occurs
+ * @throws Exception
+ */
+ public void testRemovePropertyWithoutPermissionOnParent() throws Exception
+ {
+ // login as Mary and set permissions on parent node
+ Session sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ NodeImpl testRoot =
(NodeImpl)sessMary.getRootNode().getNode("testRoot");
+
+ testRoot.removePermission("mary");
+ testRoot.setPermission("mary", new String[]{PermissionType.READ});
+ testRoot.removePermission(SystemIdentity.ANY);
+ sessMary.save();
+ sessMary.logout();
+
+ //try to remove parent's property as Mary - must fail
+ sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ try
+ {
+ testRoot = (NodeImpl)sessMary.getRootNode().getNode("testRoot");
+ testRoot.getProperty("prop").remove();
+ sessMary.save();
+ fail("There must be AccessDeniedException");
+ }
+ catch (AccessDeniedException e)
+ {
+ //Ok
+ }
+ finally
+ {
+ sessMary.logout();
+ }
+ }
+
+ /**
+ * Remove the property with a user that can remove the parent node, and check that the
remove operation was successful.
+ * @throws Exception
+ */
+ public void testRemovePropertyWithPermissionOnParent() throws Exception
+ {
+ // login as Mary and set permissions on parent node
+ Session sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+ NodeImpl testRoot =
(NodeImpl)sessMary.getRootNode().getNode("testRoot");
+
+ testRoot.removePermission("mary");
+ testRoot.setPermission("mary", PermissionType.ALL);
+ testRoot.removePermission(SystemIdentity.ANY);
+ sessMary.save();
+ sessMary.logout();
+
+ //try to remove parent's property as Mary - must fail
+ sessMary = repository.login(new CredentialsImpl("mary",
"exo".toCharArray()));
+
+ testRoot = (NodeImpl)sessMary.getRootNode().getNode("testRoot");
+ testRoot.getProperty("prop").remove();
+ sessMary.save();
+
+
assertFalse(sessMary.getRootNode().getNode("testRoot").hasProperty("prop"));
+ sessMary.logout();
+ }
+
+}
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestUserAccess.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestUserAccess.java 2010-12-01
14:59:21 UTC (rev 3584)
+++
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestUserAccess.java 2010-12-01
15:00:37 UTC (rev 3585)
@@ -54,9 +54,13 @@
@Override
protected void tearDown() throws Exception
{
- root.refresh(false);
- testRoot.remove();
- root.save();
+ Session sysSession =
repository.getSystemSession(session.getWorkspace().getName());
+ if (sysSession.getRootNode().hasNode("testUserAccess"))
+ {
+ Node testRoot = sysSession.getRootNode().getNode("testUserAccess");
+ testRoot.remove();
+ sysSession.save();
+ }
super.tearDown();
}