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 2009/08/11 10:28:23 UTC
svn commit: r803026 - in /jackrabbit/trunk:
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/
jackrabbit-core/sr...
Author: angela
Date: Tue Aug 11 08:28:22 2009
New Revision: 803026
URL: http://svn.apache.org/viewvc?rev=803026&view=rev
Log:
JCR-2253: Discovery of privileges of any set of Principals
Added:
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManagerTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/TestAll.java
Modified:
jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java?rev=803026&r1=803025&r2=803026&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java Tue Aug 11 08:28:22 2009
@@ -19,9 +19,12 @@
import javax.jcr.AccessDeniedException;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.PathNotFoundException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.Privilege;
import java.security.Principal;
+import java.util.Set;
/**
* <code>JackrabbitAccessControlManager</code> provides extensions to the
@@ -62,4 +65,76 @@
* @throws RepositoryException
*/
JackrabbitAccessControlPolicy[] getPolicies(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException;
+
+ /**
+ * Returns whether the given set of <code>Principal</code>s has the specified
+ * privileges for absolute path <code>absPath</code>, which must be an
+ * existing node.
+ * <p>
+ * Testing an aggregate privilege is equivalent to testing each non
+ * aggregate privilege among the set returned by calling
+ * <code>Privilege.getAggregatePrivileges()</code> for that privilege.
+ * <p>
+ * The results reported by the this method reflect the net <i>effect</i> of
+ * the currently applied control mechanisms. It does not reflect unsaved
+ * access control policies or unsaved access control entries. Changes to
+ * access control status caused by these mechanisms only take effect on
+ * <code>Session.save()</code> and are only then reflected in the results of
+ * the privilege test methods.
+ * <p>
+ * Since this method allows to view the privileges of principals other
+ * than included in the editing session, this method must throw
+ * <code>AccessDeniedException</code> if the session lacks
+ * <code>READ_ACCESS_CONTROL</code> privilege for the <code>absPath</code>
+ * node.
+ *
+ * @param absPath an absolute path.
+ * @param principals a set of <code>Principal</code>s for which is the
+ * given privileges are tested.
+ * @param privileges an array of <code>Privilege</code>s.
+ * @return <code>true</code> if the session has the specified privileges;
+ * <code>false</code> otherwise.
+ * @throws javax.jcr.PathNotFoundException if no node at <code>absPath</code> exists
+ * or the session does not have sufficent access to retrieve a node at that location.
+ * @throws AccessDeniedException if the session lacks
+ * <code>READ_ACCESS_CONTROL</code> privilege for the <code>absPath</code> node.
+ * @throws RepositoryException if another error occurs.
+ */
+ public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges)
+ throws PathNotFoundException, AccessDeniedException, RepositoryException;
+
+ /**
+ * Returns the privileges the given set of <code>Principal</code>s has for
+ * absolute path <code>absPath</code>, which must be an existing node.
+ * <p>
+ * The returned privileges are those for which {@link #hasPrivileges} would
+ * return <code>true</code>.
+ * <p>
+ * The results reported by the this method reflect the net <i>effect</i> of
+ * the currently applied control mechanisms. It does not reflect unsaved
+ * access control policies or unsaved access control entries. Changes to
+ * access control status caused by these mechanisms only take effect on
+ * <code>Session.save()</code> and are only then reflected in the results of
+ * the privilege test methods.
+ * <p>
+ * Since this method allows to view the privileges of principals other
+ * than included in the editing session, this method must throw
+ * <code>AccessDeniedException</code> if the session lacks
+ * <code>READ_ACCESS_CONTROL</code> privilege for the <code>absPath</code>
+ * node.
+ *
+ *
+ * @param absPath an absolute path.
+ * @param principals a set of <code>Principal</code>s for which is the
+ * privileges are retrieved.
+ * @return an array of <code>Privilege</code>s.
+ * @throws PathNotFoundException if no node at <code>absPath</code> exists
+ * or the session does not have sufficient access to retrieve a node at that
+ * location.
+ * @throws AccessDeniedException if the session lacks <code>READ_ACCESS_CONTROL</code>
+ * privilege for the <code>absPath</code> node.
+ * @throws RepositoryException if another error occurs.
+ */
+ public Privilege[] getPrivileges(String absPath, Set<Principal> principals)
+ throws PathNotFoundException, AccessDeniedException, RepositoryException;
}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java?rev=803026&r1=803025&r2=803026&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java Tue Aug 11 08:28:22 2009
@@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.security.Principal;
import javax.jcr.AccessDeniedException;
import javax.jcr.PathNotFoundException;
@@ -274,5 +275,19 @@
// cannot determine the effective policies for the system session.
return new AccessControlPolicy[0];
}
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#hasPrivileges(String, Set, Privilege[])
+ */
+ public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#getPrivileges(String, Set)
+ */
+ public Privilege[] getPrivileges(String absPath, Set<Principal> principals) throws PathNotFoundException, RepositoryException {
+ throw new UnsupportedOperationException("not implemented");
+ }
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java?rev=803026&r1=803025&r2=803026&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java Tue Aug 11 08:28:22 2009
@@ -326,7 +326,6 @@
checkInitialized();
checkPermission(absPath, Permission.READ_AC);
- // TODO: acProvider may not retrieve the correct policy in case of transient modifications
return acProvider.getEffectivePolicies(getPath(absPath));
}
@@ -395,6 +394,40 @@
}
return editor.getPolicies(principal);
}
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#hasPrivileges(String, Set, Privilege[])
+ */
+ public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
+ checkInitialized();
+ checkValidNodePath(absPath);
+ checkPermission(absPath, Permission.READ_AC);
+
+ if (privileges == null || privileges.length == 0) {
+ // null or empty privilege array -> return true
+ log.debug("No privileges passed -> allowed.");
+ return true;
+ } else {
+ int privs = PrivilegeRegistry.getBits(privileges);
+ Path p = resolver.getQPath(absPath);
+ return (acProvider.compilePermissions(principals).getPrivileges(p) | ~privs) == -1;
+ }
+ }
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#getPrivileges(String, Set)
+ */
+ public Privilege[] getPrivileges(String absPath, Set<Principal> principals) throws PathNotFoundException, RepositoryException {
+ checkInitialized();
+ checkValidNodePath(absPath);
+ checkPermission(absPath, Permission.READ_AC);
+
+ int bits = acProvider.compilePermissions(principals).getPrivileges(resolver.getQPath(absPath));
+ return (bits == PrivilegeRegistry.NO_PRIVILEGE) ?
+ new Privilege[0] :
+ privilegeRegistry.getPrivileges(bits);
+ }
+
//---------------------------------------< AbstractAccessControlManager >---
/**
* @see AbstractAccessControlManager#checkInitialized()
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=803026&r1=803025&r2=803026&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 Tue Aug 11 08:28:22 2009
@@ -38,6 +38,8 @@
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.Set;
/**
* <code>SimpleAccessManager</code> ...
@@ -295,4 +297,44 @@
throw new PathNotFoundException(absPath);
}
}
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#hasPrivileges(String, Set, Privilege[])
+ */
+ public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges) throws PathNotFoundException, RepositoryException {
+ if (anonymous) {
+ // anonymous doesn't have READ_AC privilege
+ throw new AccessDeniedException();
+ }
+
+ if (principals.size() == 1) {
+ Principal princ = principals.iterator().next();
+ if (princ instanceof AnonymousPrincipal) {
+ return privileges.length == 1 && privileges[0].equals(privilegeRegistry.getPrivilege(Privilege.JCR_READ));
+ }
+ }
+
+ // @todo check permission based on principals
+ return true;
+ }
+
+ /**
+ * @see org.apache.jackrabbit.api.security.JackrabbitAccessControlManager#getPrivileges(String, Set)
+ */
+ public Privilege[] getPrivileges(String absPath, Set<Principal> principals) throws PathNotFoundException, RepositoryException {
+ if (anonymous) {
+ // anonymous doesn't have READ_AC privilege
+ throw new AccessDeniedException();
+ }
+
+ if (principals.size() == 1) {
+ Principal princ = principals.iterator().next();
+ if (princ instanceof AnonymousPrincipal) {
+ return new Privilege[] {privilegeRegistry.getPrivilege(Privilege.JCR_READ)};
+ }
+ }
+
+ // @todo check permission based on principals
+ return new Privilege[] {privilegeRegistry.getPrivilege(Privilege.JCR_ALL)};
+ }
}
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManagerTest.java?rev=803026&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManagerTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManagerTest.java Tue Aug 11 08:28:22 2009
@@ -0,0 +1,108 @@
+/*
+ * 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.api.security;
+
+import org.apache.jackrabbit.test.api.security.AbstractAccessControlTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.apache.jackrabbit.core.security.principal.EveryonePrincipal;
+
+import javax.jcr.Session;
+import javax.jcr.RepositoryException;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.security.Privilege;
+import java.util.Collections;
+import java.util.Set;
+import java.security.Principal;
+
+/**
+ * <code>JackrabbitAccessControlManagerTest</code>...
+ */
+public class JackrabbitAccessControlManagerTest extends AbstractAccessControlTest {
+
+ Set<Principal> principals;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ if (!(acMgr instanceof JackrabbitAccessControlManager)) {
+ throw new NotExecutableException();
+ }
+
+ Principal principal = EveryonePrincipal.getInstance();
+ principals = Collections.singleton(principal);
+ }
+
+ public void testHasPrivilegeThrowsAccessDenied() throws RepositoryException {
+ Session readOnly = getHelper().getReadOnlySession();
+ JackrabbitAccessControlManager jacMgr = (JackrabbitAccessControlManager) readOnly.getAccessControlManager();
+ try {
+ jacMgr.hasPrivileges(testRoot, principals, new Privilege[] {jacMgr.privilegeFromName(Privilege.JCR_READ)});
+ fail("ReadOnly session isn't allowed to determine the privileges of other principals.");
+ } catch (AccessDeniedException e) {
+ // success
+ } finally {
+ readOnly.logout();
+ }
+ }
+
+ public void testGetPrivilegesThrowsAccessDenied() throws RepositoryException {
+ Session readOnly = getHelper().getReadOnlySession();
+ JackrabbitAccessControlManager jacMgr = (JackrabbitAccessControlManager) readOnly.getAccessControlManager();
+ try {
+ jacMgr.getPrivileges(testRoot, principals);
+ fail("ReadOnly session isn't allowed to determine the privileges of other principals.");
+ } catch (AccessDeniedException e) {
+ // success
+ } finally {
+ readOnly.logout();
+ }
+ }
+
+ public void testHasPrivilegesWithInvalidPath() throws RepositoryException {
+ JackrabbitAccessControlManager jacMgr = (JackrabbitAccessControlManager) acMgr;
+ String invalidPath = testRoot;
+ while (superuser.nodeExists(invalidPath)) {
+ invalidPath += "_";
+ }
+
+ try {
+ jacMgr.hasPrivileges(invalidPath, principals, new Privilege[] {jacMgr.privilegeFromName(Privilege.JCR_READ)});
+ fail("Invalid path must be detected");
+ } catch (PathNotFoundException e) {
+ // success
+ }
+ }
+
+ public void testGetPrivilegesWithInvalidPath() throws RepositoryException {
+ JackrabbitAccessControlManager jacMgr = (JackrabbitAccessControlManager) acMgr;
+ String invalidPath = testRoot;
+ while (superuser.nodeExists(invalidPath)) {
+ invalidPath += "_";
+ }
+
+ try {
+ jacMgr.getPrivileges(invalidPath, principals);
+ fail("Invalid path must be detected");
+ } catch (PathNotFoundException e) {
+ // success
+ }
+ }
+
+ // TODO add more tests
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/TestAll.java?rev=803026&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/TestAll.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/TestAll.java Tue Aug 11 08:28:22 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.api.security;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <code>TestAll</code>...
+ */
+public class TestAll extends AbstractJCRTest {
+
+ /**
+ * Returns a <code>Test</code> suite that executes all tests inside this
+ * package.
+ *
+ * @return a <code>Test</code> suite that executes all tests inside this
+ * package.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("api.security tests");
+
+ suite.addTestSuite(JackrabbitAccessControlManagerTest.class);
+
+ return suite;
+ }
+}
\ No newline at end of file