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/11/18 13:38:26 UTC
svn commit: r881752 - in /jackrabbit/trunk:
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/secur...
Author: angela
Date: Wed Nov 18 12:38:25 2009
New Revision: 881752
URL: http://svn.apache.org/viewvc?rev=881752&view=rev
Log:
JCR-2397 - AccessControlEntries should be orderable
Modified:
jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java
jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplateTest.java
Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.java Wed Nov 18 12:38:25 2009
@@ -18,10 +18,12 @@
import javax.jcr.RepositoryException;
import javax.jcr.Value;
+import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.Privilege;
+import javax.jcr.security.AccessControlEntry;
import java.security.Principal;
import java.util.Map;
@@ -112,4 +114,22 @@
boolean addEntry(Principal principal, Privilege[] privileges,
boolean isAllow, Map<String, Value> restrictions)
throws AccessControlException, RepositoryException;
+
+ /**
+ * If the <code>AccessControlList</code> implementation supports
+ * reordering of entries the specified <code>srcEntry</code> is inserted
+ * at the position of the specified <code>destEntry</code>.<p/>
+ * If <code>destEntry</code> is <code>null</code> the entry is moved to the
+ * end of the list.<p/>
+ * If srcChildRelPath and destChildRelPath are the same no changes are made.
+ *
+ * @param srcEntry The access control entry to be moved within the list.
+ * @param destEntry The entry before which the <code>srcEntry</code> will be moved.
+ * @throws AccessControlException If any of the given entries is invalid or
+ * cannot be handled by the implementation.
+ * @throws UnsupportedRepositoryOperationException If ordering is not supported.
+ * @throws RepositoryException If another error occurs.
+ */
+ void orderBefore(AccessControlEntry srcEntry, AccessControlEntry destEntry)
+ throws AccessControlException, UnsupportedRepositoryOperationException, RepositoryException;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java Wed Nov 18 12:38:25 2009
@@ -19,14 +19,19 @@
import java.security.Principal;
import java.util.Collections;
import java.util.Map;
+import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
+import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.Privilege;
+import javax.jcr.security.AccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* <code>AbstractACLTemplate</code>...
@@ -34,6 +39,8 @@
public abstract class AbstractACLTemplate implements JackrabbitAccessControlList,
AccessControlConstants {
+ private static Logger log = LoggerFactory.getLogger(AbstractACLTemplate.class);
+
/**
* Path of the node this ACL template has been created for.
*/
@@ -65,6 +72,17 @@
boolean isAllow,
Map<String, Value> restrictions) throws AccessControlException;
+ /**
+ * Return the list of entries, if they are held in a orderable list.
+ *
+ * @return the list of entries.
+ * @throws UnsupportedRepositoryOperationException If the implementation
+ * does not held the entries in a list.
+ * @throws RepositoryException
+ * @see #orderBefore(AccessControlEntry, AccessControlEntry)
+ */
+ protected abstract List<? extends AccessControlEntry> getEntries() throws UnsupportedRepositoryOperationException, RepositoryException;
+
//--------------------------------------< JackrabbitAccessControlPolicy >---
/**
* @see org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy#getPath()
@@ -82,6 +100,34 @@
return addEntry(principal, privileges, isAllow, Collections.<String, Value>emptyMap());
}
+ /**
+ *
+ * @param srcEntry The access control entry to be moved within the list.
+ * @param destEntry The entry before which the <code>srcEntry</code> will be moved.
+ * @throws AccessControlException
+ * @throws UnsupportedRepositoryOperationException
+ * @throws RepositoryException
+ */
+ public void orderBefore(AccessControlEntry srcEntry, AccessControlEntry destEntry) throws AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
+ if (srcEntry.equals(destEntry)) {
+ log.debug("srcEntry equals destEntry -> no reordering required.");
+ return;
+ }
+
+ List entries = getEntries();
+ int index = (destEntry == null) ? entries.size()-1 : entries.indexOf(destEntry);
+ if (index < 0) {
+ throw new AccessControlException("destEntry not contained in this AccessControlList");
+ } else {
+ if (entries.remove(srcEntry)) {
+ // re-insert the srcEntry at the new position.
+ entries.add(index, srcEntry);
+ } else {
+ // src entry not contained in this list.
+ throw new AccessControlException("srcEntry not contained in this AccessControlList");
+ }
+ }
+ }
//--------------------------------------------------< AccessControlList >---
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java Wed Nov 18 12:38:25 2009
@@ -130,12 +130,16 @@
return accessControlEntries.length;
}
- public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow) throws AccessControlException, RepositoryException {
- throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getApplicablePolicies in order to obtain an modifiable ACL.");
+ public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicies in order to obtain an modifiable ACL.");
}
- public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow, Map<String, Value> restrictions) throws AccessControlException, RepositoryException {
- throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getApplicablePolicies in order to obtain an modifiable ACL.");
+ public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow, Map<String, Value> restrictions) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicies in order to obtain an modifiable ACL.");
+ }
+
+ public void orderBefore(AccessControlEntry srcEntry, AccessControlEntry destEntry) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicy in order to obtain a modifiable ACL.");
}
public String getPath() {
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java Wed Nov 18 12:38:25 2009
@@ -19,7 +19,6 @@
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -48,9 +47,11 @@
import org.slf4j.LoggerFactory;
/**
- * Implementation of the {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList} interface that
- * is detached from the effective access control content. Consequently, any
- * modifications applied to this ACL only take effect, if the policy gets
+ * Implementation of the
+ * {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList}
+ * interface that is detached from the effective access control content.
+ * Consequently, any modifications applied to this ACL only take effect, if
+ * the policy gets
* {@link javax.jcr.security.AccessControlManager#setPolicy(String, javax.jcr.security.AccessControlPolicy) reapplied}
* to the <code>AccessControlManager</code> and the changes are saved.
*/
@@ -59,11 +60,10 @@
private static final Logger log = LoggerFactory.getLogger(ACLTemplate.class);
/**
- * Map containing the entries of this ACL Template using the principal
- * name as key. The value represents a List containing maximal one grant
- * and one deny ACE per principal.
+ * List containing the entries of this ACL Template with maximal one
+ * grant and one deny ACE per principal.
*/
- private final Map<String, List<Entry>> entries = new LinkedHashMap<String, List<Entry>>();
+ private final List<Entry> entries = new ArrayList<Entry>();
/**
* The principal manager used for validation checks
@@ -140,57 +140,54 @@
}
}
- private List<? extends AccessControlEntry> internalGetEntries() {
- List<Entry> l = new ArrayList<Entry>();
- for (List<Entry> o : entries.values()) {
- l.addAll(o);
- }
- return l;
- }
-
private List<Entry> internalGetEntries(Principal principal) {
String principalName = principal.getName();
- if (entries.containsKey(principalName)) {
- return entries.get(principalName);
- } else {
- return new ArrayList<Entry>(2);
+ List entriesPerPrincipal = new ArrayList(2);
+ for (Entry entry : entries) {
+ if (principalName.equals(entry.getPrincipal().getName())) {
+ entriesPerPrincipal.add(entry);
+ }
}
+ return entriesPerPrincipal;
}
private synchronized boolean internalAdd(Entry entry) throws AccessControlException {
Principal principal = entry.getPrincipal();
- List<Entry> l = internalGetEntries(principal);
- if (l.isEmpty()) {
- // simple case: just add the new entry
- l.add(entry);
- entries.put(principal.getName(), l);
+ List<Entry> entriesPerPrincipal = internalGetEntries(principal);
+ if (entriesPerPrincipal.isEmpty()) {
+ // simple case: just add the new entry at the end of the list.
+ entries.add(entry);
return true;
} else {
- if (l.contains(entry)) {
+ if (entriesPerPrincipal.contains(entry)) {
// the same entry is already contained -> no modification
return false;
}
// check if need to adjust existing entries
+ int updateIndex = -1;
Entry complementEntry = null;
- Entry[] entries = l.toArray(new Entry[l.size()]);
- for (int i = 0; i < entries.length; i++) {
- if (entry.isAllow() == entries[i].isAllow()) {
- int existingPrivs = entries[i].getPrivilegeBits();
+
+ for (Entry e : entriesPerPrincipal) {
+ if (entry.isAllow() == e.isAllow()) {
+ int existingPrivs = e.getPrivilegeBits();
if ((existingPrivs | ~entry.getPrivilegeBits()) == -1) {
// all privileges to be granted/denied are already present
// in the existing entry -> not modified
return false;
}
+ // remember the index of the existing entry to be updated later on.
+ updateIndex = entries.indexOf(e);
+
// remove the existing entry and create a new that includes
// both the new privileges and the existing ones.
- l.remove(i);
- int mergedBits = entries[i].getPrivilegeBits() | entry.getPrivilegeBits();
+ entries.remove(e);
+ int mergedBits = e.getPrivilegeBits() | entry.getPrivilegeBits();
Privilege[] mergedPrivs = privilegeRegistry.getPrivileges(mergedBits);
// omit validation check.
entry = new Entry(entry.getPrincipal(), mergedPrivs, entry.isAllow(), valueFactory);
} else {
- complementEntry = entries[i];
+ complementEntry = e;
}
}
@@ -198,22 +195,34 @@
// grant/deny the same privileges -> remove privileges that are now
// denied/granted.
if (complementEntry != null) {
+
int complPrivs = complementEntry.getPrivilegeBits();
int resultPrivs = Permission.diff(complPrivs, entry.getPrivilegeBits());
+
if (resultPrivs == PrivilegeRegistry.NO_PRIVILEGE) {
- l.remove(complementEntry);
+ // remove the complement entry as the new entry covers
+ // all privileges granted by the existing entry.
+ entries.remove(complementEntry);
+ updateIndex--;
+
} else if (resultPrivs != complPrivs) {
- l.remove(complementEntry);
- // omit validation check
+ // replace the existing entry having the privileges adjusted
+ int index = entries.indexOf(complementEntry);
+ entries.remove(complementEntry);
Entry tmpl = new Entry(entry.getPrincipal(),
privilegeRegistry.getPrivileges(resultPrivs),
!entry.isAllow(), valueFactory);
- l.add(tmpl);
+ entries.add(index, tmpl);
} /* else: does not need to be modified.*/
}
- // finally add the new entry at the end.
- l.add(entry);
+ // finally update the existing entry or add the new entry passed
+ // to this method at the end.
+ if (updateIndex < 0) {
+ entries.add(entry);
+ } else {
+ entries.add(updateIndex, entry);
+ }
return true;
}
}
@@ -236,12 +245,19 @@
}
}
+ /**
+ * @see org.apache.jackrabbit.core.security.authorization.AbstractACLTemplate#getEntries()
+ */
+ protected List<? extends AccessControlEntry> getEntries() {
+ return entries;
+ }
+
//--------------------------------------------------< AccessControlList >---
/**
* @see javax.jcr.security.AccessControlList#getAccessControlEntries()
*/
public AccessControlEntry[] getAccessControlEntries() throws RepositoryException {
- List<? extends AccessControlEntry> l = internalGetEntries();
+ List<? extends AccessControlEntry> l = getEntries();
return l.toArray(new AccessControlEntry[l.size()]);
}
@@ -253,11 +269,8 @@
if (!(ace instanceof Entry)) {
throw new AccessControlException("Invalid AccessControlEntry implementation " + ace.getClass().getName() + ".");
}
- List<Entry> l = internalGetEntries(ace.getPrincipal());
- if (l.remove(ace)) {
- if (l.isEmpty()) {
- entries.remove(ace.getPrincipal().getName());
- }
+ if (entries.contains(ace)) {
+ entries.remove(ace);
} else {
throw new AccessControlException("AccessControlEntry " + ace + " cannot be removed from ACL defined at " + getPath());
}
@@ -294,7 +307,7 @@
* @see org.apache.jackrabbit.api.security.JackrabbitAccessControlList#size()
*/
public int size() {
- return internalGetEntries().size();
+ return getEntries().size();
}
/**
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java Wed Nov 18 12:38:25 2009
@@ -167,7 +167,14 @@
throw new AccessControlException("Missing mandatory restriction: " + jcrNodePathName);
}
}
-
+
+ /**
+ * @see org.apache.jackrabbit.core.security.authorization.AbstractACLTemplate#getEntries()
+ */
+ protected List<? extends AccessControlEntry> getEntries() {
+ return entries;
+ }
+
//----------------------------------------< JackrabbitAccessControlList >---
/**
* @see JackrabbitAccessControlList#getRestrictionNames()
Modified: jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd Wed Nov 18 12:38:25 2009
@@ -558,6 +558,7 @@
abstract
[rep:ACL] > rep:Policy
+ orderable
+ * (rep:ACE) = rep:GrantACE protected IGNORE
[rep:ACE]
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.java Wed Nov 18 12:38:25 2009
@@ -66,6 +66,8 @@
protected abstract JackrabbitAccessControlList createEmptyTemplate(String path) throws RepositoryException;
+ protected abstract Principal getSecondPrincipal() throws Exception;
+
public void testEmptyTemplate() throws RepositoryException {
JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
@@ -260,4 +262,63 @@
// success
}
}
+
+ public void testReorder() throws Exception {
+ Privilege[] read = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] write = privilegesFromName(Privilege.JCR_WRITE);
+
+ Principal p2 = getSecondPrincipal();
+
+ AbstractACLTemplate acl = (AbstractACLTemplate) createEmptyTemplate(getTestPath());
+ acl.addAccessControlEntry(testPrincipal, read);
+ acl.addEntry(testPrincipal, write, false);
+ acl.addAccessControlEntry(p2, write);
+
+ AccessControlEntry[] entries = acl.getAccessControlEntries();
+
+ assertEquals(3, entries.length);
+ AccessControlEntry aReadTP = entries[0];
+ AccessControlEntry dWriteTP = entries[1];
+ AccessControlEntry aWriteP2 = entries[2];
+
+ // reorder aWriteP2 to the first position
+ acl.orderBefore(aWriteP2, aReadTP);
+ assertEquals(0, acl.getEntries().indexOf(aWriteP2));
+ assertEquals(1, acl.getEntries().indexOf(aReadTP));
+ assertEquals(2, acl.getEntries().indexOf(dWriteTP));
+
+ // reorder aReadTP to the end of the list
+ acl.orderBefore(aReadTP, null);
+ assertEquals(0, acl.getEntries().indexOf(aWriteP2));
+ assertEquals(1, acl.getEntries().indexOf(dWriteTP));
+ assertEquals(2, acl.getEntries().indexOf(aReadTP));
+ }
+
+ public void testReorderInvalidElements() throws Exception {
+ Privilege[] read = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] write = privilegesFromName(Privilege.JCR_WRITE);
+
+ Principal p2 = getSecondPrincipal();
+
+ AbstractACLTemplate acl = (AbstractACLTemplate) createEmptyTemplate(getTestPath());
+ acl.addAccessControlEntry(testPrincipal, read);
+ acl.addAccessControlEntry(p2, write);
+
+ AbstractACLTemplate acl2 = (AbstractACLTemplate) createEmptyTemplate(getTestPath());
+ acl2.addEntry(testPrincipal, write, false);
+
+ AccessControlEntry invalid = acl2.getEntries().get(0);
+ try {
+ acl.orderBefore(invalid, acl.getEntries().get(0));
+ fail("src entry not contained in list -> reorder should fail.");
+ } catch (AccessControlException e) {
+ // success
+ }
+ try {
+ acl.orderBefore(acl.getEntries().get(0), invalid);
+ fail("dest entry not contained in list -> reorder should fail.");
+ } catch (AccessControlException e) {
+ // success
+ }
+ }
}
\ No newline at end of file
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=881752&r1=881751&r2=881752&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 Wed Nov 18 12:38:25 2009
@@ -18,11 +18,13 @@
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.security.authorization.AbstractACLTemplateTest;
import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
import org.apache.jackrabbit.test.NotExecutableException;
import javax.jcr.RepositoryException;
@@ -32,12 +34,15 @@
import java.security.Principal;
import java.security.acl.Group;
import java.util.Collections;
+import java.util.Map;
/**
* <code>ACLTemplateTest</code>...
*/
public class ACLTemplateTest extends AbstractACLTemplateTest {
+ private Map<String, Value> restrictions = Collections.<String, Value>emptyMap();
+
protected String getTestPath() {
return "/ab/c/d";
}
@@ -49,10 +54,14 @@
return new ACLTemplate(path, princicipalMgr, privilegeRegistry, sImpl.getValueFactory());
}
+ protected Principal getSecondPrincipal() throws Exception {
+ return pMgr.getEveryone();
+ }
+
public void testMultipleEntryEffect() throws RepositoryException, NotExecutableException {
JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
Privilege[] privileges = privilegesFromName(Privilege.JCR_READ);
- pt.addEntry(testPrincipal, privileges, true, Collections.<String, Value>emptyMap());
+ pt.addEntry(testPrincipal, privileges, true, restrictions);
// new entry extends privileges.
privileges = privilegesFromNames(new String[] {
@@ -60,7 +69,7 @@
Privilege.JCR_ADD_CHILD_NODES});
assertTrue(pt.addEntry(testPrincipal,
privileges,
- true, Collections.<String, Value>emptyMap()));
+ true, restrictions));
// net-effect: only a single allow-entry with both privileges
assertTrue(pt.size() == 1);
@@ -68,14 +77,14 @@
// adding just ADD_CHILD_NODES -> must not remove READ privilege
Privilege[] achPrivs = privilegesFromName(Privilege.JCR_ADD_CHILD_NODES);
- assertFalse(pt.addEntry(testPrincipal, achPrivs, true, Collections.<String, Value>emptyMap()));
+ assertFalse(pt.addEntry(testPrincipal, achPrivs, true, restrictions));
// net-effect: only a single allow-entry with add_child_nodes + read privilege
assertTrue(pt.size() == 1);
assertSamePrivileges(privileges, pt.getAccessControlEntries()[0].getPrivileges());
// revoke the 'READ' privilege
privileges = privilegesFromName(Privilege.JCR_READ);
- assertTrue(pt.addEntry(testPrincipal, privileges, false, Collections.<String, Value>emptyMap()));
+ assertTrue(pt.addEntry(testPrincipal, privileges, false, restrictions));
// net-effect: 2 entries one allowing ADD_CHILD_NODES, the other denying READ
assertTrue(pt.size() == 2);
assertSamePrivileges(privilegesFromName(Privilege.JCR_ADD_CHILD_NODES),
@@ -160,13 +169,113 @@
JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
Privilege[] privileges = privilegesFromName(Privilege.JCR_READ);
- pt.addEntry(testPrincipal, privileges, true, Collections.<String, Value>emptyMap());
+ pt.addEntry(testPrincipal, privileges, true, restrictions);
// same entry but with revers 'isAllow' flag
- assertTrue(pt.addEntry(testPrincipal, privileges, false, Collections.<String, Value>emptyMap()));
+ assertTrue(pt.addEntry(testPrincipal, privileges, false, restrictions));
// net-effect: only a single deny-read entry
- assertTrue(pt.size() == 1);
+ assertEquals(1, pt.size());
assertSamePrivileges(privileges, pt.getAccessControlEntries()[0].getPrivileges());
}
+
+ public void testUpdateEntry() throws RepositoryException, NotExecutableException {
+ JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
+
+ Privilege[] readPriv = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] writePriv = privilegesFromName(Privilege.JCR_WRITE);
+
+ Principal principal2 = pMgr.getEveryone();
+
+ pt.addEntry(testPrincipal, readPriv, true, restrictions);
+ pt.addEntry(principal2, readPriv, true, restrictions);
+ pt.addEntry(testPrincipal, writePriv, false, restrictions);
+
+ // adding an entry that should update the existing allow-entry for everyone.
+ pt.addEntry(principal2, writePriv, true, restrictions);
+
+ AccessControlEntry[] entries = pt.getAccessControlEntries();
+ assertEquals(3, entries.length);
+ JackrabbitAccessControlEntry princ2AllowEntry = (JackrabbitAccessControlEntry) entries[1];
+ assertEquals(principal2, princ2AllowEntry.getPrincipal());
+ assertTrue(princ2AllowEntry.isAllow());
+ assertSamePrivileges(new Privilege[] {readPriv[0], writePriv[0]}, princ2AllowEntry.getPrivileges());
+ }
+
+ public void testUpdateComplementaryEntry() throws RepositoryException, NotExecutableException {
+ JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
+
+ Privilege[] readPriv = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] writePriv = privilegesFromName(Privilege.JCR_WRITE);
+ Principal principal2 = pMgr.getEveryone();
+
+ pt.addEntry(testPrincipal, readPriv, true, restrictions);
+ pt.addEntry(principal2, readPriv, true, restrictions);
+ pt.addEntry(testPrincipal, writePriv, false, restrictions);
+ pt.addEntry(principal2, writePriv, true, restrictions);
+ // entry complementary to the first entry
+ // -> must remove the allow-READ entry and update the deny-WRITE entry.
+ pt.addEntry(testPrincipal, readPriv, false, restrictions);
+
+ AccessControlEntry[] entries = pt.getAccessControlEntries();
+
+ assertEquals(2, entries.length);
+
+ JackrabbitAccessControlEntry first = (JackrabbitAccessControlEntry) entries[0];
+ assertEquals(principal2, first.getPrincipal());
+
+ JackrabbitAccessControlEntry second = (JackrabbitAccessControlEntry) entries[1];
+ assertEquals(testPrincipal, second.getPrincipal());
+ assertFalse(second.isAllow());
+ assertSamePrivileges(new Privilege[] {readPriv[0], writePriv[0]}, second.getPrivileges());
+ }
+
+ public void testTwoEntriesPerPrincipal() throws RepositoryException, NotExecutableException {
+ JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
+
+ Privilege[] readPriv = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] writePriv = privilegesFromName(Privilege.JCR_WRITE);
+ Privilege[] acReadPriv = privilegesFromName(Privilege.JCR_READ_ACCESS_CONTROL);
+
+ pt.addEntry(testPrincipal, readPriv, true, restrictions);
+ pt.addEntry(testPrincipal, writePriv, true, restrictions);
+ pt.addEntry(testPrincipal, acReadPriv, true, restrictions);
+
+ pt.addEntry(testPrincipal, readPriv, false, restrictions);
+ pt.addEntry(new PrincipalImpl(testPrincipal.getName()), readPriv, false, restrictions);
+ pt.addEntry(new Principal() {
+ public String getName() {
+ return testPrincipal.getName();
+ }
+ }, readPriv, false, restrictions);
+
+ AccessControlEntry[] entries = pt.getAccessControlEntries();
+ assertEquals(2, entries.length);
+ }
+
+ /**
+ * Test if new entries get appended at the end of the list.
+ *
+ * @throws RepositoryException
+ * @throws NotExecutableException
+ */
+ public void testNewEntriesAppendedAtEnd() throws RepositoryException, NotExecutableException {
+ JackrabbitAccessControlList pt = createEmptyTemplate(getTestPath());
+
+ Privilege[] readPriv = privilegesFromName(Privilege.JCR_READ);
+ Privilege[] writePriv = privilegesFromName(Privilege.JCR_WRITE);
+
+ pt.addEntry(testPrincipal, readPriv, true, restrictions);
+ pt.addEntry(pMgr.getEveryone(), readPriv, true, restrictions);
+ pt.addEntry(testPrincipal, writePriv, false, restrictions);
+
+ AccessControlEntry[] entries = pt.getAccessControlEntries();
+
+ assertEquals(3, entries.length);
+
+ JackrabbitAccessControlEntry last = (JackrabbitAccessControlEntry) entries[2];
+ assertEquals(testPrincipal, last.getPrincipal());
+ assertEquals(false, last.isAllow());
+ assertEquals(writePriv[0], last.getPrivileges()[0]);
+ }
}
\ No newline at end of file
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplateTest.java?rev=881752&r1=881751&r2=881752&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplateTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplateTest.java Wed Nov 18 12:38:25 2009
@@ -25,6 +25,7 @@
import javax.jcr.RepositoryException;
import java.util.Arrays;
import java.util.List;
+import java.security.Principal;
/**
* <code>ACLTemplateTest</code>...
@@ -42,6 +43,10 @@
return new ACLTemplate(testPrincipal, testPath, (SessionImpl) superuser, superuser.getValueFactory());
}
+ protected Principal getSecondPrincipal() throws Exception {
+ return testPrincipal;
+ }
+
public void testGetRestrictionNames() throws RepositoryException {
List names = Arrays.asList(createEmptyTemplate(getTestPath()).getRestrictionNames());