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 2008/04/17 18:27:20 UTC
svn commit: r649172 [2/2] - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/
main/java/org/apache/jackrabbit/core/observation/
main/java/org/apache/jackrabbit/core/query/lucene/
main/java/org/apache/jackrabbit/core/securi...
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java Thu Apr 17 09:27:09 2008
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.core.security.authorization.combined;
-import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.NodeImpl;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.security.SecurityConstants;
@@ -34,11 +33,11 @@
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Node;
@@ -63,18 +62,30 @@
private static Logger log = LoggerFactory.getLogger(CombinedProvider.class);
// TODO: add means to show effective-policy to a user.
- // TODO: TOBEFIXED add means to create user-based ACLs (currently editor is not exposed in the API)
// TODO: TOBEFIXED proper evaluation of permissions respecting resource-based ACLs.
// TODO: TOBEFIXED assert proper evaluation order of group/non-group principal-ACLs
private CombinedEditor editor;
private NodeImpl acRoot;
- private String policyName;
-
public CombinedProvider() {
super("Combined AC policy", "Policy evaluating user-based and resource-based ACLs.");
}
+
+ //--------------------------------------< AbstractAccessControlProvider >---
+ /**
+ * @see AbstractAccessControlProvider#isAcItem(Path)
+ */
+ protected boolean isAcItem(Path absPath) throws RepositoryException {
+ Path.Element[] elems = absPath.getElements();
+ for (int i = 0; i < elems.length; i++) {
+ if (N_POLICY.equals(elems[i].getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
//----------------------------------------------< AccessControlProvider >---
/**
* @see AccessControlProvider#init(javax.jcr.Session, java.util.Map)
@@ -92,8 +103,6 @@
acRoot = root.addNode(N_ACCESSCONTROL, NT_REP_ACCESS_CONTROL, null);
}
- policyName = session.getJCRName(AccessControlConstants.N_POLICY);
-
editor = new CombinedEditor(session, resolver, resolver.getQPath(acRoot.getPath()));
try {
log.info("Install initial ACL:...");
@@ -131,9 +140,10 @@
}
/**
- * @see AccessControlProvider#getAccessControlEntries(org.apache.jackrabbit.core.NodeId)
+ * @see AccessControlProvider#getAccessControlEntries(Path)
+ * @param absPath
*/
- public AccessControlEntry[] getAccessControlEntries(NodeId nodeId) throws RepositoryException {
+ public AccessControlEntry[] getAccessControlEntries(Path absPath) throws RepositoryException {
checkInitialized();
// TODO: TOBEFIXED
return new AccessControlEntry[0];
@@ -162,16 +172,29 @@
/**
* @see AccessControlProvider#compilePermissions(Set)
*/
- public CompiledPermissions compilePermissions(Set principals) throws ItemNotFoundException, RepositoryException {
+ public CompiledPermissions compilePermissions(Set principals) throws RepositoryException {
checkInitialized();
if (isAdminOrSystem(principals)) {
return getAdminPermissions();
+ } else if (isReadOnly(principals)) {
+ return getReadOnlyPermissions();
} else {
- // TODO: TOBEFIXED include the resource-based ACLs!
return new CompiledPermissionImpl(principals);
}
}
+ /**
+ * @see AccessControlProvider#canAccessRoot(Set)
+ */
+ public boolean canAccessRoot(Set principals) throws RepositoryException {
+ checkInitialized();
+ if (isAdminOrSystem(principals)) {
+ return true;
+ } else {
+ return new CompiledPermissionImpl(principals, false).grants(PathFactoryImpl.getInstance().getRootPath(), Permission.READ);
+ }
+ }
+
//-----------------------------------------------------< CompiledPolicy >---
/**
*
@@ -188,18 +211,28 @@
* @throws RepositoryException
*/
private CompiledPermissionImpl(Set principals) throws RepositoryException {
+ this(principals, true);
+ }
+
+ /**
+ * @param principals
+ * @throws RepositoryException
+ */
+ private CompiledPermissionImpl(Set principals, boolean listenToEvents) throws RepositoryException {
this.principals = principals;
acPaths = new HashSet(principals.size());
entries = reload();
// TODO: describe
- int events = Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED |
- Event.PROPERTY_REMOVED | Event.NODE_ADDED | Event.NODE_REMOVED;
- String[] ntNames = new String[] {
- session.getJCRName(NT_REP_ACE)
- };
- observationMgr.addEventListener(this, events, acRoot.getPath(), true, null, ntNames, false);
+ if (listenToEvents) {
+ int events = Event.PROPERTY_CHANGED | Event.PROPERTY_ADDED |
+ Event.PROPERTY_REMOVED | Event.NODE_ADDED | Event.NODE_REMOVED;
+ String[] ntNames = new String[] {
+ session.getJCRName(NT_REP_ACE)
+ };
+ observationMgr.addEventListener(this, events, acRoot.getPath(), true, null, ntNames, false);
+ }
}
//------------------------------------< AbstractCompiledPermissions >---
@@ -211,19 +244,12 @@
throw new RepositoryException("Absolute path expected.");
}
- String jcrPath = session.getJCRPath(absPath);
- boolean isAclItem = false;
/* Test if the given path points to a Node (or an existing or non
* existing direct decendant of an existing Node) that stores
* AC-information
*/
- String[] segments = Text.explode(jcrPath, '/', false);
- if (segments.length > 0) {
- for (int i = segments.length - 1; i >= 0 && !isAclItem; i--) {
- isAclItem = policyName.equals(segments[i]);
- }
- }
-
+ boolean isAclItem = isAcItem(absPath);
+ String jcrPath = session.getJCRPath(absPath);
int permissions;
if (session.itemExists(jcrPath)) {
permissions = entries.getPermissions(session.getItem(jcrPath), isAclItem);
@@ -255,7 +281,7 @@
try {
observationMgr.removeEventListener(this);
} catch (RepositoryException e) {
- log.error("Internal error: ", e.getMessage());
+ log.debug("Unable to unregister listener: ", e.getMessage());
}
super.close();
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/PolicyTemplateImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/PolicyTemplateImpl.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/PolicyTemplateImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/PolicyTemplateImpl.java Thu Apr 17 09:27:09 2008
@@ -18,6 +18,7 @@
import org.apache.jackrabbit.core.security.authorization.PolicyEntry;
import org.apache.jackrabbit.core.security.authorization.PolicyTemplate;
+import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,6 +70,8 @@
public boolean setEntry(PolicyEntry entry) throws AccessControlException, RepositoryException {
if (entry instanceof PolicyEntryImpl &&
principal.equals(entry.getPrincipal())) {
+ // make sure valid privileges are provided.
+ PrivilegeRegistry.getBits(entry.getPrivileges());
return internalAddEntry((PolicyEntryImpl) entry);
} else {
throw new AccessControlException("Invalid entry.");
@@ -76,7 +79,14 @@
}
public boolean removeEntry(PolicyEntry entry) throws AccessControlException, RepositoryException {
- return entries.remove(entry);
+ if (entry instanceof PolicyEntryImpl &&
+ principal.equals(entry.getPrincipal())) {
+ // make sure valid privileges are provided.
+ PrivilegeRegistry.getBits(entry.getPrivileges());
+ return entries.remove(entry);
+ } else {
+ throw new AccessControlException("Invalid entry.");
+ }
}
//------------------------------------------------< AccessControlPolicy >---
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/principal/DefaultPrincipalProvider.java Thu Apr 17 09:27:09 2008
@@ -75,7 +75,7 @@
* @throws RepositoryException if an error accessing the repository occurs.
*/
public DefaultPrincipalProvider(Session securitySession,
- UserManagerImpl userManager) throws RepositoryException {
+ UserManagerImpl userManager) throws RepositoryException {
this.userManager = userManager;
everyonePrincipal = EveryonePrincipal.getInstance();
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java Thu Apr 17 09:27:09 2008
@@ -157,6 +157,10 @@
return internalIsGranted(parentPath, permissions);
}
+ public boolean canRead(Path itemPath) throws ItemNotFoundException, RepositoryException {
+ return true;
+ }
+
private boolean internalIsGranted(Path absPath, int permissions) throws ItemNotFoundException, RepositoryException {
if (!absPath.isAbsolute()) {
throw new RepositoryException("Absolute path expected");
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java Thu Apr 17 09:27:09 2008
@@ -78,6 +78,17 @@
"Policy that defines the general access control rules for the security workspace.");
}
+ //--------------------------------------< AbstractAccessControlProvider >---
+ /**
+ * Always returns false, since this ac provider does not use content stored
+ * in items to evaluate AC information.
+ *
+ * @see AbstractAccessControlProvider#isAcItem(Path)
+ */
+ protected boolean isAcItem(Path absPath) throws RepositoryException {
+ return false;
+ }
+
//----------------------------------------------< AccessControlProvider >---
/**
* @see AccessControlProvider#init(Session, Map)
@@ -110,7 +121,7 @@
}
}
- public CompiledPermissions compilePermissions(Set principals) throws ItemNotFoundException, RepositoryException {
+ public CompiledPermissions compilePermissions(Set principals) throws RepositoryException {
checkInitialized();
if (isAdminOrSystem(principals)) {
return getAdminPermissions();
@@ -127,6 +138,11 @@
}
}
+ public boolean canAccessRoot(Set principals) throws RepositoryException {
+ checkInitialized();
+ return true;
+ }
+
//------------------------------------------------------------< private >---
private ItemBasedPrincipal getUserPrincipal(Set principals) {
@@ -387,10 +403,15 @@
// read is always granted
return true;
}
- // TODO: additional simple checks.... (last accessed... etc)
-
- // finally retrieve from cache (or build)
+ // otherwise: retrieve from cache (or build)
return super.grants(absPath, permissions);
+ }
+
+ /**
+ * @see CompiledPermissions#canReadAll()
+ */
+ public boolean canReadAll() throws RepositoryException {
+ return true;
}
//--------------------------------------------------< EventListener >---
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java?rev=649172&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java Thu Apr 17 09:27:09 2008
@@ -0,0 +1,511 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+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.SessionImpl;
+import org.apache.jackrabbit.core.security.TestPrincipal;
+import org.apache.jackrabbit.core.security.jsr283.security.AbstractAccessControlTest;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.ConstraintViolationException;
+import java.security.Principal;
+
+/**
+ * <code>AbstractEvaluationTest</code>...
+ */
+public abstract class AbstractEvaluationTest extends AbstractAccessControlTest {
+
+ private static Logger log = LoggerFactory.getLogger(AbstractEvaluationTest.class);
+
+ protected Credentials creds;
+ protected User testUser;
+ protected SessionImpl testSession;
+ protected AccessControlManager testAcMgr;
+
+ protected String path;
+ protected String childNPath;
+ protected String childNPath2;
+ protected String childPPath;
+ protected String childchildPPath;
+ protected String siblingPath;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ UserManager uMgr = getUserManager(superuser);
+ Principal princ = new TestPrincipal("anyUser");
+ creds = new SimpleCredentials("anyUser", "anyUser".toCharArray());
+
+ Authorizable a = uMgr.getAuthorizable(princ);
+ if (a == null) {
+ testUser = uMgr.createUser("anyUser", creds, princ);
+ } else if (a.isGroup()) {
+ throw new NotExecutableException();
+ } else {
+ testUser = (User) a;
+ }
+
+ // TODO: remove cast once 283 is released.
+ testSession = (SessionImpl) helper.getRepository().login(creds);
+ testAcMgr = getAccessControlManager(testSession);
+
+ // create some nodes below the test root in order to apply ac-stuff
+ Node node = testRootNode.addNode(nodeName1, testNodeType);
+ Node cn1 = node.addNode(nodeName2, testNodeType);
+ Property cp1 = node.setProperty(propertyName1, "anyValue");
+ Node cn2 = node.addNode(nodeName3, testNodeType);
+
+ Property ccp1 = cn1.setProperty(propertyName1, "childNodeProperty");
+
+ Node n2 = testRootNode.addNode(nodeName2, testNodeType);
+ superuser.save();
+
+ path = node.getPath();
+ childNPath = cn1.getPath();
+ childNPath2 = cn2.getPath();
+ childPPath = cp1.getPath();
+ childchildPPath = ccp1.getPath();
+ siblingPath = n2.getPath();
+ }
+
+ protected void tearDown() throws Exception {
+ if (testSession != null && testSession.isLive()) {
+ testSession.logout();
+ }
+ // make sure all ac info is removed
+ clearACInfo();
+ // remove the test user again.
+ if (testUser != null) {
+ testUser.remove();
+ }
+ super.tearDown();
+ }
+
+ private static UserManager getUserManager(Session session) throws NotExecutableException {
+ if (!(session instanceof JackrabbitSession)) {
+ throw new NotExecutableException();
+ }
+
+ try {
+ return ((JackrabbitSession) session).getUserManager();
+ } catch (RepositoryException e) {
+ throw new NotExecutableException();
+ }
+ }
+
+ protected abstract void clearACInfo();
+
+ protected abstract PolicyTemplate getPolicyTemplate(AccessControlManager acM, String path) throws RepositoryException, AccessDeniedException, NotExecutableException;
+
+ protected abstract PolicyEntry createEntry(Principal principal, int privileges, boolean isAllow, String[] restrictions);
+
+ protected abstract String[] getRestrictions(String path);
+
+ protected PolicyTemplate givePrivileges(String nPath, int privileges, String[] restrictions) throws NotExecutableException, RepositoryException {
+ PolicyTemplate tmpl = getPolicyTemplate(acMgr, nPath);
+ tmpl.setEntry(createEntry(testUser.getPrincipal(), privileges, true, restrictions));
+ acMgr.setPolicy(tmpl.getPath(), tmpl);
+ superuser.save();
+ return tmpl;
+ }
+
+ protected PolicyTemplate withdrawPrivileges(String nPath, int privileges, String[] restrictions) throws NotExecutableException, RepositoryException {
+ PolicyTemplate tmpl = getPolicyTemplate(acMgr, nPath);
+ tmpl.setEntry(createEntry(testUser.getPrincipal(), privileges, false, restrictions));
+ acMgr.setPolicy(tmpl.getPath(), tmpl);
+ superuser.save();
+ return tmpl;
+ }
+
+ protected void checkReadOnly(String path) throws RepositoryException {
+ Privilege[] privs = testAcMgr.getPrivileges(path);
+ assertTrue(privs.length == 1);
+ assertEquals(PrivilegeRegistry.READ_PRIVILEGE, privs[0]);
+ }
+
+ public void testGrantedPermissions() throws RepositoryException, AccessDeniedException, NotExecutableException {
+ /* precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES privileges at 'path'
+ givePrivileges(path, PrivilegeRegistry.ADD_CHILD_NODES |
+ PrivilegeRegistry.MODIFY_PROPERTIES, getRestrictions(path));
+ /*
+ testuser must now have
+ - ADD_NODE permission for child node
+ - SET_PROPERTY permission for child props
+ - REMOVE permission for child-props
+ - READ-only permission for the node at 'path'
+
+ testuser must not have
+ - REMOVE permission for child node
+ */
+ String nonExChildPath = path + "/anyItem";
+ assertTrue(testSession.hasPermission(nonExChildPath, "read,add_node,set_property"));
+ assertFalse(testSession.hasPermission(nonExChildPath, "remove"));
+
+ Node testN = testSession.getNode(path);
+
+ // must be allowed to add child node
+ testN.addNode(nodeName3, testNodeType);
+ testSession.save();
+
+ // must be allowed to remove child-property
+ testSession.getProperty(childPPath).remove();
+ testSession.save();
+
+ // must be allowed to set child property again
+ testN.setProperty(Text.getName(childPPath), "othervalue");
+ testSession.save();
+
+ // must not be allowed to remove child nodes
+ try {
+ testSession.getNode(childNPath).remove();
+ testSession.save();
+ fail("test-user is not allowed to remove a node below " + path);
+ } catch (AccessDeniedException e) {
+ // success
+ }
+
+ // must have read-only access on 'testN' and it's sibling
+ assertTrue(testSession.hasPermission(path, "read"));
+ assertFalse(testSession.hasPermission(path, "add_node,set_property,remove"));
+ checkReadOnly(siblingPath);
+ }
+
+ public void testDeniedPermission() throws RepositoryException, NotExecutableException, InterruptedException {
+ /* precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ // withdraw READ privilege to 'testUser' at 'path'
+ withdrawPrivileges(childNPath, PrivilegeRegistry.READ, getRestrictions(childNPath));
+ /*
+ testuser must now have
+ - READ-only permission for the child-props of path
+
+ testuser must not have
+ - any permission on child-node and all its subtree
+ */
+
+ // must still have read-access to path, ...
+ assertTrue(testSession.hasPermission(path, "read"));
+ Node n = testSession.getNode(path);
+ // ... siblings of childN
+ testSession.getNode(childNPath2);
+ // ... and props of path
+ assertTrue(n.getProperties().hasNext());
+
+ /*
+ testSession must not have access to 'childNPath'
+ */
+ assertFalse(testSession.itemExists(childNPath));
+ try {
+ Node testN = testSession.getNode(childNPath);
+ fail("Read access has been denied -> cannot retrieve child node.");
+ } catch (PathNotFoundException e) {
+ // ok.
+ }
+ /*
+ -> must not have access to subtree below 'childNPath'
+ */
+ assertFalse(testSession.itemExists(childchildPPath));
+ try {
+ testSession.getItem(childchildPPath);
+ fail("Read access has been denied -> cannot retrieve prop below child node.");
+ } catch (PathNotFoundException e) {
+ // ok.
+ }
+ }
+
+ public void testAccessControlRead() throws NotExecutableException, RepositoryException {
+ checkReadOnly(path);
+
+ // re-grant READ in order to have an ACL-node
+ PolicyTemplate tmpl = givePrivileges(path, PrivilegeRegistry.READ, getRestrictions(path));
+ // make sure the 'rep:policy' node has been created.
+ assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+
+ /*
+ Testuser must still have READ-only access only and must not be
+ allowed to view the acl-node that has been created.
+ */
+ assertFalse(testAcMgr.hasPrivileges(path, new Privilege[] {
+ PrivilegeRegistry.READ_AC_PRIVILEGE
+ }));
+ assertFalse(testSession.itemExists(path + "/rep:policy"));
+
+ Node n = testSession.getNode(tmpl.getPath());
+ assertFalse(n.hasNode("rep:policy"));
+ try {
+ n.getNode("rep:policy");
+ fail("Accessing the rep:policy node must throw PathNotFoundException.");
+ } catch (PathNotFoundException e) {
+ // ok.
+ }
+
+ /* Finally the test user must not be allowed to remove the policy. */
+ try {
+ testAcMgr.removePolicy(path);
+ fail("Test user must not be allowed to remove the access control policy.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ }
+
+ public void testAccessControlModification() throws RepositoryException, NotExecutableException {
+ /* precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES| REMOVE_CHILD_NODES privileges at 'path'
+ PolicyTemplate tmpl = givePrivileges(path,
+ PrivilegeRegistry.ADD_CHILD_NODES |
+ PrivilegeRegistry.REMOVE_CHILD_NODES |
+ PrivilegeRegistry.MODIFY_PROPERTIES, getRestrictions(path));
+ /*
+ testuser must not have
+ - permission to view AC items
+ - permission to modify AC items
+ */
+
+ // make sure the 'rep:policy' node has been created.
+ assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+ // the policy node however must not be visible to the test-user
+ assertFalse(testSession.itemExists(tmpl.getPath() + "/rep:policy"));
+ try {
+ testAcMgr.getPolicy(tmpl.getPath());
+ fail("test user must not have READ_AC privilege.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ try {
+ testAcMgr.getEffectivePolicy(tmpl.getPath());
+ fail("test user must not have READ_AC privilege.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ try {
+ testAcMgr.getEffectivePolicy(path);
+ fail("test user must not have READ_AC privilege.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ try {
+ testAcMgr.getAccessControlEntries(tmpl.getPath());
+ fail("test user must not have READ_AC privilege.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ try {
+ testAcMgr.removePolicy(tmpl.getPath());
+ fail("test user must not have MODIFY_AC privilege.");
+ } catch (AccessDeniedException e) {
+ // success
+ }
+ }
+
+
+ public void testWithDrawRead() throws RepositoryException, NotExecutableException {
+ /*
+ precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ // give 'testUser' READ_AC|MODIFY_AC privileges at 'path'
+ givePrivileges(path, PrivilegeRegistry.WRITE, getRestrictions(path));
+ // withdraw the READ privilege
+ withdrawPrivileges(path, PrivilegeRegistry.READ, getRestrictions(path));
+
+ //assertFalse(testSession.itemExists(path));
+
+ Session s = null;
+ try {
+ s = helper.getRepository().login(creds);
+ assertFalse(s.itemExists(path));
+ } finally {
+ if (s != null) {
+ s.logout();
+ }
+ }
+ }
+
+ public void testInheritance() throws RepositoryException, NotExecutableException {
+ /* precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ // give 'modify-properties' privilege on 'path'
+ givePrivileges(path, PrivilegeRegistry.MODIFY_PROPERTIES, getRestrictions(path));
+ // give 'add-child-nodes' and 'remove-child-nodes' privilege on 'child-path'
+ givePrivileges(childNPath, PrivilegeRegistry.ADD_CHILD_NODES |
+ PrivilegeRegistry.REMOVE_CHILD_NODES, getRestrictions(childNPath));
+
+ /*
+ since permission evaluation respects inheritance through the node
+ hierarchy, the following privileges must now be given at 'childNPath':
+ - read
+ - modify-properties
+ - add-child-nodes
+ - remove-child-nodes
+ -> read + write
+ */
+ Privilege[] privs = new Privilege[] {
+ PrivilegeRegistry.READ_PRIVILEGE,
+ PrivilegeRegistry.WRITE_PRIVILEGE
+ };
+ assertTrue(testAcMgr.hasPrivileges(childNPath, privs));
+ /*
+ ... and the following permissions must be granted at any child item
+ of child-path:
+ - read
+ - set-property
+ - add-node
+ - remove
+ */
+ String nonExistingItemPath = childNPath + "/anyItem";
+ String actions = SessionImpl.ADD_NODE_ACTION + "," +
+ SessionImpl.REMOVE_ACTION + "," +
+ SessionImpl.SET_PROPERTY_ACTION + "," +
+ SessionImpl.READ_ACTION;
+ assertTrue(testSession.hasPermission(nonExistingItemPath, actions));
+
+ /* try adding a new child node -> must succeed. */
+ Node childN = testSession.getNode(childNPath);
+ Node testChild = childN.addNode(nodeName2, testNodeType);
+
+ /* test privileges on the 'new' child node */
+ privs = testAcMgr.getPrivileges(testChild.getPath());
+ int exptectedPrivs = PrivilegeRegistry.WRITE | PrivilegeRegistry.READ;
+ assertTrue(exptectedPrivs == PrivilegeRegistry.getBits(privs));
+
+ /* repeate test after save. */
+ testSession.save();
+ privs = testAcMgr.getPrivileges(testChild.getPath());
+ assertTrue(exptectedPrivs == PrivilegeRegistry.getBits(privs));
+ }
+
+ public void testNewNodes() throws RepositoryException {
+ /*
+ precondition:
+ testuser must have READ-only permission on test-node and below
+ */
+ checkReadOnly(path);
+
+ /* create some new nodes below 'path' */
+ Node n = testSession.getNode(path);
+ for (int i = 0; i < 5; i++) {
+ n = n.addNode(nodeName2, testNodeType);
+ }
+
+ /* make sure the same privileges/permissions are granted as at path. */
+ Privilege[] privs = testAcMgr.getPrivileges(n.getPath());
+ assertTrue(PrivilegeRegistry.READ == PrivilegeRegistry.getBits(privs));
+ testSession.checkPermission(n.getPath(), SessionImpl.READ_ACTION);
+ }
+
+ public void testNonExistingItem() throws RepositoryException {
+ /*
+ precondition:
+ testuser must have READ-only permission on the root node and below
+ */
+ String rootPath = testSession.getRootNode().getPath();
+ checkReadOnly(rootPath);
+ testSession.checkPermission(rootPath + "nonExistingItem", SessionImpl.READ_ACTION);
+ }
+
+ public void testACItemsAreProtected() throws NotExecutableException, RepositoryException {
+ // search for a rep:policy node
+ Node policyNode = findPolicyNode(superuser.getRootNode());
+ if (policyNode == null) {
+ throw new NotExecutableException("no policy node found.");
+ }
+
+ assertTrue("The rep:Policy node must be protected", policyNode.getDefinition().isProtected());
+ try {
+ policyNode.remove();
+ fail("rep:Policy node must be protected.");
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+
+ for (NodeIterator it = policyNode.getNodes(); it.hasNext();) {
+ Node n = it.nextNode();
+ if (n.isNodeType("rep:ACE")) {
+ try {
+ n.remove();
+ fail("ACE node must be protected.");
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+ break;
+ }
+ }
+
+ try {
+ policyNode.setProperty("test", "anyvalue");
+ fail("rep:policy node must be protected.");
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+ try {
+ policyNode.addNode("test", "rep:ACE");
+ fail("rep:policy node must be protected.");
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+ }
+
+ private static Node findPolicyNode(Node start) throws RepositoryException {
+ Node policyNode = null;
+ if (start.isNodeType("rep:ACL")) {
+ policyNode = start;
+ }
+ for (NodeIterator it = start.getNodes(); it.hasNext() && policyNode == null;) {
+ policyNode = findPolicyNode(it.nextNode());
+ }
+ return policyNode;
+ }
+
+ // TODO: test AC for moved node
+ // TODO: test AC for moved AC-controlled node
+ // TODO: test if combination of group and user permissions are properly evaluated
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEvaluationTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractPolicyTemplateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractPolicyTemplateTest.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractPolicyTemplateTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractPolicyTemplateTest.java Thu Apr 17 09:27:09 2008
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.core.security.authorization;
import org.apache.jackrabbit.test.JUnitTest;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlException;
+import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,15 +52,113 @@
assertNotNull(pt.getEntries());
assertTrue(pt.getEntries().length == 0);
+ assertTrue(pt.size() == pt.getEntries().length);
assertTrue(pt.isEmpty());
assertNotNull(pt.getName());
}
-
public void testGetPath() {
PolicyTemplate pt = (PolicyTemplate) createEmptyTemplate(getTestPath());
assertEquals(getTestPath(), pt.getPath());
}
- // TODO: add more tests
+ public void testSetInvalidEntry() throws RepositoryException {
+ PolicyTemplate pt = (PolicyTemplate) createEmptyTemplate(getTestPath());
+ try {
+ pt.setEntry(new PolicyEntry() {
+ public boolean isAllow() {
+ return false;
+ }
+ public int getPrivilegeBits() {
+ return PrivilegeRegistry.READ;
+ }
+
+ public Principal getPrincipal() {
+ return testPrincipal;
+ }
+
+ public Privilege[] getPrivileges() {
+ return new Privilege[] {PrivilegeRegistry.READ_PRIVILEGE};
+ }
+ });
+ fail("Passing an unknown PolicyEntry should fail");
+ } catch (AccessControlException e) {
+ // success
+ }
+ }
+
+ public void testSetInvalidEntry2() throws RepositoryException {
+ PolicyTemplate pt = (PolicyTemplate) createEmptyTemplate(getTestPath());
+ try {
+ pt.setEntry(new PolicyEntry() {
+ public boolean isAllow() {
+ return false;
+ }
+ public int getPrivilegeBits() {
+ return 0;
+ }
+
+ public Principal getPrincipal() {
+ return testPrincipal;
+ }
+
+ public Privilege[] getPrivileges() {
+ return new Privilege[0];
+ }
+ });
+ fail("Passing a PolicyEntry with invalid privileges should fail");
+ } catch (AccessControlException e) {
+ // success
+ }
+ }
+
+ public void testRemoveInvalidEntry() throws RepositoryException {
+ PolicyTemplate pt = (PolicyTemplate) createEmptyTemplate(getTestPath());
+ try {
+ pt.removeEntry(new PolicyEntry() {
+ public boolean isAllow() {
+ return false;
+ }
+ public int getPrivilegeBits() {
+ return PrivilegeRegistry.READ;
+ }
+
+ public Principal getPrincipal() {
+ return testPrincipal;
+ }
+
+ public Privilege[] getPrivileges() {
+ return new Privilege[] {PrivilegeRegistry.READ_PRIVILEGE};
+ }
+ });
+ fail("Passing an unknown PolicyEntry should fail");
+ } catch (AccessControlException e) {
+ // success
+ }
+ }
+
+ public void testRemoveInvalidEntry2() throws RepositoryException {
+ PolicyTemplate pt = (PolicyTemplate) createEmptyTemplate(getTestPath());
+ try {
+ pt.removeEntry(new PolicyEntry() {
+ public boolean isAllow() {
+ return false;
+ }
+ public int getPrivilegeBits() {
+ return 0;
+ }
+
+ public Principal getPrincipal() {
+ return testPrincipal;
+ }
+
+ public Privilege[] getPrivileges() {
+ return new Privilege[0];
+ }
+ });
+ fail("Passing a PolicyEntry with invalid privileges should fail");
+ } catch (AccessControlException e) {
+ // success
+ }
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java Thu Apr 17 09:27:09 2008
@@ -18,9 +18,14 @@
import org.apache.jackrabbit.core.security.authorization.AbstractPolicyTemplateTest;
import org.apache.jackrabbit.core.security.authorization.PolicyTemplate;
+import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.security.authorization.PolicyEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+
/**
* <code>ACLTemplateTest</code>...
*/
@@ -34,5 +39,129 @@
protected PolicyTemplate createEmptyTemplate(String path) {
return new ACLTemplate(path);
+ }
+
+ public void testAddEntry() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+
+ assertTrue(pt.setEntry(new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true)));
+ }
+
+ public void testAddEntryTwice() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+
+ pt.setEntry(pe);
+ assertFalse(pt.setEntry(pe));
+ }
+
+ public void testRevokeEffect() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+
+ pt.setEntry(pe);
+
+ // same entry but with revers 'isAllow' flag
+ pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, false);
+ assertTrue(pt.setEntry(pe));
+
+ // net-effect: only a single deny-read entry
+ assertTrue(pt.size() == 1);
+ assertEquals(pt.getEntries()[0], pe);
+ }
+
+ public void testEffect() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+
+ pt.setEntry(pe);
+
+ // new entry extends privs.
+ pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ | PrivilegeRegistry.ADD_CHILD_NODES, true);
+ assertTrue(pt.setEntry(pe));
+
+ // net-effect: only a single allow-entry with both privileges
+ assertTrue(pt.size() == 1);
+ assertEquals(pt.getEntries()[0], pe);
+
+ // new entry revokes READ priv
+ pe = new ACEImpl(testPrincipal, PrivilegeRegistry.ADD_CHILD_NODES, true);
+ assertTrue(pt.setEntry(pe));
+ // net-effect: only a single allow-entry with add_child_nodes priv
+ assertTrue(pt.size() == 1);
+ assertEquals(pt.getEntries()[0], pe);
+ }
+
+ public void testEffect2() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+ pt.setEntry(pe);
+
+ // add deny entry for mod_props
+ PolicyEntry pe2 = new ACEImpl(testPrincipal, PrivilegeRegistry.MODIFY_PROPERTIES, false);
+ assertTrue(pt.setEntry(pe2));
+
+ // net-effect: 2 entries
+ assertTrue(pt.size() == 2);
+ assertEquals(pt.getEntries()[0], pe);
+ assertEquals(pt.getEntries()[1], pe2);
+ }
+
+ public void testEffect3() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.WRITE, true);
+
+ pt.setEntry(pe);
+
+ // add deny entry for mod_props
+ PolicyEntry pe2 = new ACEImpl(testPrincipal, PrivilegeRegistry.MODIFY_PROPERTIES, false);
+ assertTrue(pt.setEntry(pe2));
+
+ // net-effect: 2 entries with the allow entry being adjusted
+ assertTrue(pt.size() == 2);
+ PolicyEntry[] entries = pt.getEntries();
+ for (int i = 0; i < entries.length; i++) {
+ int privs = entries[i].getPrivilegeBits();
+ if (entries[i].isAllow()) {
+ assertTrue(privs == (PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.REMOVE_CHILD_NODES));
+ } else {
+ assertTrue(privs == PrivilegeRegistry.MODIFY_PROPERTIES);
+ }
+ }
+ }
+
+ public void testMultiplePrincipals() throws RepositoryException {
+ Principal princ2 = new Principal() {
+ public String getName() {
+ return "AnotherPrincipal";
+ }
+ };
+
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+ pt.setEntry(pe);
+
+ // add deny entry for mod_props
+ pe = new ACEImpl(princ2, PrivilegeRegistry.READ, true);
+ assertTrue(pt.setEntry(pe));
+ assertTrue(pt.getEntries().length == 2);
+ }
+
+ public void testRemoveEntry() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+ pt.setEntry(pe);
+
+ assertTrue(pt.removeEntry(pe));
+ }
+
+ public void testRemoveNonExisting() throws RepositoryException {
+ PolicyTemplate pt = createEmptyTemplate(getTestPath());
+ PolicyEntry pe = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, true);
+ pt.setEntry(pe);
+ PolicyEntry pe2 = new ACEImpl(testPrincipal, PrivilegeRegistry.READ, false);
+ pt.setEntry(pe2);
+
+ assertFalse(pt.removeEntry(pe));
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationTest.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EvaluationTest.java Thu Apr 17 09:27:09 2008
@@ -16,113 +16,46 @@
*/
package org.apache.jackrabbit.core.security.authorization.acl;
-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.api.JackrabbitSession;
-import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.security.TestPrincipal;
+import org.apache.jackrabbit.core.security.authorization.AbstractEvaluationTest;
+import org.apache.jackrabbit.core.security.authorization.PolicyEntry;
+import org.apache.jackrabbit.core.security.authorization.PolicyTemplate;
import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
-import org.apache.jackrabbit.core.security.jsr283.security.AbstractAccessControlTest;
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager;
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicyIterator;
import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
import org.apache.jackrabbit.test.NotExecutableException;
-import org.apache.jackrabbit.util.Text;
import javax.jcr.AccessDeniedException;
-import javax.jcr.Credentials;
-import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.Property;
import javax.jcr.RepositoryException;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.NodeIterator;
-import javax.jcr.Session;
-import javax.jcr.nodetype.ConstraintViolationException;
import java.security.Principal;
/**
* <code>EvaluationTest</code>...
*/
-public class EvaluationTest extends AbstractAccessControlTest {
+public class EvaluationTest extends AbstractEvaluationTest {
- private User testUser;
- private SessionImpl testSession;
- private AccessControlManager testAcMgr;
-
- private String path;
- private String childNPath;
- private String childNPath2;
- private String childPPath;
- private String childchildPPath;
- private String siblingPath;
+ private String[] restrictions = new String[0];
protected void setUp() throws Exception {
super.setUp();
- UserManager uMgr = getUserManager(superuser);
- Principal princ = new TestPrincipal("anyUser");
- Credentials creds = new SimpleCredentials("anyUser", "anyUser".toCharArray());
-
- Authorizable a = uMgr.getAuthorizable(princ);
- if (a == null) {
- testUser = uMgr.createUser("anyUser", creds, princ);
- } else if (a.isGroup()) {
- throw new NotExecutableException();
- } else {
- testUser = (User) a;
- }
-
- // TODO: remove cast once 283 is released.
- testSession = (SessionImpl) helper.getRepository().login(creds);
- testAcMgr = getAccessControlManager(testSession);
-
- // create some nodes below the test root in order to apply ac-stuff
- Node node = testRootNode.addNode(nodeName1, testNodeType);
- Node cn1 = node.addNode(nodeName2, testNodeType);
- Property cp1 = node.setProperty(propertyName1, "anyValue");
- Node cn2 = node.addNode(nodeName3, testNodeType);
-
- Property ccp1 = cn1.setProperty(propertyName1, "childNodeProperty");
-
- Node n2 = testRootNode.addNode(nodeName2, testNodeType);
- superuser.save();
-
- path = node.getPath();
- childNPath = cn1.getPath();
- childNPath2 = cn2.getPath();
- childPPath = cp1.getPath();
- childchildPPath = ccp1.getPath();
- siblingPath = n2.getPath();
- }
-
- protected void tearDown() throws Exception {
- super.tearDown();
-
- if (testSession != null && testSession.isLive()) {
- testSession.logout();
- }
- if (testUser != null) {
- testUser.remove();
- }
- }
-
- private static UserManager getUserManager(Session session) throws NotExecutableException {
- if (!(session instanceof JackrabbitSession)) {
- throw new NotExecutableException();
- }
-
try {
- return ((JackrabbitSession) session).getUserManager();
+ AccessControlPolicy rootPolicy = acMgr.getPolicy("/");
+ if (!(rootPolicy instanceof ACLTemplate)) {
+ throw new NotExecutableException();
+ }
} catch (RepositoryException e) {
throw new NotExecutableException();
}
}
- private static ACLTemplate getACLTemplate(AccessControlManager acM, String path) throws RepositoryException, AccessDeniedException {
+ protected void clearACInfo() {
+ // nop
+ }
+
+ protected PolicyTemplate getPolicyTemplate(AccessControlManager acM, String path) throws RepositoryException, AccessDeniedException, NotExecutableException {
AccessControlPolicyIterator it = acM.getApplicablePolicies(path);
while (it.hasNext()) {
AccessControlPolicy acp = it.nextAccessControlPolicy();
@@ -130,208 +63,27 @@
return (ACLTemplate) acp;
}
}
- // TODO: change to NotExecutableException
- throw new RepositoryException();
+ throw new NotExecutableException("ACLTemplate expected.");
}
- private void givePrivileges(String nPath, int privileges) throws NotExecutableException, RepositoryException {
- ACLTemplate tmpl = getACLTemplate(acMgr, nPath);
- tmpl.setEntry(new ACEImpl(testUser.getPrincipal(), privileges, true));
- acMgr.setPolicy(nPath, tmpl);
- superuser.save();
- }
-
- private void withdrawPrivileges(String nPath, int privileges) throws NotExecutableException, RepositoryException {
- ACLTemplate tmpl = getACLTemplate(acMgr, nPath);
- tmpl.setEntry(new ACEImpl(testUser.getPrincipal(), privileges, false));
- acMgr.setPolicy(nPath, tmpl);
- superuser.save();
- }
-
- private void checkReadOnly(String path) throws RepositoryException {
- Privilege[] privs = testAcMgr.getPrivileges(path);
- assertTrue(privs.length == 1);
- assertEquals(PrivilegeRegistry.READ_PRIVILEGE, privs[0]);
- }
-
- public void testGrantedPermissions() throws RepositoryException, AccessDeniedException, NotExecutableException {
- /* precondition:
- testuser must have READ-only permission on test-node and below
- */
- checkReadOnly(path);
-
- // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES privileges at 'path'
- givePrivileges(path, PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.MODIFY_PROPERTIES);
- /*
- testuser must now have
- - ADD_NODE permission for child node
- - SET_PROPERTY permission for child props
- - REMOVE permission for child-props
- - READ-only permission for the node at 'path'
-
- testuser must not have
- - REMOVE permission for child node
- */
- String nonExChildPath = path + "/anyItem";
- assertTrue(testSession.hasPermission(nonExChildPath, "read,add_node,set_property"));
- assertFalse(testSession.hasPermission(nonExChildPath, "remove"));
-
- Node testN = testSession.getNode(path);
-
- // must be allowed to add child node
- testN.addNode(nodeName3, testNodeType);
- testSession.save();
-
- // must be allowed to remove child-property
- testSession.getProperty(childPPath).remove();
- testSession.save();
-
- // must be allowed to set child property again
- testN.setProperty(Text.getName(childPPath), "othervalue");
- testSession.save();
-
- // must not be allowed to remove child nodes
- try {
- testSession.getNode(childNPath).remove();
- testSession.save();
- fail("test-user is not allowed to remove a node below " + path);
- } catch (AccessDeniedException e) {
- // success
- }
-
- // must have read-only access on 'testN' and it's sibling
- assertTrue(testSession.hasPermission(path, "read"));
- assertFalse(testSession.hasPermission(path, "add_node,set_property,remove"));
- checkReadOnly(siblingPath);
- }
-
- public void testDeniedPermission() throws RepositoryException, NotExecutableException, InterruptedException {
- /* precondition:
- testuser must have READ-only permission on test-node and below
- */
- checkReadOnly(path);
-
- // withdraw READ privilege to 'testUser' at 'path'
- withdrawPrivileges(childNPath, PrivilegeRegistry.READ);
- /*
- testuser must now have
- - READ-only permission for the child-props of path
-
- testuser must not have
- - any permission on child-node and all its subtree
- */
-
- // must still have read-access to path, ...
- assertTrue(testSession.hasPermission(path, "read"));
- Node n = testSession.getNode(path);
- // ... siblings of childN
- testSession.getNode(childNPath2);
- // ... and props of path
- assertTrue(n.getProperties().hasNext());
-
- // must not have access to 'childNPath'
- assertFalse(testSession.itemExists(childNPath));
- try {
- Node testN = testSession.getNode(childNPath);
- fail("Read access has been denied -> cannot retrieve child node.");
- } catch (PathNotFoundException e) {
- // ok.
- }
-
- // must not have access to subtree below 'childNPath'
- assertFalse(testSession.itemExists(childchildPPath));
- try {
- testSession.getItem(childchildPPath);
- fail("Read access has been denied -> cannot retrieve prop below child node.");
- } catch (PathNotFoundException e) {
- // ok.
- }
- }
-
- public void testAccessControlRead() throws NotExecutableException, RepositoryException {
- checkReadOnly(path);
-
- // re-grant READ in order to have an ACL-node
- givePrivileges(path, PrivilegeRegistry.READ);
- // make sure the 'rep:policy' node has been created.
- assertTrue(superuser.itemExists(path + "/rep:policy"));
-
- /*
- Testuser must still have READ-only access only and must not be
- allowed to view the acl-node that has been created.
- */
- assertFalse(testAcMgr.hasPrivileges(path, new Privilege[] {PrivilegeRegistry.READ_AC_PRIVILEGE}));
- assertFalse(testSession.itemExists(path + "/rep:policy"));
- Node n = testSession.getNode(path);
- assertFalse(n.hasNode("rep:policy"));
- try {
- n.getNode("rep:policy");
- fail("Accessing the rep:policy node must throw PathNotFoundException.");
- } catch (PathNotFoundException e) {
- // ok.
- }
-
- /* Finally the test user must not be allowed to remove the policy. */
- try {
- testAcMgr.removePolicy(path);
- fail("Test user must not be allowed to remove the access control policy.");
- } catch (AccessDeniedException e) {
- // success
- }
+ protected PolicyEntry createEntry(Principal principal, int privileges, boolean isAllow, String[] restrictions) {
+ return new ACEImpl(principal, privileges, isAllow);
}
- public void testAccessControlModification() throws RepositoryException, NotExecutableException {
- /* precondition:
- testuser must have READ-only permission on test-node and below
- */
- checkReadOnly(path);
-
- // give 'testUser' ADD_CHILD_NODES|MODIFY_PROPERTIES| REMOVE_CHILD_NODES privileges at 'path'
- givePrivileges(path, PrivilegeRegistry.ADD_CHILD_NODES | PrivilegeRegistry.REMOVE_CHILD_NODES | PrivilegeRegistry.MODIFY_PROPERTIES);
- /*
- testuser must not have
- - permission to view AC items
- - permission to modify AC items
- */
-
- // make sure the 'rep:policy' node has been created.
- assertTrue(superuser.itemExists(path + "/rep:policy"));
-
- assertFalse(testSession.itemExists(path + "/rep:policy"));
- try {
- testAcMgr.getPolicy(path);
- fail("test user must not have READ_AC privilege.");
- } catch (AccessDeniedException e) {
- // success
- }
- try {
- testAcMgr.getEffectivePolicy(path);
- fail("test user must not have READ_AC privilege.");
- } catch (AccessDeniedException e) {
- // success
- }
- try {
- testAcMgr.getAccessControlEntries(path);
- fail("test user must not have READ_AC privilege.");
- } catch (AccessDeniedException e) {
- // success
- }
- try {
- testAcMgr.removePolicy(path);
- fail("test user must not have MODIFY_AC privilege.");
- } catch (AccessDeniedException e) {
- // success
- }
+ protected String[] getRestrictions(String path) {
+ return restrictions;
}
public void testAccessControlModification2() throws RepositoryException, NotExecutableException {
- /* precondition:
- testuser must have READ-only permission on test-node and below
+ /*
+ precondition:
+ testuser must have READ-only permission on test-node and below
*/
checkReadOnly(path);
// give 'testUser' READ_AC|MODIFY_AC privileges at 'path'
- givePrivileges(path, PrivilegeRegistry.READ_AC | PrivilegeRegistry.MODIFY_AC);
+ PolicyTemplate tmpl = givePrivileges(path, PrivilegeRegistry.READ_AC |
+ PrivilegeRegistry.MODIFY_AC, getRestrictions(path));
/*
testuser must
- still have the inherited READ permission.
@@ -343,7 +95,11 @@
*/
// make sure the 'rep:policy' node has been created.
- assertTrue(testSession.itemExists(path + "/rep:policy"));
+ assertTrue(superuser.itemExists(tmpl.getPath() + "/rep:policy"));
+
+ // test: MODIFY_AC granted at 'path'
+ assertTrue(testAcMgr.hasPrivileges(path, new Privilege[] {
+ PrivilegeRegistry.MODIFY_AC_PRIVILEGE}));
// test: READ_AC privilege does not apply outside of the tree.
try {
@@ -356,8 +112,8 @@
// test: MODIFY_AC privilege does not apply outside of the tree.
try {
testAcMgr.addAccessControlEntry(siblingPath,
- testUser.getPrincipal(),
- new Privilege[] {PrivilegeRegistry.WRITE_PRIVILEGE});
+ testUser.getPrincipal(),
+ new Privilege[] {PrivilegeRegistry.WRITE_PRIVILEGE});
fail("MODIFY_AC privilege must not apply outside of the tree it has applied to.");
} catch (AccessDeniedException e) {
// success
@@ -366,6 +122,7 @@
// test if testuser can READ access control on the path and on the
// entire subtree that gets the policy inherited.
AccessControlPolicy policy = testAcMgr.getPolicy(path);
+ AccessControlPolicy effPolicy = testAcMgr.getEffectivePolicy(path);
AccessControlPolicy effPOnChild = testAcMgr.getEffectivePolicy(childNPath);
// test if testuser can modify AC-items
@@ -374,7 +131,6 @@
testUser.getPrincipal(),
new Privilege[] {PrivilegeRegistry.WRITE_PRIVILEGE});
testSession.save();
-
assertTrue(testAcMgr.hasPrivileges(path,
new Privilege[] {PrivilegeRegistry.REMOVE_CHILD_NODES_PRIVILEGE}));
@@ -394,55 +150,5 @@
// ... and since the ACE is stored with the policy all right except
// READ must be gone.
checkReadOnly(path);
- }
-
- public void testACItemsAreProtected() throws NotExecutableException, RepositoryException {
- // make sure a rep:policy node is present at 'path'
- givePrivileges(path, PrivilegeRegistry.WRITE);
- Node n = ((SessionImpl) superuser).getNode(path);
- Node policyNode = n.getNode("rep:policy");
-
- assertTrue("The rep:policy node must be protected", policyNode.getDefinition().isProtected());
- try {
- policyNode.remove();
- fail("rep:policy node must be protected.");
- } catch (ConstraintViolationException e) {
- // success
- }
- Node aceNode = null;
- for (NodeIterator it = policyNode.getNodes(); it.hasNext();) {
- n = it.nextNode();
- if (n.isNodeType("rep:ACE")) {
- aceNode = n;
- break;
- }
- }
- if (aceNode == null) {
- fail("Child-node expected below rep:policy node.");
- }
- try {
- aceNode.remove();
- fail("ACE node must be protected.");
- } catch (ConstraintViolationException e) {
- // success
- }
- try {
- aceNode.setProperty("anyProperty", "anyValue");
- fail("ACE node must be protected.");
- } catch (ConstraintViolationException e) {
- // success
- }
- try {
- policyNode.setProperty("test", "anyvalue");
- fail("rep:policy node must be protected.");
- } catch (ConstraintViolationException e) {
- // success
- }
- try {
- policyNode.addNode("test", aceNode.getPrimaryNodeType().getName());
- fail("rep:policy node must be protected.");
- } catch (ConstraintViolationException e) {
- // success
- }
}
}
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java?rev=649172&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java Thu Apr 17 09:27:09 2008
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.security.authorization.combined;
+
+import org.apache.jackrabbit.core.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.core.security.authorization.AbstractEvaluationTest;
+import org.apache.jackrabbit.core.security.authorization.PolicyEntry;
+import org.apache.jackrabbit.core.security.authorization.PolicyTemplate;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.RepositoryException;
+import java.security.Principal;
+
+/**
+ * <code>EvaluationTest</code>...
+ */
+public class EvaluationTest extends AbstractEvaluationTest {
+
+ private static Logger log = LoggerFactory.getLogger(EvaluationTest.class);
+
+ private String testPolicyPath;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ JackrabbitAccessControlManager jam;
+ if (acMgr instanceof JackrabbitAccessControlManager) {
+ jam = (JackrabbitAccessControlManager) acMgr;
+ } else {
+ throw new NotExecutableException();
+ }
+ try {
+ AccessControlPolicy rootPolicy = acMgr.getPolicy("/");
+ if (!(rootPolicy instanceof PolicyTemplateImpl)) {
+ throw new NotExecutableException();
+ }
+ } catch (RepositoryException e) {
+ throw new NotExecutableException();
+ }
+
+
+ StringBuffer b = new StringBuffer("/rep:accesscontrol");
+ Principal principal = testUser.getPrincipal();
+ testPolicyPath = jam.editPolicy(principal).getPath();
+ }
+
+ protected void clearACInfo() {
+ try {
+ acMgr.removePolicy(testPolicyPath);
+ superuser.save();
+ } catch (RepositoryException e) {
+ // log error and ignore
+ log.error(e.getMessage());
+ }
+ }
+
+ protected PolicyTemplate getPolicyTemplate(AccessControlManager acM, String path) throws RepositoryException, AccessDeniedException, NotExecutableException {
+ if (acM instanceof JackrabbitAccessControlManager) {
+ PolicyTemplate pt = ((JackrabbitAccessControlManager) acM).editPolicy(testPolicyPath);
+ if (pt instanceof PolicyTemplateImpl) {
+ return (PolicyTemplateImpl) pt;
+ }
+ }
+ throw new NotExecutableException();
+ }
+
+ protected PolicyEntry createEntry(Principal principal, int privileges, boolean isAllow, String[] restrictions) {
+ String nodePath = restrictions[0];
+ String glob = restrictions[1];
+ return new PolicyEntryImpl(principal, privileges, isAllow, nodePath, glob);
+ }
+
+ protected String[] getRestrictions(String path) {
+ return new String[] {path, "*"};
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/EvaluationTest.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java?rev=649172&r1=649171&r2=649172&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/combined/TestAll.java Thu Apr 17 09:27:09 2008
@@ -23,8 +23,8 @@
suite.addTestSuite(PolicyEntryImplTest.class);
suite.addTestSuite(GlobPatternTest.class);
- //todo: add evaluation tests.
-
+ suite.addTestSuite(EvaluationTest.class);
+
return suite;
}
}