You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2013/09/24 18:58:43 UTC

svn commit: r1525944 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ oak-core/src/main/java/or...

Author: angela
Date: Tue Sep 24 16:58:42 2013
New Revision: 1525944

URL: http://svn.apache.org/r1525944
Log:
OAK-1026 : AccessControlEntry.getPrivileges() behaves diffent than in Oak

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlListTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ImmutableACLTest.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/JackrabbitAccessControlListTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java Tue Sep 24 16:58:42 2013
@@ -39,10 +39,10 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlList;
-import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
-import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,6 +70,8 @@ abstract class ACL extends AbstractAcces
 
     abstract PrivilegeBitsProvider getPrivilegeBitsProvider();
 
+    abstract ACE createACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws RepositoryException;
+
     //------------------------------------------< AbstractAccessControlList >---
     @Nonnull
     @Override
@@ -96,7 +98,10 @@ abstract class ACL extends AbstractAcces
             throw new AccessControlException("Privileges may not be null nor an empty array");
         }
         for (Privilege p : privileges) {
-            getPrivilegeManager().getPrivilege(p.getName());
+            Privilege pv = getPrivilegeManager().getPrivilege(p.getName());
+            if (pv.isAbstract()) {
+                throw new AccessControlException("Privilege " + p + " is abstract.");
+            }
         }
 
         Util.checkValidPrincipal(principal, getPrincipalManager());
@@ -119,7 +124,7 @@ abstract class ACL extends AbstractAcces
             }
         }
 
