jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1181645 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/security/authorization/ main/java/org/apache/jackrabbit/core/security/authorization/acl/ main/java/org/apache/jackrabbit/core/security/authorization/p...
Date Tue, 11 Oct 2011 07:46:36 GMT
Author: angela
Date: Tue Oct 11 07:46:36 2011
New Revision: 1181645

URL: http://svn.apache.org/viewvc?rev=1181645&view=rev
Log:
JCR-2887 - Split PrivilegeRegistry in a per-session manager instance and a repository level
registry  (WIP)

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBits.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.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/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEntryTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBitsTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
Tue Oct 11 07:46:36 2011
@@ -119,7 +119,7 @@ public abstract class AbstractCompiledPe
     }
 
     /**
-     * @see CompiledPermissions#hasPrivileges(org.apache.jackrabbit.spi.Path,javax.jcr.security.Privilege...)
+     * @see CompiledPermissions#hasPrivileges(org.apache.jackrabbit.spi.Path, javax.jcr.security.Privilege[])
      */
     public boolean hasPrivileges(Path absPath, Privilege... privileges) throws RepositoryException
{
         Result result = getResult(absPath);
@@ -167,8 +167,9 @@ public abstract class AbstractCompiledPe
         public Result(int allows, int denies, PrivilegeBits allowPrivileges, PrivilegeBits
denyPrivileges) {
             this.allows = allows;
             this.denies = denies;
-            this.allowPrivileges = allowPrivileges;
-            this.denyPrivileges = denyPrivileges;
+            // make sure privilegebits are unmodifiable -> proper hashcode generation
+            this.allowPrivileges = allowPrivileges.unmodifiable();
+            this.denyPrivileges = denyPrivileges.unmodifiable();
         }
 
         public boolean grants(int permissions) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java
Tue Oct 11 07:46:36 2011
@@ -31,6 +31,7 @@ import java.security.Principal;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Simple, immutable implementation of the
@@ -40,9 +41,9 @@ import java.util.Map;
 public abstract class AccessControlEntryImpl implements JackrabbitAccessControlEntry {
 
     /**
-     * All privileges contained in this entry
+     * All privileges contained in this entry.
      */
-    private final Privilege[] privileges;
+    private Privilege[] privileges;
 
     /**
      * PrivilegeBits calculated from built-in privileges
@@ -76,42 +77,63 @@ public abstract class AccessControlEntry
      *
      * @param principal Principal for this access control entry.
      * @param privileges Privileges for this access control entry.
+     * @param isAllow <code>true</code> if this ACE grants the specified
+     * privileges to the specified principal; <code>false</code> otherwise.
+     * @param restrictions A map of restriction name (String) to restriction
+     * (Value). See {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList#getRestrictionNames()}
+     * and {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList#getRestrictionType(String)}.
      * @throws AccessControlException if either principal or privileges are invalid.
      * @throws RepositoryException if another error occurs.
      */
-    protected AccessControlEntryImpl(Principal principal, Privilege[] privileges)
+    protected AccessControlEntryImpl(Principal principal, Privilege[] privileges,
+                                     boolean isAllow, Map<String, Value> restrictions)
             throws AccessControlException, RepositoryException {
-        this(principal, privileges, true, null);
+        if (principal == null || privileges == null) {
+            throw new AccessControlException();
+        }
+        // make sure no abstract privileges are passed.
+        for (Privilege privilege : privileges) {
+            if (privilege.isAbstract()) {
+                throw new AccessControlException("Privilege " + privilege + " is abstract.");
+            }
+        }
+        this.principal = principal;
+        this.privileges = privileges;
+        this.privilegeBits = getPrivilegeManager().getBits(privileges).unmodifiable();
+        this.allow = isAllow;
+
+        if (restrictions == null) {
+            this.restrictions = Collections.emptyMap();
+        } else {
+            this.restrictions = new HashMap<Name, Value>(restrictions.size());
+            // validate the passed restrictions and fill the map
+            for (String name : restrictions.keySet()) {
+                Value value = ValueHelper.copy(restrictions.get(name), getValueFactory());
+                this.restrictions.put(getResolver().getQName(name), value);
+            }
+        }
     }
 
     /**
      * Construct an access control entry for the given principal and privileges.
      *
      * @param principal Principal for this access control entry.
-     * @param privileges Privileges for this access control entry.
+     * @param privilegesBits Privileges for this access control entry.
      * @param isAllow <code>true</code> if this ACE grants the specified
      * privileges to the specified principal; <code>false</code> otherwise.
      * @param restrictions A map of restriction name (String) to restriction
      * (Value). See {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList#getRestrictionNames()}
      * and {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList#getRestrictionType(String)}.
-     * @throws AccessControlException if either principal or privileges are invalid.
      * @throws RepositoryException if another error occurs.
      */
-    protected AccessControlEntryImpl(Principal principal, Privilege[] privileges,
+    protected AccessControlEntryImpl(Principal principal, PrivilegeBits privilegesBits,
                                      boolean isAllow, Map<String, Value> restrictions)
-            throws AccessControlException, RepositoryException {
-        if (principal == null) {
+            throws RepositoryException {
+        if (principal == null || privilegesBits == null) {
             throw new IllegalArgumentException();
         }
-        // make sure no abstract privileges are passed.
-        for (Privilege privilege : privileges) {
-            if (privilege.isAbstract()) {
-                throw new AccessControlException("Privilege " + privilege + " is abstract.");
-            }
-        }
         this.principal = principal;
-        this.privileges = privileges;
-        this.privilegeBits = getPrivilegeManager().getBits(privileges);
+        this.privilegeBits = privilegesBits.unmodifiable();
         this.allow = isAllow;
 
         if (restrictions == null) {
@@ -129,6 +151,26 @@ public abstract class AccessControlEntry
     /**
      *
      * @param base
+     * @param privilegeBits
+     * @param isAllow
+     * @throws AccessControlException
+     */
+    protected AccessControlEntryImpl(AccessControlEntryImpl base, PrivilegeBits privilegeBits,
boolean isAllow)
+            throws AccessControlException, RepositoryException {
+        this(base.principal, privilegeBits, isAllow, (base.restrictions.isEmpty()) ? null
: Collections.<String, Value>emptyMap());
+
+        if (!base.restrictions.isEmpty()) {
+            // validate the passed restrictions and fill the map
+            for (Name name : base.restrictions.keySet()) {
+                Value value = ValueHelper.copy(base.restrictions.get(name), getValueFactory());
+                this.restrictions.put(name, value);
+            }
+        }
+    }
+
+    /**
+     *
+     * @param base
      * @param privileges
      * @param isAllow
      * @throws AccessControlException
@@ -203,9 +245,7 @@ public abstract class AccessControlEntry
     protected int buildHashCode() {
         int h = 17;
         h = 37 * h + principal.getName().hashCode();
-        for (Privilege p : privileges) {
-            h = 37 * h + p.hashCode();
-        }
+        h = 37 * h + privilegeBits.hashCode();
         h = 37 * h + Boolean.valueOf(allow).hashCode();
         h = 37 * h + restrictions.hashCode();
         return h;
@@ -223,6 +263,10 @@ public abstract class AccessControlEntry
      * @see javax.jcr.security.AccessControlEntry#getPrivileges()
      */
     public Privilege[] getPrivileges() {
+        if (privileges == null) {
+            Set<Privilege> ps = getPrivilegeManager().getPrivileges(privilegeBits);
+            privileges = ps.toArray(new Privilege[ps.size()]);
+        }
         return privileges;
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBits.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBits.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBits.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBits.java
Tue Oct 11 07:46:36 2011
@@ -17,6 +17,8 @@
 package org.apache.jackrabbit.core.security.authorization;
 
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * <code>PrivilegeBits</code> 
@@ -27,6 +29,11 @@ public class PrivilegeBits {
 
     private static final long READ = 1; // PrivilegeRegistry.READ
 
+    private static final Map<Long, PrivilegeBits> BUILT_IN = new HashMap<Long, PrivilegeBits>();
+    static {
+        BUILT_IN.put(EMPTY.longValue(), EMPTY);
+    }
+
     private final Data d;
 
     /**
@@ -60,26 +67,17 @@ public class PrivilegeBits {
         if (this == EMPTY) {
             return EMPTY;
         } else {
-            return new PrivilegeBits(d.next());
-        }
-    }
-        
-    /**
-     * Returns an unmodifiable instance.
-     *
-     * @return an unmodifiable <code>PrivilegeBits</code> instance.
-     */
-    PrivilegeBits unmodifiable() {
-        if (d instanceof ModifiableData) {
-            return (d.isSimple()) ? getInstance(d.longValue()) : getInstance(d.longValues());
-        } else {
-            return this;
+            PrivilegeBits pb = new PrivilegeBits(d.next());
+            if (pb.d.isSimple()) {
+                BUILT_IN.put(pb.longValue(), pb);
+            }
+            return pb;
         }
     }
 
     /**
-     * Package private method used by <code>PrivilegeRegistry</code> to create
-     * an instance of privilege bits for the specified long value.
+     * Package private method used by <code>PrivilegeRegistry</code> to get or
+     * create an instance of privilege bits for the specified long value.
      *
      * @param bits
      * @return an instance of <code>PrivilegeBits</code>
@@ -90,7 +88,12 @@ public class PrivilegeBits {
         } else if (bits < PrivilegeRegistry.NO_PRIVILEGE) {
             throw new IllegalArgumentException();
         } else {
-            return new PrivilegeBits(new UnmodifiableData(bits));
+            PrivilegeBits pb = BUILT_IN.get(bits);
+            if (pb == null) {
+                pb = new PrivilegeBits(new UnmodifiableData(bits));
+                BUILT_IN.put(bits, pb);
+            }
+            return pb;
         }
     }
 
@@ -138,6 +141,28 @@ public class PrivilegeBits {
     }
 
     /**
+     * Returns an unmodifiable instance.
+     *
+     * @return an unmodifiable <code>PrivilegeBits</code> instance.
+     */
+    public PrivilegeBits unmodifiable() {
+        if (d instanceof ModifiableData) {
+            return (d.isSimple()) ? getInstance(d.longValue()) : getInstance(d.longValues());
+        } else {
+            return this;
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if this privilege bits instance can be altered.
+     *
+     * @return true if this privilege bits instance can be altered.
+     */
+    public boolean isModifiable() {
+        return (d instanceof ModifiableData);
+    }
+
+    /**
      * Returns <code>true</code> if this instance includes the jcr:read
      * privilege. Shortcut for calling {@link PrivilegeBits#includes(PrivilegeBits)}
      * where the other bits represented the jcr:read privilege.
@@ -148,10 +173,8 @@ public class PrivilegeBits {
     public boolean includesRead() {
         if (this == EMPTY) {
             return false;
-        } else if (d.isSimple()) {
-            return (d.longValue() & READ) == READ;
         } else {
-            return (d.longValues()[0] & READ) == READ;
+            return d.includesRead();
         }
     }
 
@@ -261,6 +284,19 @@ public class PrivilegeBits {
 
         abstract boolean includes(Data other);
 
+        abstract boolean includesRead();
+
+        boolean equalData(Data d) {
+            if (isSimple() != d.isSimple()) {
+                return false;
+            }
+            if (isSimple()) {
+                return longValue() == d.longValue();
+            } else {
+                return Arrays.equals(longValues(), d.longValues());
+            }
+        }
+
         static boolean includes(long bits, long otherBits) {
             return (bits | ~otherBits) == -1;
         }
@@ -279,26 +315,6 @@ public class PrivilegeBits {
                 return false;
             }
         }
-
-        //---------------------------------------------------------< Object >---
-        @Override
-        public boolean equals(Object o) {
-            if (o == this) {
-                return true;
-            } else if (o instanceof Data) {
-                Data d = (Data) o;
-                if (isSimple() != d.isSimple()) {
-                    return false;
-                }
-                if (isSimple()) {
-                    return longValue() == d.longValue();
-                } else {
-                    return Arrays.equals(longValues(), d.longValues());
-                }
-            } else {
-                return false;
-            }
-        }
     }
 
     /**
@@ -313,17 +329,20 @@ public class PrivilegeBits {
         private final long bits;
         private final long[] bitsArr;
         private final boolean isSimple;
+        private final boolean includesRead;
 
         private UnmodifiableData(long bits) {
             this.bits = bits;
             bitsArr = new long[] {bits};
             isSimple = true;
+            includesRead  = (bits & READ) == READ;
         }
 
         private UnmodifiableData(long[] bitsArr) {
             bits = PrivilegeRegistry.NO_PRIVILEGE;            
             this.bitsArr = bitsArr;
             isSimple = false;
+            includesRead = (bitsArr[0] & READ) == READ;
         }
 
         @Override
@@ -381,10 +400,36 @@ public class PrivilegeBits {
             }
         }
 
+        @Override
+        boolean includesRead() {
+            return includesRead;
+        }
+
         //---------------------------------------------------------< Object >---
         @Override
         public int hashCode() {
-            return (isSimple) ? new Long(bits).hashCode() : bitsArr.hashCode();
+            return (isSimple) ? new Long(bits).hashCode() : Arrays.hashCode(bitsArr);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            } else if (o instanceof UnmodifiableData) {
+                UnmodifiableData d = (UnmodifiableData) o;
+                if (isSimple != d.isSimple) {
+                    return false;
+                }
+                if (isSimple) {
+                    return bits == d.bits;
+                } else {
+                    return Arrays.equals(bitsArr, d.bitsArr);
+                }
+            } else if (o instanceof ModifiableData) {
+                return equalData((Data) o);
+            } else {
+                return false;
+            }
         }
     }
 
@@ -451,6 +496,11 @@ public class PrivilegeBits {
             }
         }
 
+        @Override
+        boolean includesRead() {
+            return (bits[0] & READ) == READ;
+        }
+
         /**
          * Add the other Data to this instance.
          *
@@ -543,5 +593,19 @@ public class PrivilegeBits {
             // NOTE: mutable object. hashCode not implemented.
             return 0;
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            } else if (o instanceof ModifiableData) {
+                ModifiableData d = (ModifiableData) o;
+                return Arrays.equals(bits, d.bits);
+            } else if (o instanceof UnmodifiableData) {
+                return equalData((Data) o);
+            } else {
+                return false;
+            }
+        }
     }
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImpl.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImpl.java
Tue Oct 11 07:46:36 2011
@@ -191,6 +191,20 @@ public final class PrivilegeManagerImpl 
     }
 
     /**
+     * @param privilegeNames An array of privilege names.
+     * @return The bits of the privileges contained in the specified
+     * array.
+     * @throws AccessControlException If the specified array is null or if it
+     * contains the name of an unregistered privilege.
+     */
+    public PrivilegeBits getBits(Name... privilegeNames) throws RepositoryException {
+        if (privilegeNames == null) {
+            throw new AccessControlException("Privilege name array is null.");
+        }
+        return registry.getBits(privilegeNames);
+    }
+
+    /**
      * Returns an array of registered <code>Privilege</code>s. If the specified
      * <code>bits</code> represent a single registered privilege the returned
array
      * contains a single element. Otherwise the returned array contains the

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
Tue Oct 11 07:46:36 2011
@@ -600,13 +600,60 @@ public final class PrivilegeRegistry imp
      * @return privilege bits.
      */
     PrivilegeBits getBits(PrivilegeDefinition... definitions) {
-        PrivilegeBits bts = PrivilegeBits.getInstance();
-        for (PrivilegeDefinition d : definitions) {
-            if (d instanceof Definition) {
-                bts.add(((Definition) d).bits);
-            }
+        switch (definitions.length) {
+            case 0:
+                return PrivilegeBits.EMPTY;
+
+            case 1:
+                if (definitions[0] instanceof Definition) {
+                    return ((Definition) definitions[0]).bits;
+                } else {
+                    return PrivilegeBits.EMPTY;
+                }
+
+            default:
+                PrivilegeBits bts = PrivilegeBits.getInstance();
+                for (PrivilegeDefinition d : definitions) {
+                    if (d instanceof Definition) {
+                        bts.add(((Definition) d).bits);
+                    }
+                }
+                return bts;
         }
-        return bts;
+    }
+
+    /**
+     * Return the privilege bits for the specified privilege names.
+     *
+     * @param privilegeNames
+     * @return privilege bits.
+     */
+    PrivilegeBits getBits(Name... privilegeNames) {
+        switch (privilegeNames.length) {
+            case 0:
+                return PrivilegeBits.EMPTY;
+
+            case 1:
+                return getBits(privilegeNames[0]);
+
+            default:
+                PrivilegeBits bts = PrivilegeBits.getInstance();
+                for (Name privName : privilegeNames) {
+                    bts.add(getBits(privName));
+                }
+                return bts;
+        }
+    }
+
+    /**
+     * Return the privilege bits for the specified privilege name.
+     *
+     * @param privilegeName
+     * @return privilege bits.
+     */
+    PrivilegeBits getBits(Name privilegeName) {
+        Definition def = registeredPrivileges.get(privilegeName);
+        return (def == null) ? PrivilegeBits.EMPTY : def.bits;
     }
 
     /**
@@ -677,7 +724,7 @@ public final class PrivilegeRegistry imp
                 allbits.add(d.bits);
             }
 
-            Definition newAll = new Definition(NameConstants.JCR_ALL, false, allAggrNames,
allbits.unmodifiable(), false);
+            Definition newAll = new Definition(NameConstants.JCR_ALL, false, allAggrNames,
allbits, false);
             registeredPrivileges.put(NameConstants.JCR_ALL, newAll);
             bitsToNames.put(newAll.bits, Collections.singleton(NameConstants.JCR_ALL));
         }
@@ -963,7 +1010,7 @@ public final class PrivilegeRegistry imp
             if (bits == null || bits.isEmpty()) {
                 throw new IllegalArgumentException("Failed to build bit representation of
PrivilegeDefinition.");
             } else {
-                this.bits = bits;
+                this.bits = bits.unmodifiable();
             }
             this.isCustom = isCustom;
         }

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=1181645&r1=1181644&r2=1181645&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
Tue Oct 11 07:46:36 2011
@@ -49,6 +49,8 @@ import org.apache.jackrabbit.core.securi
 import org.apache.jackrabbit.core.security.authorization.GlobPattern;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.core.security.principal.UnknownPrincipal;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
 import org.slf4j.Logger;
@@ -167,10 +169,10 @@ class ACLTemplate extends AbstractACLTem
                     princ = new PrincipalImpl(principalName);
                 }
 
-                Value[] privValues = aceNode.getProperty(P_PRIVILEGES).getValues();
-                Privilege[] privs = new Privilege[privValues.length];
+                InternalValue[] privValues = aceNode.getProperty(P_PRIVILEGES).internalGetValues();
+                Name[] privNames = new Name[privValues.length];
                 for (int i = 0; i < privValues.length; i++) {
-                    privs[i] = acMgr.privilegeFromName(privValues[i].getString());
+                    privNames[i] = privValues[i].getName();
                 }
 
                 Map<String,Value> restrictions = null;
@@ -178,9 +180,7 @@ class ACLTemplate extends AbstractACLTem
                     restrictions = Collections.singletonMap(jcrRepGlob, aceNode.getProperty(P_GLOB).getValue());
                 }
                 // create a new ACEImpl (omitting validation check)
-                Entry ace = createEntry(
-                        princ,
-                        privs,
+                Entry ace = new Entry(princ, privilegeMgr.getBits(privNames),
                         NT_REP_GRANT_ACE.equals(((NodeTypeImpl) aceNode.getPrimaryNodeType()).getQName()),
                         restrictions);
                 // add the entry omitting any validation.
@@ -256,9 +256,8 @@ class ACLTemplate extends AbstractACLTem
                         PrivilegeBits mergedBits = PrivilegeBits.getInstance(e.getPrivilegeBits());
                         mergedBits.add(entry.getPrivilegeBits());
                         
-                        Set<Privilege> mergedPrivs = privilegeMgr.getPrivileges(mergedBits);
                         // omit validation check.
-                        entry = createEntry(entry, mergedPrivs.toArray(new Privilege[mergedPrivs.size()]),
entry.isAllow());
+                        entry = new Entry(entry, mergedBits, entry.isAllow());
                     } else {
                         complementEntry = e;
                     }
@@ -286,11 +285,8 @@ class ACLTemplate extends AbstractACLTem
                     entries.remove(complementEntry);
 
                     // combine set of new builtin and custom privileges
-                    Set<Privilege> result = privilegeMgr.getPrivileges(diff);
                     // and create a new entry.
-                    Entry tmpl = createEntry(entry,
-                            result.toArray(new Privilege[result.size()]),
-                            !entry.isAllow());
+                    Entry tmpl = new Entry(entry, diff, !entry.isAllow());
                     entries.add(index, tmpl);
                 } /* else: does not need to be modified.*/
             }
@@ -433,12 +429,23 @@ class ACLTemplate extends AbstractACLTem
 
         private final GlobPattern pattern;
 
+        private Entry(Principal principal, PrivilegeBits privilegeBits, boolean allow, Map<String,Value>
restrictions)
+                throws RepositoryException {
+            super(principal, privilegeBits, allow, restrictions);
+            pattern = calculatePattern();
+        }
+
         private Entry(Principal principal, Privilege[] privileges, boolean allow, Map<String,Value>
restrictions)
                 throws RepositoryException {
             super(principal, privileges, allow, restrictions);
             pattern = calculatePattern();
         }
 
+        private Entry(Entry base, PrivilegeBits newPrivilegeBits, boolean isAllow) throws
RepositoryException {
+            super(base, newPrivilegeBits, isAllow);
+            pattern = calculatePattern();
+        }
+
         private Entry(Entry base, Privilege[] newPrivileges, boolean isAllow) throws RepositoryException
{
             super(base, newPrivileges, isAllow);
             pattern = calculatePattern();

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=1181645&r1=1181644&r2=1181645&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
Tue Oct 11 07:46:36 2011
@@ -23,7 +23,9 @@ import org.apache.jackrabbit.core.Sessio
 import org.apache.jackrabbit.core.security.authorization.AccessControlEntryImpl;
 import org.apache.jackrabbit.core.security.authorization.AbstractACLTemplate;
 import org.apache.jackrabbit.core.security.authorization.GlobPattern;
+import org.apache.jackrabbit.core.security.authorization.PrivilegeBits;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeManagerImpl;
+import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
@@ -114,10 +116,10 @@ class ACLTemplate extends AbstractACLTem
                     // the isAllow flag:
                     boolean isAllow = aceNode.isNodeType(NT_REP_GRANT_ACE);
                     // the privileges
-                    Value[] pValues = aceNode.getProperty(P_PRIVILEGES).getValues();
-                    Privilege[] privileges = new Privilege[pValues.length];
+                    InternalValue[] pValues = aceNode.getProperty(P_PRIVILEGES).internalGetValues();
+                    Name[] privilegeNames = new Name[pValues.length];
                     for (int i = 0; i < pValues.length; i++) {
-                        privileges[i] = acMgr.privilegeFromName(pValues[i].getString());
+                        privilegeNames[i] = pValues[i].getName();
                     }
                     // the restrictions:
                     Map<String, Value> restrictions = new HashMap<String, Value>(2);
@@ -129,7 +131,7 @@ class ACLTemplate extends AbstractACLTem
                         restrictions.put(prop.getName(), prop.getValue());
                     }
                     // finally add the entry
-                    AccessControlEntry entry = createEntry(principal, privileges, isAllow,
restrictions);
+                    AccessControlEntry entry = new Entry(principal, privilegeMgr.getBits(privilegeNames),
isAllow, restrictions);
                     entries.add(entry);
                 } else {
                     log.warn("ACE must be of nodetype rep:ACE -> ignored child-node "
+ aceNode.getPath());
@@ -324,6 +326,21 @@ class ACLTemplate extends AbstractACLTem
             }
         }
 
+        private Entry(Principal principal, PrivilegeBits privilegeBits, boolean allow,
+                      Map<String, Value> restrictions)
+                throws AccessControlException, RepositoryException {
+            super(principal, privilegeBits, allow, restrictions);
+
+            Map<Name, Value> rstr = getRestrictions();
+            nodePath = rstr.get(P_NODE_PATH).getString();
+            Value glob = rstr.get(P_GLOB);
+            if (glob != null) {
+                pattern = GlobPattern.create(nodePath, glob.getString());
+            } else {
+                pattern = GlobPattern.create(nodePath);
+            }
+        }
+
         boolean matches(String jcrPath) throws RepositoryException {
             return pattern.matches(jcrPath);
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
Tue Oct 11 07:46:36 2011
@@ -38,6 +38,7 @@ import org.apache.jackrabbit.core.securi
 import org.apache.jackrabbit.core.security.authorization.PrivilegeManagerImpl;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
@@ -378,11 +379,19 @@ public class UserAccessControlProvider e
 
         private PrivilegeBits getPrivilegeBits(String... privNames) throws RepositoryException
{
             PrivilegeManagerImpl impl = getPrivilegeManagerImpl();
-            Privilege[] privs = new Privilege[privNames.length];
+            Name[] names = new Name[privNames.length];
             for (int i = 0; i < privNames.length; i++) {
-                privs[i] = impl.getPrivilege(privNames[i]);
+                names[i] = session.getQName(privNames[i]);
+            }
+            return impl.getBits(names);
+        }
+
+        private PrivilegeBits assertModifiable(PrivilegeBits bits) {
+            if (bits.isModifiable()) {
+                return bits;
+            } else {
+                return PrivilegeBits.getInstance(bits);
             }
-            return impl.getBits(privs);
         }
 
         //------------------------------------< AbstractCompiledPermissions >---
@@ -440,6 +449,7 @@ public class UserAccessControlProvider e
                         if (calcPrivs) {
                             // grant WRITE privilege
                             // note: ac-read/modification is not included
+                            privs = assertModifiable(privs);
                             privs.add(getPrivilegeBits(PrivilegeRegistry.REP_WRITE));
                         }
                     }
@@ -452,6 +462,7 @@ public class UserAccessControlProvider e
                         // user can only read && write his own props
                         allows |= (Permission.SET_PROPERTY | Permission.REMOVE_PROPERTY);
                         if (calcPrivs) {
+                            privs = assertModifiable(privs);
                             privs.add(getPrivilegeBits(Privilege.JCR_MODIFY_PROPERTIES));
                         }
                     } else if (isUserAdmin) {
@@ -459,6 +470,7 @@ public class UserAccessControlProvider e
                         if (calcPrivs) {
                             // grant WRITE privilege
                             // note: ac-read/modification is not included
+                            privs = assertModifiable(privs);
                             privs.add(getPrivilegeBits(PrivilegeRegistry.REP_WRITE));
                         }
                     } // else: normal user that isn't allowed to modify another user.
@@ -478,12 +490,14 @@ public class UserAccessControlProvider e
                             // no remove perm on group-admin node
                             allows |= (Permission.ADD_NODE | Permission.SET_PROPERTY | Permission.REMOVE_PROPERTY
| Permission.NODE_TYPE_MNGMT);
                             if (calcPrivs) {
+                                privs = assertModifiable(privs);
                                 privs.add(getPrivilegeBits(Privilege.JCR_ADD_CHILD_NODES,
Privilege.JCR_MODIFY_PROPERTIES, Privilege.JCR_NODE_TYPE_MANAGEMENT));
                             }
                         } else {
                             // complete write
                             allows |= (Permission.ADD_NODE | Permission.REMOVE_NODE | Permission.SET_PROPERTY
| Permission.REMOVE_PROPERTY | Permission.NODE_TYPE_MNGMT);
                             if (calcPrivs) {
+                                privs = assertModifiable(privs);
                                 privs.add(getPrivilegeBits(PrivilegeRegistry.REP_WRITE));
                             }
                         }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEntryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEntryTest.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEntryTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractEntryTest.java
Tue Oct 11 07:46:36 2011
@@ -219,6 +219,90 @@ public abstract class AbstractEntryTest 
         }
     }
 
+    public void testHashCode() throws RepositoryException, NotExecutableException  {
+
+        Map<AccessControlEntry, AccessControlEntry> equivalent = new HashMap<AccessControlEntry,
AccessControlEntry>();
+        JackrabbitAccessControlEntry ace = createEntry(new String[] {Privilege.JCR_ALL},
true);
+        // create same entry again
+        equivalent.put(ace, createEntry(new String[] {Privilege.JCR_ALL}, true));
+        // create entry with declared aggregate privileges
+        Privilege[] declaredAllPrivs = acMgr.privilegeFromName(Privilege.JCR_ALL).getDeclaredAggregatePrivileges();
+        equivalent.put(ace, createEntry(testPrincipal, declaredAllPrivs, true));
+        // create entry with aggregate privileges
+        Privilege[] aggregateAllPrivs = acMgr.privilegeFromName(Privilege.JCR_ALL).getAggregatePrivileges();
+        equivalent.put(ace, createEntry(testPrincipal, aggregateAllPrivs, true));
+        // create entry with different privilege order
+        List<Privilege> reordered = new ArrayList<Privilege>(Arrays.asList(aggregateAllPrivs));
+        reordered.add(reordered.remove(0));
+        equivalent.put(createEntry(testPrincipal, reordered.toArray(new Privilege[reordered.size()]),
true),
+                      createEntry(testPrincipal, aggregateAllPrivs, true));
+        // even if entries are build with aggregated or declared aggregate privileges
+        equivalent.put(createEntry(testPrincipal, declaredAllPrivs, true),
+                      createEntry(testPrincipal, aggregateAllPrivs, true));
+
+        for (AccessControlEntry entry : equivalent.keySet()) {
+            assertEquals(entry.hashCode(), equivalent.get(entry).hashCode());
+        }
+
+        // and the opposite:
+        List<JackrabbitAccessControlEntry> otherAces = new ArrayList<JackrabbitAccessControlEntry>();
+        try {
+            // ACE template with different principal
+            Principal princ = new Principal() {
+                public String getName() {
+                    return "a name";
+                }
+            };
+            Privilege[] privs = new Privilege[] {
+                    acMgr.privilegeFromName(Privilege.JCR_ALL)
+            };
+            otherAces.add(createEntry(princ, privs, true));
+        } catch (RepositoryException e) {
+        }
+        // ACE template with different privileges
+        try {
+            otherAces.add(createEntry(new String[] {Privilege.JCR_READ}, true));
+        } catch (RepositoryException e) {
+        }
+        // ACE template with different 'allow' flag
+        try {
+            otherAces.add(createEntry(new String[] {Privilege.JCR_ALL}, false));
+        } catch (RepositoryException e) {
+        }
+        // ACE template with different privileges and 'allows
+        try {
+            otherAces.add(createEntry(new String[] {PrivilegeRegistry.REP_WRITE}, false));
+        } catch (RepositoryException e) {
+        }
+        // other ace impl
+        final Privilege[] privs = new Privilege[] {
+                acMgr.privilegeFromName(Privilege.JCR_ALL)
+        };
+        JackrabbitAccessControlEntry pe = new JackrabbitAccessControlEntry() {
+            public boolean isAllow() {
+                return true;
+            }
+            public String[] getRestrictionNames() {
+                return new String[0];
+            }
+            public Value getRestriction(String restrictionName) {
+                return null;
+            }
+            public Principal getPrincipal() {
+                return testPrincipal;
+            }
+            public Privilege[] getPrivileges() {
+                return privs;
+            }
+        };
+        otherAces.add(pe);
+
+        for (JackrabbitAccessControlEntry otherAce : otherAces) {
+            assertFalse(ace.hashCode() == otherAce.hashCode());
+        }
+
+    }
+
     public void testNullPrincipal() throws RepositoryException {
         try {
             Privilege[] privs = new Privilege[] {

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBitsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBitsTest.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBitsTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeBitsTest.java
Tue Oct 11 07:46:36 2011
@@ -486,7 +486,6 @@ public class PrivilegeBitsTest extends J
         for (long l : LONGS) {
             pb = PrivilegeBits.getInstance(l);
             assertEquals(pb, PrivilegeBits.getInstance(l));
-            assertNotSame(pb, PrivilegeBits.getInstance(l));
             assertSame(pb, pb.unmodifiable());
 
             assertEquals(pb, PrivilegeBits.getInstance(pb));

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java?rev=1181645&r1=1181644&r2=1181645&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java
Tue Oct 11 07:46:36 2011
@@ -118,7 +118,7 @@ public class PrivilegeManagerImplTest ex
 
         PrivilegeBits bits = getPrivilegeManagerImpl().getBits(privs);
         assertFalse(bits.isEmpty());
-        PrivilegeBits other = getPrivilegeManagerImpl().getBits(p1);
+        PrivilegeBits other = PrivilegeBits.getInstance(getPrivilegeManagerImpl().getBits(p1));
         other.add(getPrivilegeManagerImpl().getBits(p2));
         assertEquals(bits, other);
     }



Mime
View raw message