-        ACE entry = new ACE(principal, privileges, isAllow, rs, getNamePathMapper());
+        ACE entry = createACE(principal, getPrivilegeBits(privileges), isAllow, rs, getNamePathMapper());
         if (entries.contains(entry)) {
             log.debug("Entry is already contained in policy -> no modification.");
             return false;
@@ -189,8 +194,8 @@ abstract class ACL extends AbstractAcces
         }));
 
         for (ACE existing : subList) {
-            PrivilegeBits existingBits = getPrivilegeBits(existing);
-            PrivilegeBits entryBits = getPrivilegeBits(entry);
+            PrivilegeBits existingBits = PrivilegeBits.getInstance(existing.getPrivilegeBits());
+            PrivilegeBits entryBits = entry.getPrivilegeBits();
             if (entry.getRestrictions().equals(existing.getRestrictions())) {
                 if (entry.isAllow() == existing.isAllow()) {
                     if (existingBits.includes(entryBits)) {
@@ -225,23 +230,11 @@ abstract class ACL extends AbstractAcces
         return true;
     }
 
-    private ACE createACE(ACE existing, PrivilegeBits newPrivilegeBits) throws RepositoryException {
-        return new ACE(existing.getPrincipal(), getPrivileges(newPrivilegeBits), existing.isAllow(), existing.getRestrictions(), getNamePathMapper());
+    private ACE createACE(@Nonnull ACE existing, @Nonnull PrivilegeBits newPrivilegeBits) throws RepositoryException {
+        return createACE(existing.getPrincipal(), newPrivilegeBits, existing.isAllow(), existing.getRestrictions(), getNamePathMapper());
     }
 
-    private Set<Privilege> getPrivileges(PrivilegeBits bits) throws RepositoryException {
-        Set<Privilege> privileges = new HashSet<Privilege>();
-        for (String name : getPrivilegeBitsProvider().getPrivilegeNames(bits)) {
-            privileges.add(getPrivilegeManager().getPrivilege(name));
-        }
-        return privileges;
-    }
-
-    private PrivilegeBits getPrivilegeBits(ACE entry) {
-        PrivilegeBits bits = PrivilegeBits.getInstance();
-        for (Privilege privilege : entry.getPrivileges()) {
-            bits.add(getPrivilegeBitsProvider().getBits(privilege.getName()));
-        }
-        return bits;
+    private PrivilegeBits getPrivilegeBits(Privilege[] privileges) {
+        return getPrivilegeBitsProvider().getBits(privileges, getNamePathMapper());
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java Tue Sep 24 16:58:42 2013
@@ -78,6 +78,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration;
 import org.apache.jackrabbit.oak.spi.state.PropertyBuilder;
@@ -105,6 +106,7 @@ public class AccessControlManagerImpl im
     private final AuthorizationConfiguration acConfig;
 
     private final PrivilegeManager privilegeManager;
+    private final PrivilegeBitsProvider bitsProvider;
     private final PrincipalManager principalManager;
     private final RestrictionProvider restrictionProvider;
     private final ReadOnlyNodeTypeManager ntMgr;
@@ -119,6 +121,7 @@ public class AccessControlManagerImpl im
         this.namePathMapper = namePathMapper;
 
         privilegeManager = getConfig(securityProvider, PrivilegeConfiguration.class).getPrivilegeManager(root, namePathMapper);
+        bitsProvider = new PrivilegeBitsProvider(root);
         principalManager = getConfig(securityProvider, PrincipalConfiguration.class).getPrincipalManager(root, namePathMapper);
 
         acConfig = getConfig(securityProvider, AuthorizationConfiguration.class);
@@ -571,7 +574,8 @@ public class AccessControlManagerImpl im
                           @Nonnull RestrictionProvider restrictionProvider) throws RepositoryException {
         boolean isAllow = NT_REP_GRANT_ACE.equals(TreeUtil.getPrimaryTypeName(aceTree));
         Set<Restriction> restrictions = restrictionProvider.readRestrictions(oakPath, aceTree);
-        return new ACE(getPrincipal(aceTree), getPrivileges(aceTree), isAllow, restrictions, namePathMapper);
+        Iterable<String> privNames = checkNotNull(TreeUtil.getStrings(aceTree, REP_PRIVILEGES));
+        return new Entry(getPrincipal(aceTree), bitsProvider.getBits(privNames), isAllow, restrictions, namePathMapper);
     }
 
     @Nonnull
@@ -728,7 +732,12 @@ public class AccessControlManagerImpl im
 
         @Override
         PrivilegeBitsProvider getPrivilegeBitsProvider() {
-            return new PrivilegeBitsProvider(root);
+            return bitsProvider;
+        }
+
+        @Override
+        ACE createACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws RepositoryException {
+            return new Entry(principal, privilegeBits, isAllow, restrictions, namePathMapper);
         }
 
         @Override
@@ -785,7 +794,12 @@ public class AccessControlManagerImpl im
 
         @Override
         PrivilegeBitsProvider getPrivilegeBitsProvider() {
-            return new PrivilegeBitsProvider(root);
+            return bitsProvider;
+        }
+
+        @Override
+        ACE createACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws RepositoryException {
+            return new Entry(principal, privilegeBits, isAllow, restrictions, namePathMapper);
         }
 
         @Override
@@ -812,6 +826,26 @@ public class AccessControlManagerImpl im
         }
     }
 
+    private final class Entry extends ACE {
+
+        private Entry(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws AccessControlException {
+            super(principal, privilegeBits, isAllow, restrictions, namePathMapper);
+        }
+
+        @Override
+        public Privilege[] getPrivileges() {
+            Set<Privilege> privileges = new HashSet<Privilege>();
+            for (String name : bitsProvider.getPrivilegeNames(getPrivilegeBits())) {
+                try {
+                    privileges.add(privilegeManager.getPrivilege(name));
+                } catch (RepositoryException e) {
+                    log.warn("Unable to get privilege with name : " + name, e);
+                }
+            }
+            return privileges.toArray(new Privilege[privileges.size()]);
+        }
+    }
+
     private static final class ReadPolicy implements NamedAccessControlPolicy {
 
         private static final NamedAccessControlPolicy INSTANCE = new ReadPolicy();

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java?rev=1525944&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java Tue Sep 24 16:58:42 2013
@@ -0,0 +1,178 @@
+/*
+ * 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.oak.spi.security.authorization.accesscontrol;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.security.AccessControlException;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+
+/**
+ * Default implementation of the {@code JackrabbitAccessControlEntry} interface.
+ * It asserts that the basic contract is fulfilled but does perform any additional
+ * validation on the principal, the privileges or the specified restrictions.
+ */
+public abstract class ACE implements JackrabbitAccessControlEntry {
+
+    private final Principal principal;
+    private final PrivilegeBits privilegeBits;
+    private final boolean isAllow;
+    private final Set<Restriction> restrictions;
+    private final NamePathMapper namePathMapper;
+
+    private int hashCode;
+
+    public ACE(Principal principal, PrivilegeBits privilegeBits,
+               boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws AccessControlException {
+        if (principal == null || privilegeBits == null || privilegeBits.isEmpty()) {
+            throw new AccessControlException();
+        }
+
+        this.principal = principal;
+        this.privilegeBits = privilegeBits;
+        this.isAllow = isAllow;
+        this.restrictions = (restrictions == null) ? Collections.<Restriction>emptySet() : ImmutableSet.copyOf(restrictions);
+        this.namePathMapper = namePathMapper;
+    }
+
+
+
+    //--------------------------------------------------------------------------
+    @Nonnull
+    public PrivilegeBits getPrivilegeBits() {
+        return privilegeBits;
+    }
+
+    @Nonnull
+    public Set<Restriction> getRestrictions() {
+        return restrictions;
+    }
+
+    //-------------------------------------------------< AccessControlEntry >---
+    @Nonnull
+    @Override
+    public Principal getPrincipal() {
+        return principal;
+    }
+
+    //---------------------------------------< JackrabbitAccessControlEntry >---
+    @Override
+    public boolean isAllow() {
+        return isAllow;
+    }
+
+    @Nonnull
+    @Override
+    public String[] getRestrictionNames() throws RepositoryException {
+        return Collections2.transform(restrictions, new Function<Restriction, String>() {
+            @Override
+            public String apply(Restriction restriction) {
+                return getJcrName(restriction);
+            }
+        }).toArray(new String[restrictions.size()]);
+    }
+
+    @CheckForNull
+    @Override
+    public Value getRestriction(String restrictionName) throws RepositoryException {
+        for (Restriction restriction : restrictions) {
+            String jcrName = getJcrName(restriction);
+            if (jcrName.equals(restrictionName)) {
+                if (restriction.getDefinition().getRequiredType().isArray()) {
+                    List<Value> values = ValueFactoryImpl.createValues(restriction.getProperty(), namePathMapper);
+                    switch (values.size()) {
+                        case 1: return values.get(0);
+                        default : throw new ValueFormatException("Attempt to retrieve single value from multivalued property");
+                    }
+                } else {
+                    return ValueFactoryImpl.createValue(restriction.getProperty(), namePathMapper);
+                }
+            }
+        }
+        return null;
+    }
+
+    @CheckForNull
+    @Override
+    public Value[] getRestrictions(String restrictionName) throws RepositoryException {
+        for (Restriction restriction : restrictions) {
+            String jcrName = getJcrName(restriction);
+            if (jcrName.equals(restrictionName)) {
+                List<Value> values = ValueFactoryImpl.createValues(restriction.getProperty(), namePathMapper);
+                return values.toArray(new Value[values.size()]);
+            }
+        }
+        return null;
+    }
+
+    //-------------------------------------------------------------< Object >---
+
+    /**
+     * @see Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        if (hashCode == 0) {
+            hashCode = Objects.hashCode(principal.getName(), privilegeBits, isAllow, restrictions);
+        }
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof ACE) {
+            ACE other = (ACE) obj;
+            return principal.getName().equals(other.principal.getName())
+                    && isAllow == other.isAllow
+                    && privilegeBits.equals(other.privilegeBits)
+                    && restrictions.equals(other.restrictions);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(principal.getName()).append('-').append(isAllow).append('-');
+        sb.append(privilegeBits.toString()).append('-').append(restrictions.toString());
+        return sb.toString();
+    }
+
+    //------------------------------------------------------------< private >---
+    private String getJcrName(Restriction restriction) {
+        return namePathMapper.getJcrName(restriction.getDefinition().getName());
+    }
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java Tue Sep 24 16:58:42 2013
@@ -16,18 +16,25 @@
  */
 package org.apache.jackrabbit.oak.spi.security.privilege;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
 
+import com.google.common.base.Function;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
-
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.apache.jackrabbit.oak.namepath.NameMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Reads and writes privilege definitions from and to the repository content
@@ -35,6 +42,8 @@ import static com.google.common.base.Pre
  */
 public final class PrivilegeBitsProvider implements PrivilegeConstants {
 
+    private static final Logger log = LoggerFactory.getLogger(PrivilegeBitsProvider.class);
+
     private final Map<PrivilegeBits, Set<String>> bitsToNames = new HashMap<PrivilegeBits, Set<String>>();
 
     private final Root root;
@@ -62,20 +71,9 @@ public final class PrivilegeBitsProvider
     public PrivilegeBits getBits(@Nonnull String... privilegeNames) {
         if (privilegeNames.length == 0) {
             return PrivilegeBits.EMPTY;
+        } else {
+            return getBits(Arrays.asList(privilegeNames));
         }
-
-        Tree privilegesTree = getPrivilegesTree();
-        if (!privilegesTree.exists()) {
-            return PrivilegeBits.EMPTY;
-        }
-        PrivilegeBits bits = PrivilegeBits.getInstance();
-        for (String privilegeName : privilegeNames) {
-            Tree defTree = privilegesTree.getChild(checkNotNull(privilegeName));
-            if (defTree.exists()) {
-                bits.add(PrivilegeBits.getInstance(defTree));
-            }
-        }
-        return bits.unmodifiable();
     }
 
     /**
@@ -94,15 +92,44 @@ public final class PrivilegeBitsProvider
         }
         PrivilegeBits bits = PrivilegeBits.getInstance();
         for (String privilegeName : privilegeNames) {
-            Tree defTree = privilegesTree.getChild(checkNotNull(privilegeName));
-            if (defTree.exists()) {
-                bits.add(PrivilegeBits.getInstance(defTree));
+            if (privilegeName != null) {
+                Tree defTree = privilegesTree.getChild(privilegeName);
+                if (defTree.exists()) {
+                    bits.add(PrivilegeBits.getInstance(defTree));
+                }
+            } else {
+                log.debug("Ignoring 'null' privilege name");
             }
         }
         return bits.unmodifiable();
     }
 
     /**
+     *
+     * @param privileges
+     * @param nameMapper
+     * @return
+     */
+    @Nonnull
+    public PrivilegeBits getBits(@Nonnull Privilege[] privileges, final @Nonnull NameMapper nameMapper) {
+        return getBits(Iterables.transform(Arrays.asList(privileges), new Function<Privilege, String>() {
+
+            @Override
+            public String apply(@Nullable Privilege privilege) {
+                if (privilege != null) {
+                    try {
+                        return nameMapper.getOakName(privilege.getName());
+                    } catch (RepositoryException e) {
+                        log.debug("Unable to resolve OAK name of privilege " + privilege, e);
+                    }
+                }
+                // null privilege or failed to resolve the privilege name
+                return null;
+            }
+        }));
+    }
+
+    /**
      * Resolve the given privilege bits to a set of privilege names.
      *
      * @param privilegeBits An instance of privilege bits.

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java Tue Sep 24 16:58:42 2013
@@ -28,6 +28,7 @@ import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.security.AccessControlEntry;
 import javax.jcr.security.AccessControlException;
@@ -53,6 +54,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.junit.Before;
@@ -114,7 +116,12 @@ public class ACLTest extends AbstractAcc
 
             @Override
             PrivilegeBitsProvider getPrivilegeBitsProvider() {
-                return new PrivilegeBitsProvider(root);
+                return getBitsProvider();
+            }
+
+            @Override
+            ACE createACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws RepositoryException {
+                return createEntry(principal, privilegeBits, isAllow, restrictions);
             }
         };
     }
@@ -244,7 +251,7 @@ public class ACLTest extends AbstractAcc
     @Test
     public void testRemoveNonExisting() throws Exception {
         try {
-            acl.removeAccessControlEntry(new ACE(testPrincipal, testPrivileges, true, null, namePathMapper));
+            acl.removeAccessControlEntry(createEntry(testPrincipal, testPrivileges, true));
             fail("Removing a non-existing ACE should fail.");
         } catch (AccessControlException e) {
             // success
@@ -309,7 +316,7 @@ public class ACLTest extends AbstractAcc
         acl.addAccessControlEntry(testPrincipal, read);
         acl.addAccessControlEntry(EveryonePrincipal.getInstance(), write);
 
-        AccessControlEntry invalid = new ACE(testPrincipal, write, false, Collections.<Restriction>emptySet(), namePathMapper);
+        AccessControlEntry invalid = createEntry(testPrincipal, false, null, JCR_WRITE);
         try {
             acl.orderBefore(invalid, acl.getEntries().get(0));
             fail("src entry not contained in list -> reorder should fail.");

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java Tue Sep 24 16:58:42 2013
@@ -62,12 +62,15 @@ import org.apache.jackrabbit.oak.namepat
 import org.apache.jackrabbit.oak.plugins.name.Namespaces;
 import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
 import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlTest;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
 import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.TestACL;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.apache.jackrabbit.oak.util.NodeUtil;
@@ -191,6 +194,11 @@ public class AccessControlManagerImplTes
                 return new PrivilegeBitsProvider(root);
             }
 
+            @Override
+            ACE createACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions, NamePathMapper namePathMapper) throws RepositoryException {
+                throw new UnsupportedOperationException();
+            }
+
             @Nonnull
             @Override
             public RestrictionProvider getRestrictionProvider() {

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java Tue Sep 24 16:58:42 2013
@@ -40,6 +40,7 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
 import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.junit.Before;
 import org.junit.Test;
@@ -87,24 +88,16 @@ public class ACETest extends AbstractAcc
 
     private ACE createEntry(String... privilegeNames)
             throws RepositoryException {
-        Privilege[] privs = AccessControlUtils.privilegesFromNames(acMgr, privilegeNames);
-        return createEntry(testPrincipal, privs, true);
+        return createEntry(testPrincipal, true, null, privilegeNames);
     }
 
     private ACE createEntry(String[] privilegeNames, boolean isAllow)
             throws RepositoryException {
-        Privilege[] privs = AccessControlUtils.privilegesFromNames(acMgr, privilegeNames);
-        return createEntry(testPrincipal, privs, isAllow);
-    }
-
-    private ACE createEntry(Principal principal, Privilege[] privileges, boolean isAllow) throws AccessControlException {
-        return new ACE(principal, privileges, isAllow, null, namePathMapper);
+        return createEntry(testPrincipal, isAllow, null, privilegeNames);
     }
 
     private ACE createEntry(Set<Restriction> restrictions) throws Exception {
-        return new ACE(testPrincipal,
-                privilegesFromNames(PrivilegeConstants.JCR_READ), true,
-                restrictions, namePathMapper);
+        return createEntry(testPrincipal, true, restrictions, PrivilegeConstants.JCR_READ);
     }
 
     private Restriction createRestriction(String name, Value value) throws Exception {
@@ -169,14 +162,38 @@ public class ACETest extends AbstractAcc
         Privilege[] expected = AccessControlUtils.privilegesFromNames(acMgr,
                 PrivilegeConstants.JCR_ADD_CHILD_NODES,
                 PrivilegeConstants.JCR_REMOVE_CHILD_NODES);
-        assertEquals(Arrays.asList(expected), Arrays.asList(privs));
+        assertEquals(ImmutableSet.copyOf(expected), ImmutableSet.copyOf(privs));
+    }
+
+    @Test
+    public void testGetPrivilegeBits() throws RepositoryException {
+        ACE entry = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
+
+        PrivilegeBits bits = entry.getPrivilegeBits();
+        assertNotNull(bits);
+        assertEquals(bits, getBitsProvider().getBits(PrivilegeConstants.JCR_READ));
+
+        entry = createEntry(new String[]{PrivilegeConstants.REP_WRITE}, true);
+        bits = entry.getPrivilegeBits();
+        assertNotNull(bits);
+        assertEquals(bits, getBitsProvider().getBits(PrivilegeConstants.REP_WRITE));
+
+        entry = createEntry(new String[]{PrivilegeConstants.JCR_ADD_CHILD_NODES,
+                PrivilegeConstants.JCR_REMOVE_CHILD_NODES}, true);
+        bits = entry.getPrivilegeBits();
+        assertNotNull(bits);
+
+        PrivilegeBits expected = getBitsProvider().getBits(
+                PrivilegeConstants.JCR_ADD_CHILD_NODES,
+                PrivilegeConstants.JCR_REMOVE_CHILD_NODES);
+        assertEquals(expected, bits);
     }
 
     @Test
     public void testNullPrivileges() throws Exception {
         try {
-            createEntry(testPrincipal, null, true);
-            fail("Principal must not be null");
+            ACE empty = new EmptyACE(null);
+            fail("Privileges must not be null");
         } catch (AccessControlException e) {
             // success
         }
@@ -185,8 +202,8 @@ public class ACETest extends AbstractAcc
     @Test
     public void testEmptyPrivileges() throws Exception {
         try {
-            createEntry(testPrincipal, new Privilege[0], true);
-            fail("Privilege array must not be null.");
+            ACE empty = new EmptyACE(PrivilegeBits.EMPTY);
+            fail("Privileges must not be empty.");
         } catch (AccessControlException e) {
             // success
         }
@@ -195,9 +212,7 @@ public class ACETest extends AbstractAcc
     @Test
     public void testRedundantPrivileges() throws Exception {
         ACE ace = createEntry(PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_READ);
-        Privilege[] privs = ace.getPrivileges();
-        assertEquals(1, privs.length);
-        assertEquals(PrivilegeConstants.JCR_READ, privs[0].getName());
+        assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), ace.getPrivilegeBits());
     }
 
     /**
@@ -227,7 +242,16 @@ public class ACETest extends AbstractAcc
             }
         };
         Privilege[] privs = new Privilege[]{invalidPriv, acMgr.privilegeFromName(PrivilegeConstants.JCR_READ)};
-        createEntry(testPrincipal, privs, true);
+        ACE entry = createEntry(testPrincipal, privs, true);
+        assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), entry.getPrivilegeBits());
+    }
+
+    @Test
+    public void testAggregatePrivileges() throws Exception {
+        ACE ace = createEntry(PrivilegeConstants.REP_READ_NODES, PrivilegeConstants.REP_READ_PROPERTIES);
+
+        assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), ace.getPrivilegeBits());
+        assertArrayEquals(privilegesFromNames(PrivilegeConstants.JCR_READ), ace.getPrivileges());
     }
 
     @Test
@@ -564,4 +588,16 @@ public class ACETest extends AbstractAcc
         }
 
     }
+
+    private class EmptyACE extends ACE {
+
+        public EmptyACE(PrivilegeBits privilegeBits) throws AccessControlException {
+            super(testPrincipal, privilegeBits, true, null, namePathMapper);
+        }
+
+        @Override
+        public Privilege[] getPrivileges() {
+            return new Privilege[0];
+        }
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlListTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlListTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlListTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlListTest.java Tue Sep 24 16:58:42 2013
@@ -87,10 +87,8 @@ public abstract class AbstractAccessCont
     protected List<ACE> createTestEntries() throws RepositoryException {
         List<ACE> entries = new ArrayList<ACE>(3);
         for (int i = 0; i < 3; i++) {
-            entries.add(new ACE(
-                    new PrincipalImpl("testPrincipal" + i),
-                    new Privilege[]{getPrivilegeManager(root).getPrivilege(PrivilegeConstants.JCR_READ)},
-                    true, null, namePathMapper));
+            entries.add(createEntry(
+                    new PrincipalImpl("testPrincipal" + i), true, null, PrivilegeConstants.JCR_READ));
         }
         return entries;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java Tue Sep 24 16:58:42 2013
@@ -17,18 +17,27 @@
 package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
 
 import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
 import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
 
 import org.apache.jackrabbit.oak.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.plugins.name.ReadWriteNamespaceRegistry;
 import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
 
 public abstract class AbstractAccessControlTest extends AbstractSecurityTest {
 
     private RestrictionProvider restrictionProvider;
+    private PrivilegeBitsProvider bitsProvider;
 
     protected void registerNamespace(String prefix, String uri) throws Exception {
         NamespaceRegistry nsRegistry = new ReadWriteNamespaceRegistry() {
@@ -52,7 +61,49 @@ public abstract class AbstractAccessCont
         return restrictionProvider;
     }
 
+    protected PrivilegeBitsProvider getBitsProvider() {
+        if (bitsProvider == null) {
+            bitsProvider = new PrivilegeBitsProvider(root);
+        }
+        return bitsProvider;
+    }
+
     protected Principal getTestPrincipal() throws Exception {
         return getTestUser().getPrincipal();
     }
+
+    protected ACE createEntry(Principal principal, boolean isAllow, Set<Restriction> restrictions, String... privilegeNames) throws RepositoryException {
+        return new TestACE(principal, getBitsProvider().getBits(privilegeNames), isAllow, restrictions);
+    }
+
+    protected ACE createEntry(Principal principal, Privilege[] privileges, boolean isAllow)
+            throws RepositoryException {
+        PrivilegeBits bits = getBitsProvider().getBits(privileges, getNamePathMapper());
+        return new TestACE(principal, bits, isAllow, null);
+    }
+
+    protected ACE createEntry(Principal principal, PrivilegeBits bits, boolean isAllow, Set<Restriction> restrictions) throws AccessControlException {
+        return new TestACE(principal, bits, isAllow, restrictions);
+    }
+
+    private final class TestACE extends ACE {
+
+    private TestACE(Principal principal, PrivilegeBits privilegeBits, boolean isAllow, Set<Restriction> restrictions) throws AccessControlException {
+        super(principal, privilegeBits, isAllow, restrictions, getNamePathMapper());
+    }
+
+    @Override
+    public Privilege[] getPrivileges() {
+        Set<Privilege> privileges = new HashSet<Privilege>();
+            for (String name : bitsProvider.getPrivilegeNames(getPrivilegeBits())) {
+                try {
+                    privileges.add(getPrivilegeManager(root).getPrivilege(name));
+                } catch (RepositoryException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+            return privileges.toArray(new Privilege[privileges.size()]);
+    }
+}
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ImmutableACLTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ImmutableACLTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ImmutableACLTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ImmutableACLTest.java Tue Sep 24 16:58:42 2013
@@ -29,7 +29,6 @@ import org.apache.jackrabbit.api.securit
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
-import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.junit.Before;
 import org.junit.Test;
@@ -117,8 +116,8 @@ public class ImmutableACLTest extends Ab
     @Test
     public void testImmutable() throws Exception {
         List<ACE> entries = new ArrayList<ACE>();
-        entries.add(new ACE(testPrincipal, testPrivileges, true, null, namePathMapper));
-        entries.add(new ACE(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT), false, null, namePathMapper));
+        entries.add(createEntry(testPrincipal, testPrivileges, true));
+        entries.add(createEntry(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT), false));
 
         JackrabbitAccessControlList acl = createACL(entries);
         assertFalse(acl.isEmpty());
@@ -143,16 +142,17 @@ public class ImmutableACLTest extends Ab
         JackrabbitAccessControlList acl = createEmptyACL();
 
         assertEquals(acl, createEmptyACL());
-        assertFalse(acl.equals(createACL(new ACE(testPrincipal, testPrivileges, true, Collections.<Restriction>emptySet(), namePathMapper))));
+        ACE entry = createEntry(testPrincipal, testPrivileges, true);
+        assertFalse(acl.equals(createACL(entry)));
         assertFalse(acl.equals(new TestACL(getTestPath(), getRestrictionProvider(), Collections.<JackrabbitAccessControlEntry>emptyList())));
     }
 
     @Test
     public void testEquals() throws Exception {
         RestrictionProvider rp = getRestrictionProvider();
-        ACE ace1 = new ACE(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), false, null, namePathMapper);
-        ACE ace2 = new ACE(testPrincipal, testPrivileges, true, null, namePathMapper);
-        ACE ace2b = new ACE(testPrincipal, getAggregatedPrivileges(testPrivileges), true, null, namePathMapper);
+        ACE ace1 = createEntry(testPrincipal, false, null, PrivilegeConstants.JCR_VERSION_MANAGEMENT);
+        ACE ace2 = createEntry(testPrincipal, testPrivileges, true);
+        ACE ace2b = createEntry(testPrincipal, getAggregatedPrivileges(testPrivileges), true);
 
         JackrabbitAccessControlList acl = createACL(ace1, ace2);
         JackrabbitAccessControlList repoAcl = createACL((String) null, ace1, ace2);
@@ -175,9 +175,9 @@ public class ImmutableACLTest extends Ab
     @Test
     public void testHashCode() throws Exception {
         RestrictionProvider rp = getRestrictionProvider();
-        ACE ace1 = new ACE(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), false, null, namePathMapper);
-        ACE ace2 = new ACE(testPrincipal, testPrivileges, true, null, namePathMapper);
-        ACE ace2b = new ACE(testPrincipal, getAggregatedPrivileges(testPrivileges), true, null, namePathMapper);
+        ACE ace1 = createEntry(testPrincipal, privilegesFromNames(PrivilegeConstants.JCR_VERSION_MANAGEMENT), false);
+        ACE ace2 = createEntry(testPrincipal, testPrivileges, true);
+        ACE ace2b = createEntry(testPrincipal, getAggregatedPrivileges(testPrivileges), true);
 
         JackrabbitAccessControlList acl = createACL(ace1, ace2);
         JackrabbitAccessControlList repoAcl = createACL((String) null, ace1, ace2);

Modified: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/JackrabbitAccessControlListTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/JackrabbitAccessControlListTest.java?rev=1525944&r1=1525943&r2=1525944&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/JackrabbitAccessControlListTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/JackrabbitAccessControlListTest.java Tue Sep 24 16:58:42 2013
@@ -33,10 +33,13 @@ import org.apache.jackrabbit.api.Jackrab
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
 import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
 import org.apache.jackrabbit.test.NotExecutableException;
 import org.apache.jackrabbit.test.api.security.AbstractAccessControlTest;
 import org.junit.Test;
 
+import static org.junit.Assert.assertArrayEquals;
+
 /**
  * Testing {@code JackrabbitAccessControlList} functionality exposed by the API.
  */
@@ -167,4 +170,26 @@ public class JackrabbitAccessControlList
         assertEquals(0, acl.size());
         assertEquals(0, acl.getAccessControlEntries().length);
     }
+
+    /**
+     * <a href="https://issues.apache.org/jira/browse/OAK-1026">OAK-1026</a>
+     */
+    @Test
+    public void testEntryWithAggregatePrivileges() throws Exception {
+        Privilege write = acMgr.privilegeFromName(Privilege.JCR_WRITE);
+        acl.addEntry(testPrincipal, write.getAggregatePrivileges(), true);
+
+        AccessControlEntry[] entries = acl.getAccessControlEntries();
+        assertEquals(1, entries.length);
+        assertArrayEquals(new Privilege[]{write}, entries[0].getPrivileges());
+
+        acMgr.setPolicy(acl.getPath(), acl);
+
+        AccessControlPolicy policy = AccessControlUtils.getAccessControlList(acMgr, acl.getPath());
+        assertNotNull(policy);
+
+        entries = acl.getAccessControlEntries();
+        assertEquals(1, entries.length);
+        assertArrayEquals(new Privilege[]{write}, entries[0].getPrivileges());
+    }
 }
\ No newline at end of file