You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2011/09/30 16:03:12 UTC

svn commit: r1177668 [1/2] - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/ jackrabbi...

Author: angela
Date: Fri Sep 30 14:03:11 2011
New Revision: 1177668

URL: http://svn.apache.org/viewvc?rev=1177668&view=rev
Log:
JCR-2887 : Split PrivilegeRegistry in a per-session manager instance and a repository level registry [work in progress]
JCR-2774 : Access control for repository level API operations

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractRepositoryOperationTest.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/RepositoryOperationTest.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/RepositoryOperationTest.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java
    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/AccessControlConstants.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.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/ACLEditor.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.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/acl/CompiledPermissionsImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java
    jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/authorization/PrivilegeManagerTest.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/CustomPrivilegeTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PermissionTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerImplTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/TestAll.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/EvaluationUtil.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/principalbased/TestAll.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameConstants.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java Fri Sep 30 14:03:11 2011
@@ -195,6 +195,13 @@ class SystemSession extends SessionImpl 
 
         /**
          * {@inheritDoc}
+         */
+        public void checkRepositoryPermission(int permissions) throws AccessDeniedException, RepositoryException {
+            // allow everything
+        }
+
+        /**
+         * {@inheritDoc}
          *
          * @return always <code>true</code>
          * @throws RepositoryException   is never thrown
@@ -275,12 +282,14 @@ class SystemSession extends SessionImpl 
         @Override
         protected void checkValidNodePath(String absPath)
                 throws PathNotFoundException, RepositoryException {
-            Path p = getQPath(absPath);
-            if (!p.isAbsolute()) {
-                throw new RepositoryException("Absolute path expected.");
-            }
-            if (context.getHierarchyManager().resolveNodePath(p) == null) {
-                throw new PathNotFoundException("No such node " + absPath);
+            if (absPath != null) {
+                Path p = getQPath(absPath);
+                if (!p.isAbsolute()) {
+                    throw new RepositoryException("Absolute path expected.");
+                }
+                if (context.getHierarchyManager().resolveNodePath(p) == null) {
+                    throw new PathNotFoundException("No such node " + absPath);
+                }
             }
         }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Fri Sep 30 14:03:11 2011
@@ -54,6 +54,7 @@ import org.apache.jackrabbit.core.observ
 import org.apache.jackrabbit.core.observation.ObservationManagerImpl;
 import org.apache.jackrabbit.core.query.QueryManagerImpl;
 import org.apache.jackrabbit.core.retention.RetentionRegistry;
+import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.session.SessionContext;
 import org.apache.jackrabbit.core.state.ItemStateCacheFactory;
 import org.apache.jackrabbit.core.state.LocalItemStateManager;
@@ -210,12 +211,9 @@ public class WorkspaceImpl extends Abstr
             throws AccessDeniedException, RepositoryException {
         // check state of this instance
         sanityCheck();
+        context.getAccessManager().checkRepositoryPermission(Permission.WORKSPACE_MNGMT);
 
-        WorkspaceManager manager =
-            context.getRepositoryContext().getWorkspaceManager();
-
-        // TODO verify that this session has the right privileges
-        // for this operation
+        WorkspaceManager manager = context.getRepositoryContext().getWorkspaceManager();
         manager.createWorkspace(name);
 
         SessionImpl tmpSession = null;
@@ -253,6 +251,8 @@ public class WorkspaceImpl extends Abstr
             UnsupportedRepositoryOperationException, RepositoryException {
         // check if workspace exists (will throw NoSuchWorkspaceException if not)
         context.getRepository().getWorkspaceInfo(name);
+        context.getAccessManager().checkRepositoryPermission(Permission.WORKSPACE_MNGMT);
+
         // todo implement deleteWorkspace
         throw new UnsupportedRepositoryOperationException("not yet implemented");
     }
@@ -313,9 +313,8 @@ public class WorkspaceImpl extends Abstr
             throws AccessDeniedException, RepositoryException {
         // check state of this instance
         sanityCheck();
+        context.getAccessManager().checkRepositoryPermission(Permission.WORKSPACE_MNGMT);
 
-        // TODO verify that this session has the right privileges
-        // for this operation
         context.getRepositoryContext().getWorkspaceManager().createWorkspace(name);
     }
 
@@ -337,9 +336,7 @@ public class WorkspaceImpl extends Abstr
             throws AccessDeniedException, RepositoryException {
         // check state of this instance
         sanityCheck();
-
-        // TODO verify that this session has the right privileges
-        // for this operation
+        context.getAccessManager().checkRepositoryPermission(Permission.WORKSPACE_MNGMT);
         context.getRepositoryContext().getWorkspaceManager().createWorkspace(
                 workspaceName, configTemplate);
     }
@@ -576,7 +573,7 @@ public class WorkspaceImpl extends Abstr
      * {@inheritDoc}
      */
     public NamespaceRegistry getNamespaceRegistry() throws RepositoryException {
-        return context.getRepositoryContext().getNamespaceRegistry();
+        return context.getNamespaceRegistry();
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java Fri Sep 30 14:03:11 2011
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.commons.cnd
 import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
 import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
+import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.session.SessionContext;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QNodeDefinition;
@@ -219,6 +220,9 @@ public class NodeTypeManagerImpl extends
     public NodeType[] registerNodeTypes(InputStream in, String contentType,
             boolean reregisterExisting)
             throws IOException, RepositoryException {
+        
+        // make sure the editing session is allowed to register node types.
+        context.getAccessManager().checkRepositoryPermission(Permission.NODE_TYPE_DEF_MNGMT);
 
         try {
             Map<String, String> namespaceMap = new HashMap<String, String>();
@@ -549,6 +553,10 @@ public class NodeTypeManagerImpl extends
             NodeTypeDefinition[] definitions, boolean allowUpdate)
             throws InvalidNodeTypeDefinitionException, NodeTypeExistsException,
             UnsupportedRepositoryOperationException, RepositoryException {
+
+        // make sure the editing session is allowed to register node types.
+        context.getAccessManager().checkRepositoryPermission(Permission.NODE_TYPE_DEF_MNGMT);
+
         NodeTypeRegistry registry = context.getNodeTypeRegistry();
 
         // split the node types into new and already registered node types.
@@ -605,6 +613,10 @@ public class NodeTypeManagerImpl extends
     public void unregisterNodeTypes(String[] names)
             throws UnsupportedRepositoryOperationException,
             NoSuchNodeTypeException, RepositoryException {
+
+        // make sure the editing session is allowed to un-register node types.
+        context.getAccessManager().checkRepositoryPermission(Permission.NODE_TYPE_DEF_MNGMT);
+
         Set<Name> ntNames = new HashSet<Name>();
         for (String name : names) {
             try {
@@ -642,5 +654,4 @@ public class NodeTypeManagerImpl extends
         return "NodeTypeManager(" + super.toString() + ")\n"
             + context.getNodeTypeRegistry();
     }
-
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java Fri Sep 30 14:03:11 2011
@@ -180,4 +180,4 @@ public abstract class AbstractAccessCont
      */
     protected abstract void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException;
 
-}
\ No newline at end of file
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java Fri Sep 30 14:03:11 2011
@@ -117,7 +117,17 @@ public interface AccessManager {
      * @throws RepositoryException   it another error occurs
      */
     void checkPermission(Path absPath, int permissions) throws AccessDeniedException, RepositoryException;
-    
+
+    /**
+     * Determines whether the specified <code>permissions</code> are granted
+     * on the repository level.
+     *
+     * @param permissions The permissions to check.
+     * @throws AccessDeniedException if permissions are denied.
+     * @throws RepositoryException if another error occurs.
+     */
+    void checkRepositoryPermission(int permissions) throws AccessDeniedException, RepositoryException;
+
     /**
      * Determines whether the specified <code>permissions</code> are granted
      * on the item with the specified <code>id</code> (i.e. the <i>target</i> item).

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java Fri Sep 30 14:03:11 2011
@@ -195,6 +195,16 @@ public class DefaultAccessManager extend
     }
 
     /**
+     * @see AccessManager#checkRepositoryPermission(int)
+     */
+    public void checkRepositoryPermission(int permissions) throws AccessDeniedException, RepositoryException {
+        checkInitialized();
+        if (!compiledPermissions.grants(null, permissions)) {
+            throw new AccessDeniedException("Access denied.");
+        }
+    }
+
+    /**
      * @see AccessManager#isGranted(ItemId, int)
      */
     public boolean isGranted(ItemId id, int actions)
@@ -276,7 +286,7 @@ public class DefaultAccessManager extend
             log.debug("No privileges passed -> allowed.");
             return true;
         } else {
-            Path p = resolver.getQPath(absPath);
+            Path p = getPath(absPath);
             return compiledPermissions.hasPrivileges(p, privileges);
         }
     }
@@ -287,7 +297,7 @@ public class DefaultAccessManager extend
     public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
         checkInitialized();
         checkValidNodePath(absPath);
-        Set<Privilege> privs = compiledPermissions.getPrivilegeSet(resolver.getQPath(absPath));
+        Set<Privilege> privs = compiledPermissions.getPrivilegeSet(getPath(absPath));
         return privs.toArray(new Privilege[privs.size()]);
     }
 
@@ -410,7 +420,7 @@ public class DefaultAccessManager extend
             log.debug("No privileges passed -> allowed.");
             return true;
         } else {
-            Path p = resolver.getQPath(absPath);
+            Path p = getPath(absPath);
             CompiledPermissions perms = acProvider.compilePermissions(principals);
             try {
                 return perms.hasPrivileges(p, privileges);
@@ -430,7 +440,7 @@ public class DefaultAccessManager extend
 
         CompiledPermissions perms = acProvider.compilePermissions(principals);
         try {
-            Set<Privilege> privs = perms.getPrivilegeSet(resolver.getQPath(absPath));
+            Set<Privilege> privs = perms.getPrivilegeSet(getPath(absPath));
             return privs.toArray(new Privilege[privs.size()]);
         } finally {
             perms.close();
@@ -453,12 +463,14 @@ public class DefaultAccessManager extend
      */
     @Override
     protected void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
-        Path p = resolver.getQPath(absPath);
-        if (!p.isAbsolute()) {
-            throw new RepositoryException("Absolute path expected.");
-        }
-        if (hierMgr.resolveNodePath(p) == null) {
-            throw new PathNotFoundException("No such node " + absPath);
+        Path p = getPath(absPath);
+        if (p != null) {
+            if (!p.isAbsolute()) {
+                throw new RepositoryException("Absolute path expected.");
+            }
+            if (hierMgr.resolveNodePath(p) == null) {
+                throw new PathNotFoundException("No such node " + absPath);
+            }
         }
     }
 
@@ -468,7 +480,7 @@ public class DefaultAccessManager extend
     @Override
     protected void checkPermission(String absPath, int permission) throws AccessDeniedException, RepositoryException {
         checkValidNodePath(absPath);
-        Path p = resolver.getQPath(absPath);
+        Path p = getPath(absPath);
         if (!compiledPermissions.grants(p, permission)) {
             throw new AccessDeniedException("Access denied at " + absPath);
         }
@@ -485,7 +497,7 @@ public class DefaultAccessManager extend
 
     //------------------------------------------------------------< private >---
     private Path getPath(String absPath) throws RepositoryException {
-        return resolver.getQPath(absPath);
+        return (absPath == null) ? null : resolver.getQPath(absPath);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java Fri Sep 30 14:03:11 2011
@@ -107,6 +107,12 @@ public class SimpleJBossAccessManager im
         }
     }
 
+    public void checkRepositoryPermission(int permissions) throws AccessDeniedException, RepositoryException {
+        if (!isGranted((ItemId) null, permissions)) {
+            throw new AccessDeniedException("Access denied");
+        }
+    }
+
     public boolean isGranted(ItemId id, int permissions) throws RepositoryException {
         // system has always all permissions
         // anonymous has only READ permissions

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -16,14 +16,13 @@
  */
 package org.apache.jackrabbit.core.security.authorization;
 
-import java.util.Map;
-import java.util.Set;
+import org.apache.commons.collections.map.LRUMap;
+import org.apache.jackrabbit.spi.Path;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.security.Privilege;
-
-import org.apache.commons.collections.map.LRUMap;
-import org.apache.jackrabbit.spi.Path;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * <code>AbstractCompiledPermissions</code>...
@@ -50,7 +49,11 @@ public abstract class AbstractCompiledPe
         synchronized (monitor) {
             result = cache.get(absPath);
             if (result == null) {
-                result = buildResult(absPath);
+                if (absPath == null) {
+                    result = buildRepositoryResult();
+                } else {
+                    result = buildResult(absPath);
+                }
                 cache.put(absPath, result);
             }
         }
@@ -58,7 +61,8 @@ public abstract class AbstractCompiledPe
     }
 
     /**
-     *
+     * Retrieve the result for the specified path.
+     * 
      * @param absPath Absolute path to build the result for.
      * @return Result for the specified <code>absPath</code>.
      * @throws RepositoryException If an error occurs.
@@ -66,8 +70,19 @@ public abstract class AbstractCompiledPe
     protected abstract Result buildResult(Path absPath) throws RepositoryException;
 
     /**
+     * Retrieve the result for repository level operations.
+     *
+     * @return The result instance for those permissions and privileges granted
+     * for repository level operations.
+     * @throws RepositoryException
+     */
+    protected abstract Result buildRepositoryResult() throws RepositoryException;
+
+    /**
+     * Retrieve the privilege manager.
      * 
-     * @return
+     * @return An instance of privilege manager.
+     * @throws javax.jcr.RepositoryException If an error occurs.
      */
     protected abstract PrivilegeManagerImpl getPrivilegeManagerImpl() throws RepositoryException;
 
@@ -135,7 +150,6 @@ public abstract class AbstractCompiledPe
     public static class Result {
 
         public static final Result EMPTY = new Result(Permission.NONE, Permission.NONE, PrivilegeBits.EMPTY, PrivilegeBits.EMPTY);
-
         private final int allows;
         private final int denies;
         private final PrivilegeBits allowPrivileges;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java Fri Sep 30 14:03:11 2011
@@ -31,6 +31,11 @@ public interface AccessControlConstants 
     Name N_POLICY = NameConstants.REP_POLICY;
 
     /**
+     * Name name for a node of type rep:Policy storing repository level privileges.
+     */
+    Name N_REPO_POLICY = NameConstants.REP_REPO_POLICY;
+
+    /**
      * PrincipalBased-ACL:
      * Name of the root-node of all access-control-nodes that store the
      * privileges for individual principals. This node is created upon
@@ -60,6 +65,10 @@ public interface AccessControlConstants 
      */
     Name NT_REP_ACCESS_CONTROLLABLE = NameConstants.REP_ACCESS_CONTROLLABLE;
     /**
+     * rep:RepoAccessControllable nodetype
+     */
+    Name NT_REP_REPO_ACCESS_CONTROLLABLE = NameConstants.REP_REPO_ACCESS_CONTROLLABLE;
+    /**
      * rep:ACL nodetype
      */
     Name NT_REP_ACL = NameConstants.REP_ACL;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java Fri Sep 30 14:03:11 2011
@@ -49,9 +49,19 @@ public final class Permission {
 
     public static final int MODIFY_CHILD_NODE_COLLECTION = RETENTION_MNGMT << 1;
 
-    public static final int PRIVILEGE_MNGMT = MODIFY_CHILD_NODE_COLLECTION << 1;
+    public static final int NODE_TYPE_DEF_MNGMT = MODIFY_CHILD_NODE_COLLECTION << 1;
 
-    public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE | REMOVE_PROPERTY | READ_AC | MODIFY_AC | NODE_TYPE_MNGMT | VERSION_MNGMT | LOCK_MNGMT | LIFECYCLE_MNGMT | RETENTION_MNGMT | MODIFY_CHILD_NODE_COLLECTION | PRIVILEGE_MNGMT);
+    public static final int NAMESPACE_MNGMT = NODE_TYPE_DEF_MNGMT << 1;
+
+    public static final int WORKSPACE_MNGMT = NAMESPACE_MNGMT << 1;
+
+    public static final int PRIVILEGE_MNGMT = WORKSPACE_MNGMT << 1;
+
+    public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE
+            | REMOVE_PROPERTY | READ_AC | MODIFY_AC | NODE_TYPE_MNGMT
+            | VERSION_MNGMT | LOCK_MNGMT | LIFECYCLE_MNGMT | RETENTION_MNGMT
+            | MODIFY_CHILD_NODE_COLLECTION | NODE_TYPE_DEF_MNGMT | NAMESPACE_MNGMT
+            | WORKSPACE_MNGMT | PRIVILEGE_MNGMT);
 
     /**
      * Returns those bits from <code>permissions</code> that are not present in

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -141,14 +141,11 @@ public final class PrivilegeManagerImpl 
     public Privilege registerPrivilege(String privilegeName, boolean isAbstract,
                                        String[] declaredAggregateNames)
             throws AccessDeniedException, RepositoryException {
-        boolean allowed = false;
         if (resolver instanceof SessionImpl) {
-            // TODO: FIXME should be 'null' path as privilegeManagement is a
-            // TODO: repo-level privilege such as namespace or node type mgt.
             SessionImpl sImpl = (SessionImpl) resolver;
-            allowed = sImpl.getAccessManager().isGranted(sImpl.getQPath("/"), Permission.PRIVILEGE_MNGMT);
-        }
-        if (!allowed) {
+            sImpl.getAccessManager().checkRepositoryPermission(Permission.PRIVILEGE_MNGMT);
+        } else {
+            // cannot evaluate
             throw new AccessDeniedException("Registering privileges is not allowed for the editing session.");
         }
 

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -97,8 +97,11 @@ public final class PrivilegeRegistry imp
     private static final int LOCK_MNGMT = VERSION_MNGMT << 1;
     private static final int LIFECYCLE_MNGMT = LOCK_MNGMT << 1;
     private static final int RETENTION_MNGMT = LIFECYCLE_MNGMT << 1;
-    private static final int PRIVILEGE_MNGMT = RETENTION_MNGMT << 1;
-
+    private static final int WORKSPACE_MNGMT = RETENTION_MNGMT << 1;
+    private static final int NODE_TYPE_DEF_MNGMT = WORKSPACE_MNGMT << 1;
+    private static final int NAMESPACE_MNGMT = NODE_TYPE_DEF_MNGMT << 1;
+    private static final int PRIVILEGE_MNGMT = NAMESPACE_MNGMT << 1;
+    
     private static final Map<Name, Integer> PRIVILEGE_NAMES = new HashMap<Name, Integer>();
     static {
         PRIVILEGE_NAMES.put(NameConstants.JCR_READ, READ);
@@ -113,6 +116,9 @@ public final class PrivilegeRegistry imp
         PRIVILEGE_NAMES.put(NameConstants.JCR_LOCK_MANAGEMENT, LOCK_MNGMT);
         PRIVILEGE_NAMES.put(NameConstants.JCR_LIFECYCLE_MANAGEMENT, LIFECYCLE_MNGMT);
         PRIVILEGE_NAMES.put(NameConstants.JCR_RETENTION_MANAGEMENT, RETENTION_MNGMT);
+        PRIVILEGE_NAMES.put(NameConstants.JCR_WORKSPACE_MANAGEMENT, WORKSPACE_MNGMT);
+        PRIVILEGE_NAMES.put(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT, NODE_TYPE_DEF_MNGMT);
+        PRIVILEGE_NAMES.put(NameConstants.JCR_NAMESPACE_MANAGEMENT, NAMESPACE_MNGMT);
         PRIVILEGE_NAMES.put(REP_PRIVILEGE_MANAGEMENT_NAME, PRIVILEGE_MNGMT);
     }
 
@@ -420,6 +426,15 @@ public final class PrivilegeRegistry imp
         if ((privs & VERSION_MNGMT) == VERSION_MNGMT) {
             perm |= Permission.VERSION_MNGMT;
         }
+        if ((privs & WORKSPACE_MNGMT) == WORKSPACE_MNGMT) {
+            perm |= Permission.WORKSPACE_MNGMT;
+        }
+        if ((privs & NODE_TYPE_DEF_MNGMT) == NODE_TYPE_DEF_MNGMT) {
+            perm |= Permission.NODE_TYPE_DEF_MNGMT;
+        }
+        if ((privs & NAMESPACE_MNGMT) == NAMESPACE_MNGMT) {
+            perm |= Permission.NAMESPACE_MNGMT;
+        }
         if ((privs & PRIVILEGE_MNGMT) == PRIVILEGE_MNGMT) {
             perm |= Permission.PRIVILEGE_MNGMT;
         }
@@ -540,6 +555,15 @@ public final class PrivilegeRegistry imp
             if ((bits & RETENTION_MNGMT) == RETENTION_MNGMT) {
                 names.add(NameConstants.JCR_RETENTION_MANAGEMENT);
             }
+            if ((bits & WORKSPACE_MNGMT) == WORKSPACE_MNGMT) {
+                names.add(NameConstants.JCR_WORKSPACE_MANAGEMENT);
+            }
+            if ((bits & NODE_TYPE_DEF_MNGMT) == NODE_TYPE_DEF_MNGMT) {
+                names.add(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT);
+            }
+            if ((bits & NAMESPACE_MNGMT) == NAMESPACE_MNGMT) {
+                names.add(NameConstants.JCR_NAMESPACE_MANAGEMENT);
+            }
             if ((bits & PRIVILEGE_MNGMT) == PRIVILEGE_MNGMT) {
                 names.add(REP_PRIVILEGE_MANAGEMENT_NAME);
             }
@@ -694,11 +718,13 @@ public final class PrivilegeRegistry imp
         jcrAllAggregates.add(NameConstants.JCR_NODE_TYPE_MANAGEMENT);
         jcrAllAggregates.add(NameConstants.JCR_RETENTION_MANAGEMENT);
         jcrAllAggregates.add(NameConstants.JCR_LIFECYCLE_MANAGEMENT);
+        jcrAllAggregates.add(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT);
+        jcrAllAggregates.add(NameConstants.JCR_NAMESPACE_MANAGEMENT);
+        jcrAllAggregates.add(NameConstants.JCR_WORKSPACE_MANAGEMENT);
         jcrAllAggregates.add(NameConstants.JCR_WRITE);
         jcrAllAggregates.add(REP_WRITE_NAME);
         jcrAllAggregates.add(REP_PRIVILEGE_MANAGEMENT_NAME);
 
-
         Definition jcrAll = new Definition(NameConstants.JCR_ALL, false, jcrAllAggregates, jcrAllBits);
         defs.put(jcrAll.getName(), jcrAll);
 
@@ -732,7 +758,7 @@ public final class PrivilegeRegistry imp
             // - make sure the specified name defines a registered namespace
             namespaceRegistry.getPrefix(name.getNamespaceURI());
             // - and isn't one of the reserved namespaces
-            if (((NamespaceRegistryImpl) namespaceRegistry).isReservedURI(name.getNamespaceURI())) {
+            if (isReservedNamespaceURI(name.getNamespaceURI())) {
                 throw new RepositoryException("Failed to register custom privilege: Reserved namespace URI: " + name.getNamespaceURI());
             }
 
@@ -803,6 +829,17 @@ public final class PrivilegeRegistry imp
         return definitions;
     }
 
+    private boolean isReservedNamespaceURI(String uri) {
+        if (namespaceRegistry instanceof NamespaceRegistryImpl) {
+            return ((NamespaceRegistryImpl) namespaceRegistry).isReservedURI(uri);
+        } else {
+            // hardcoded fallback
+            return Name.NS_REP_URI.equals(uri)
+                    || (uri.startsWith("http://www.w3.org"))
+                    || uri.startsWith("http://www.jcp.org");
+        }
+    }
+
     /**
      *
      * @return

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java Fri Sep 30 14:03:11 2011
@@ -82,11 +82,12 @@ public class ACLEditor extends Protected
     /**
      *
      * @param aclNode the node
+     * @param path
      * @return the control list
      * @throws RepositoryException if an error occurs
      */
-    ACLTemplate getACL(NodeImpl aclNode) throws RepositoryException {
-        return new ACLTemplate(aclNode);
+    ACLTemplate getACL(NodeImpl aclNode, String path) throws RepositoryException {
+        return new ACLTemplate(aclNode, path);
     }
 
     //------------------------------------------------< AccessControlEditor >---
@@ -100,7 +101,7 @@ public class ACLEditor extends Protected
         if (aclNode == null) {
             return new AccessControlPolicy[0];
         } else {
-            return new AccessControlPolicy[] {getACL(aclNode)};
+            return new AccessControlPolicy[] {getACL(aclNode, nodePath)};
         }
     }
 
@@ -123,18 +124,30 @@ public class ACLEditor extends Protected
     public AccessControlPolicy[] editAccessControlPolicies(String nodePath) throws AccessControlException, PathNotFoundException, RepositoryException {
         checkProtectsNode(nodePath);
 
+        String mixin;
+        Name aclName;
+        NodeImpl controlledNode;
+
+        if (nodePath == null) {
+            controlledNode = (NodeImpl) session.getRootNode();
+            mixin = session.getJCRName(NT_REP_REPO_ACCESS_CONTROLLABLE);
+            aclName = N_REPO_POLICY;
+        } else {
+            controlledNode = getNode(nodePath);
+            mixin = session.getJCRName(NT_REP_ACCESS_CONTROLLABLE);
+            aclName = N_POLICY;
+        }
+
         AccessControlPolicy acl = null;
-        NodeImpl controlledNode = getNode(nodePath);
-        NodeImpl aclNode = getAclNode(controlledNode);
+        NodeImpl aclNode = getAclNode(controlledNode, nodePath);
         if (aclNode == null) {
             // create an empty acl unless the node is protected or cannot have
-            // rep:AccessControllable mixin set (e.g. due to a lock) or
-            // has colliding rep:policy child node set.
-            if (controlledNode.hasNode(N_POLICY)) {
+            // mixin set (e.g. due to a lock) or
+            // has colliding rep:policy or rep:repoPolicy child node set.
+            if (controlledNode.hasNode(aclName)) {
                 // policy child node without node being access controlled
-                log.warn("Colliding rep:policy child without node being access controllable ({}).", nodePath);
+                log.warn("Colliding policy child without node being access controllable ({}).", nodePath);
             } else {
-                String mixin = session.getJCRName(NT_REP_ACCESS_CONTROLLABLE);
                 PrivilegeManager privMgr = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager();
                 if (controlledNode.isNodeType(mixin) || controlledNode.canAddMixin(mixin)) {
                     acl = new ACLTemplate(nodePath, session.getPrincipalManager(),
@@ -144,6 +157,7 @@ public class ACLEditor extends Protected
                 }
             }
         } // else: acl already present -> getPolicies must be used.
+
         return (acl != null) ? new AccessControlPolicy[] {acl} : new AccessControlPolicy[0];
     }
 
@@ -174,7 +188,7 @@ public class ACLEditor extends Protected
             }
         } else {
             // create the acl node
-            aclNode = createAclNode(nodePath);
+            aclNode = (nodePath == null) ? createRepoAclNode() : createAclNode(nodePath);
         }
         
         AccessControlEntry[] entries = ((ACLTemplate) policy).getAccessControlEntries();
@@ -236,9 +250,11 @@ public class ACLEditor extends Protected
      * @throws RepositoryException
      */
     private void checkProtectsNode(String nodePath) throws RepositoryException {
-        NodeImpl node = getNode(nodePath);
-        if (utils.isAcItem(node)) {
-            throw new AccessControlException("Node " + nodePath + " defines ACL or ACE itself.");
+        if (nodePath != null) {
+            NodeImpl node = getNode(nodePath);
+            if (utils.isAcItem(node)) {
+                throw new AccessControlException("Node " + nodePath + " defines ACL or ACE itself.");
+            }
         }
     }
 
@@ -254,7 +270,8 @@ public class ACLEditor extends Protected
             throw new AccessControlException("Attempt to set/remove invalid policy " + policy);
         }
         ACLTemplate acl = (ACLTemplate) policy;
-        if (!nodePath.equals(acl.getPath())) {
+        boolean matchingPath = (nodePath == null) ? acl.getPath() == null : nodePath.equals(acl.getPath());
+        if (!matchingPath) {
             throw new AccessControlException("Policy " + policy + " cannot be applied/removed from the node at " + nodePath);
         }
     }
@@ -281,8 +298,13 @@ public class ACLEditor extends Protected
      * @throws RepositoryException if an error occurs
      */
     private NodeImpl getAclNode(String nodePath) throws PathNotFoundException, RepositoryException {
-        NodeImpl controlledNode = getNode(nodePath);
-        return getAclNode(controlledNode);
+        NodeImpl controlledNode;
+        if (nodePath == null) {
+            controlledNode = (NodeImpl) session.getRootNode();
+        } else {
+            controlledNode = getNode(nodePath);
+        }
+        return getAclNode(controlledNode, nodePath);
     }
 
     /**
@@ -290,13 +312,20 @@ public class ACLEditor extends Protected
      * if the node is not mix:AccessControllable or if no policy node exists.
      *
      * @param controlledNode the controlled node
+     * @param nodePath
      * @return node or <code>null</code>
      * @throws RepositoryException if an error occurs
      */
-    private NodeImpl getAclNode(NodeImpl controlledNode) throws RepositoryException {
+    private NodeImpl getAclNode(NodeImpl controlledNode, String nodePath) throws RepositoryException {
         NodeImpl aclNode = null;
-        if (ACLProvider.isAccessControlled(controlledNode)) {
-            aclNode = controlledNode.getNode(N_POLICY);
+        if (nodePath == null) {
+            if (ACLProvider.isRepoAccessControlled(controlledNode)) {
+                aclNode = controlledNode.getNode(N_REPO_POLICY);
+            }
+        } else {
+            if (ACLProvider.isAccessControlled(controlledNode)) {
+                aclNode = controlledNode.getNode(N_POLICY);
+            }
         }
         return aclNode;
     }
@@ -316,6 +345,19 @@ public class ACLEditor extends Protected
     }
 
     /**
+     *
+     * @return the new acl node used to store repository level privileges.
+     * @throws RepositoryException if an error occurs
+     */
+    private NodeImpl createRepoAclNode() throws RepositoryException {
+        NodeImpl root = (NodeImpl) session.getRootNode();
+        if (!root.isNodeType(NT_REP_REPO_ACCESS_CONTROLLABLE)) {
+            root.addMixin(NT_REP_REPO_ACCESS_CONTROLLABLE);
+        }
+        return addNode(root, N_REPO_POLICY, NT_REP_ACL);
+    }
+
+    /**
      * Create a unique valid name for the Permission nodes to be save.
      *
      * @param node a name for the child is resolved

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java Fri Sep 30 14:03:11 2011
@@ -43,6 +43,7 @@ import javax.jcr.Session;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryManager;
 import javax.jcr.query.QueryResult;
+import javax.jcr.security.AccessControlEntry;
 import javax.jcr.security.AccessControlList;
 import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.AccessControlPolicy;
@@ -130,12 +131,27 @@ public class ACLProvider extends Abstrac
     public AccessControlPolicy[] getEffectivePolicies(Path absPath, CompiledPermissions permissions) throws ItemNotFoundException, RepositoryException {
         checkInitialized();
 
-        NodeImpl targetNode = (NodeImpl) session.getNode(session.getJCRPath(absPath));
-        NodeImpl node = getNode(targetNode, isAcItem(targetNode));
+        NodeImpl targetNode;
         List<AccessControlList> acls = new ArrayList<AccessControlList>();
+        if (absPath == null) {
+            targetNode = (NodeImpl) session.getRootNode();
+            if (isRepoAccessControlled(targetNode)) {
+                if (permissions.grants(targetNode.getPrimaryPath(), Permission.READ_AC)) {
+                    // retrieve the entries for the access controlled node
+                    List<AccessControlEntry> entries = entryCollector.collectEntries(null, new EntryFilterImpl(null, (NodeId) null, session));
+                    acls.add(new UnmodifiableAccessControlList(entries));
+                } else {
+                    throw new AccessDeniedException("Access denied at " + targetNode.getPath());
+                }
+            }
+        } else {
+            targetNode = (NodeImpl) session.getNode(session.getJCRPath(absPath));
+            NodeImpl node = getNode(targetNode, isAcItem(targetNode));
+
+            // collect all ACLs effective at node
+            collectAcls(node, permissions, acls);
+        }
 
-        // collect all ACLs effective at node
-        collectAcls(node, permissions, acls);
         // if no effective ACLs are present -> add a default, empty acl.
         if (acls.isEmpty()) {
             // no access control information can be retrieved for the specified
@@ -332,7 +348,7 @@ public class ACLProvider extends Abstrac
      * controlled if it is of node type
      * {@link AccessControlConstants#NT_REP_ACCESS_CONTROLLABLE "rep:AccessControllable"}
      * and if it has a child node named
-     * {@link AccessControlConstants#N_POLICY "rep:ACL"}.
+     * {@link AccessControlConstants#N_POLICY}.
      *
      * @param node the node to be tested
      * @return <code>true</code> if the node is access controlled and has a
@@ -343,6 +359,23 @@ public class ACLProvider extends Abstrac
         return node.hasNode(N_POLICY) && node.isNodeType(NT_REP_ACCESS_CONTROLLABLE);
     }
 
+
+    /**
+     * Test if the given node is access controlled. The node is access
+     * controlled if it is of node type
+     * {@link AccessControlConstants#NT_REP_REPO_ACCESS_CONTROLLABLE "rep:RepoAccessControllable"}
+     * and if it has a child node named
+     * {@link AccessControlConstants#N_REPO_POLICY}.
+     *
+     * @param node the node to be tested
+     * @return <code>true</code> if the node is access controlled and has a
+     * rep:policy child; <code>false</code> otherwise.
+     * @throws RepositoryException if an error occurs
+     */
+    static boolean isRepoAccessControlled(NodeImpl node) throws RepositoryException {
+        return node.hasNode(N_REPO_POLICY) && node.isNodeType(NT_REP_REPO_ACCESS_CONTROLLABLE);
+    }
+
     /**
      * Returns the given <code>targetNode</code> unless the node itself stores
      * access control information in which case it's nearest non-ac-parent is

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -130,7 +130,19 @@ class ACLTemplate extends AbstractACLTem
      * @throws RepositoryException if an error occurs
      */
     ACLTemplate(NodeImpl aclNode) throws RepositoryException {
-        super((aclNode != null) ? aclNode.getParent().getPath() : null, (aclNode != null) ? aclNode.getSession().getValueFactory() : null);
+        this(aclNode, ((aclNode != null) ? aclNode.getParent().getPath() : null));
+    }
+
+    /**
+     * Create a {@link ACLTemplate} that is used to edit an existing ACL
+     * node.
+     *
+     * @param aclNode node
+     * @param path The path as exposed by "@link JackrabbitAccessControlList#getPath()}
+     * @throws RepositoryException if an error occurs
+     */
+    ACLTemplate(NodeImpl aclNode, String path) throws RepositoryException {
+        super(path, (aclNode != null) ? aclNode.getSession().getValueFactory() : null);
         if (aclNode == null || !NT_REP_ACL.equals(((NodeTypeImpl)aclNode.getPrimaryNodeType()).getQName())) {
             throw new IllegalArgumentException("Node must be of type 'rep:ACL'");
         }
@@ -315,6 +327,10 @@ class ACLTemplate extends AbstractACLTem
         } else if (!principalMgr.hasPrincipal(principal.getName())) {
             throw new AccessControlException("Principal " + principal.getName() + " does not exist.");
         }
+
+        if (path == null && restrictions != null && !restrictions.isEmpty()) {
+            throw new AccessControlException("Repository level policy does not support restrictions.");
+        }
     }
 
     /**
@@ -346,7 +362,7 @@ class ACLTemplate extends AbstractACLTem
      * @see JackrabbitAccessControlList#getRestrictionNames()
      */
     public String[] getRestrictionNames() {
-        return new String[] {jcrRepGlob};
+        return (path == null) ? new String[0] : new String[] {jcrRepGlob};
     }
 
     /**
@@ -420,21 +436,26 @@ class ACLTemplate extends AbstractACLTem
         private Entry(Principal principal, Privilege[] privileges, boolean allow, Map<String,Value> restrictions)
                 throws RepositoryException {
             super(principal, privileges, allow, restrictions);
-            Value glob = getRestrictions().get(P_GLOB);
-            if (glob != null) {
-                pattern = GlobPattern.create(path, glob.getString());
-            } else {
-                pattern = GlobPattern.create(path);
-            }
+            pattern = calculatePattern();
         }
 
         private Entry(Entry base, Privilege[] newPrivileges, boolean isAllow) throws RepositoryException {
             super(base, newPrivileges, isAllow);
-            Value glob = getRestrictions().get(P_GLOB);
-            if (glob != null) {
-                pattern = GlobPattern.create(path, glob.getString());
+            pattern = calculatePattern();
+        }
+
+        private GlobPattern calculatePattern() throws RepositoryException {
+            if (path == null) {
+                return null; // no pattern for repo-level aces.
             } else {
-                pattern = GlobPattern.create(path);
+                GlobPattern p;
+                Value glob = getRestrictions().get(P_GLOB);
+                if (glob != null) {
+                    p = GlobPattern.create(path, glob.getString());
+                } else {
+                    p = GlobPattern.create(path);
+                }
+                return p;
             }
         }
         
@@ -453,7 +474,7 @@ class ACLTemplate extends AbstractACLTem
          * @return
          */
         boolean matches(String jcrPath) {
-            return pattern.matches(jcrPath);
+            return pattern != null && pattern.matches(jcrPath);
         }
 
         @Override

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CompiledPermissionsImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CompiledPermissionsImpl.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CompiledPermissionsImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/CompiledPermissionsImpl.java Fri Sep 30 14:03:11 2011
@@ -87,7 +87,8 @@ class CompiledPermissionsImpl extends Ab
         }
     }
 
-    private Result buildResult(NodeImpl node, boolean isExistingNode, boolean isAcItem, EntryFilterImpl filter) throws RepositoryException {
+    private Result buildResult(NodeImpl node, boolean isExistingNode,
+                               boolean isAcItem, EntryFilterImpl filter) throws RepositoryException {
         // retrieve all ACEs at path or at the direct ancestor of path that
         // apply for the principal names.
         NodeImpl n = ACLProvider.getNode(node, isAcItem);
@@ -108,6 +109,7 @@ class CompiledPermissionsImpl extends Ab
         PrivilegeBits parentDenyBits = PrivilegeBits.getInstance();
 
         String parentPath = Text.getRelativeParent(filter.getPath(), 1);
+        NodeId nodeId = (node == null) ? null : node.getNodeId();
 
         while (entries.hasNext()) {
             ACLTemplate.Entry ace = (ACLTemplate.Entry) entries.next();
@@ -120,7 +122,7 @@ class CompiledPermissionsImpl extends Ab
             parent path.
             */
             PrivilegeBits entryBits = ace.getPrivilegeBits();
-            boolean isLocal = isExistingNode && ace.isLocal(node.getNodeId());
+            boolean isLocal = isExistingNode && ace.isLocal(nodeId);
             boolean matchesParent = (!isLocal && ace.matches(parentPath));
             if (matchesParent) {
                 if (ace.isAllow()) {
@@ -188,6 +190,11 @@ class CompiledPermissionsImpl extends Ab
         return buildResult(node, existingNode, isAcItem, new EntryFilterImpl(principalNames, absPath, session));
     }
 
+    @Override
+    protected Result buildRepositoryResult() throws RepositoryException {
+        return buildResult(null, true, false, new EntryFilterImpl(principalNames, session.getQPath("/"), session));
+    }
+
     /**
      * @see AbstractCompiledPermissions#getPrivilegeManagerImpl()
      */

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/EntryCollector.java Fri Sep 30 14:03:11 2011
@@ -121,13 +121,25 @@ public class EntryCollector extends Acce
         LinkedList<AccessControlEntry> userAces = new LinkedList<AccessControlEntry>();
         LinkedList<AccessControlEntry> groupAces = new LinkedList<AccessControlEntry>();
 
-        NodeId next = node.getNodeId();
-        while (next != null) {
-            List<AccessControlEntry> entries = getEntries(next);
-            if (!entries.isEmpty() && filter != null) {
-                filter.filterEntries(entries, userAces, groupAces);
+        if (node == null) {
+            // repository level permissions
+            NodeImpl root = (NodeImpl) systemSession.getRootNode();
+            if (ACLProvider.isRepoAccessControlled(root)) {
+                NodeImpl aclNode = root.getNode(N_REPO_POLICY);
+                List<AccessControlEntry> entries = new ACLTemplate(aclNode).getEntries();
+                if (!entries.isEmpty() && filter != null) {
+                    filter.filterEntries(entries, userAces, groupAces);
+                }
+            }
+        } else {
+            NodeId next = node.getNodeId();
+            while (next != null) {
+                List<AccessControlEntry> entries = getEntries(next);
+                if (!entries.isEmpty() && filter != null) {
+                    filter.filterEntries(entries, userAces, groupAces);
+                }
+                next = getParentId(next);
             }
-            next = getParentId(next);
         }
         
         List<AccessControlEntry> entries = new ArrayList<AccessControlEntry>(userAces.size() + groupAces.size());

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java Fri Sep 30 14:03:11 2011
@@ -243,6 +243,16 @@ public class CombinedProvider extends Ab
             return res;
         }
 
+        @Override
+        protected Result buildRepositoryResult() throws RepositoryException {
+            Result res = null;
+            for (AbstractCompiledPermissions acp : cPermissions) {
+                Result other = acp.getResult(null);
+                res = (res == null) ? other : res.combine(other);
+            }
+            return res;
+        }
+
         /**
          * @see AbstractCompiledPermissions#getPrivilegeManagerImpl()
          */

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java Fri Sep 30 14:03:11 2011
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.security.authorization.principalbased;
 
+import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.security.AccessControlEntry;
 import javax.jcr.security.AccessControlException;
 import javax.jcr.security.Privilege;
@@ -335,6 +336,10 @@ public class ACLEditor extends Protected
      * @throws RepositoryException
      */
     private void checkProtectsNode(String nodePath) throws RepositoryException {
+        if (nodePath == null) {
+            // TODO: JCR-2774
+            throw new UnsupportedRepositoryOperationException("JCR-2774");
+        }
         if (session.nodeExists(nodePath)) {
             NodeImpl n = (NodeImpl) session.getNode(nodePath);
             if (n.isNodeType(NT_REP_ACL) || n.isNodeType(NT_REP_ACE)) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java Fri Sep 30 14:03:11 2011
@@ -169,6 +169,12 @@ public class ACLProvider extends Abstrac
      * @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#getEffectivePolicies(org.apache.jackrabbit.spi.Path,org.apache.jackrabbit.core.security.authorization.CompiledPermissions)
      */
     public AccessControlPolicy[] getEffectivePolicies(Path absPath, CompiledPermissions permissions) throws ItemNotFoundException, RepositoryException {
+        if (absPath == null) {
+            // TODO: JCR-2774
+            log.warn("TODO: JCR-2774 - Repository level permissions.");
+            return new AccessControlPolicy[0];
+        }
+
         String jcrPath = session.getJCRPath(absPath);
         String pName = ISO9075.encode(session.getJCRName(ACLTemplate.P_NODE_PATH));
         int ancestorCnt = absPath.getAncestorCount();
@@ -387,6 +393,13 @@ public class ACLProvider extends Abstrac
             return buildResult(jcrPath, isAcItem);
         }
 
+        @Override
+        protected Result buildRepositoryResult() throws RepositoryException {
+            log.warn("TODO: JCR-2774 - Repository level permissions.");
+            PrivilegeManagerImpl pm = getPrivilegeManagerImpl();
+            return new Result(Permission.NONE, Permission.NONE, PrivilegeBits.EMPTY, PrivilegeBits.EMPTY);        
+        }
+
         /**
          * @see AbstractCompiledPermissions#getPrivilegeManagerImpl()
          */

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java Fri Sep 30 14:03:11 2011
@@ -146,6 +146,15 @@ public class SimpleAccessManager extends
     /**
      * {@inheritDoc}
      */
+    public void checkRepositoryPermission(int permissions) throws AccessDeniedException, RepositoryException {
+        if (!isGranted((ItemId) null, permissions)) {
+            throw new AccessDeniedException("Access denied");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public boolean isGranted(ItemId id, int permissions) throws RepositoryException {
         checkInitialized();
         if (system) {
@@ -294,13 +303,15 @@ public class SimpleAccessManager extends
      */
     @Override
     protected void checkValidNodePath(String absPath) throws PathNotFoundException, RepositoryException {
-        Path path = resolver.getQPath(absPath);
-        if (!path.isAbsolute()) {
-            throw new RepositoryException("Absolute path expected. Found: " + absPath);
-        }
+        if (absPath != null) {
+            Path path = resolver.getQPath(absPath);
+            if (!path.isAbsolute()) {
+                throw new RepositoryException("Absolute path expected. Found: " + absPath);
+            }
 
-        if (hierMgr.resolveNodePath(path) == null) {
-            throw new PathNotFoundException(absPath);
+            if (hierMgr.resolveNodePath(path) == null) {
+                throw new PathNotFoundException(absPath);
+            }
         }
     }
 

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -494,6 +494,12 @@ public class UserAccessControlProvider e
         }
 
         @Override
+        protected Result buildRepositoryResult() throws RepositoryException {
+            log.warn("TODO: JCR-2774 - Repository level permissions.");
+            return new Result(Permission.NONE, Permission.NONE, PrivilegeBits.EMPTY, PrivilegeBits.EMPTY);
+        }
+
+        @Override
         protected PrivilegeManagerImpl getPrivilegeManagerImpl() throws RepositoryException {
             return (PrivilegeManagerImpl) ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager();
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/session/SessionContext.java Fri Sep 30 14:03:11 2011
@@ -16,10 +16,6 @@
  */
 package org.apache.jackrabbit.core.session;
 
-import javax.jcr.NamespaceException;
-import javax.jcr.RepositoryException;
-import javax.jcr.ValueFactory;
-
 import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
 import org.apache.jackrabbit.core.HierarchyManager;
 import org.apache.jackrabbit.core.ItemManager;
@@ -36,6 +32,7 @@ import org.apache.jackrabbit.core.nodety
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.observation.ObservationManagerImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
+import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeManagerImpl;
 import org.apache.jackrabbit.core.state.SessionItemStateManager;
 import org.apache.jackrabbit.core.value.ValueFactoryImpl;
@@ -45,6 +42,13 @@ import org.apache.jackrabbit.spi.commons
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 
+import javax.jcr.AccessDeniedException;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ValueFactory;
+
 /**
  * Component context of a session. This class keeps track of the internal
  * components associated with a session.
@@ -87,6 +91,12 @@ public class SessionContext implements N
     private final PrivilegeManager privilegeManager;
 
     /**
+     * The namespace registry exposed for this session context that includes
+     * permission checks.
+     */
+    private final NamespaceRegistry nsRegistry;
+
+    /**
      * The workspace of this session
      */
     private final WorkspaceImpl workspace;
@@ -132,6 +142,7 @@ public class SessionContext implements N
         this.itemValidator = new ItemValidator(this);
         this.nodeTypeManager = new NodeTypeManagerImpl(this);
         this.privilegeManager = new PrivilegeManagerImpl(repositoryContext.getPrivilegeRegistry(), session);
+        this.nsRegistry = new PermissionAwareNamespaceRegistry();
         this.workspace = new WorkspaceImpl(this, workspaceConfig);
     }
 
@@ -239,6 +250,16 @@ public class SessionContext implements N
         return privilegeManager;
     }
 
+   /**
+     * Returns a namespace registry instance which asserts that the editing
+     * session is allowed to modify the namespace registry.
+     *
+     * @return
+     */
+    public NamespaceRegistry getNamespaceRegistry() {
+        return nsRegistry;
+    }
+
     /**
      * Returns the workspace of this session.
      *
@@ -339,4 +360,41 @@ public class SessionContext implements N
         return session + ":\n" + itemManager + "\n" + itemStateManager;
     }
 
+    //--------------------------------------------------------------------------
+    /**
+     * Permission aware namespace registry implementation that makes sure that
+     * modifications of the namespace registry are only allowed if the editing
+     * session has the corresponding permissions.
+     */
+    private class PermissionAwareNamespaceRegistry implements NamespaceRegistry {
+
+        private final NamespaceRegistry nsRegistry = repositoryContext.getNamespaceRegistry();        
+
+        public void registerNamespace(String prefix, String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+            session.getAccessManager().checkRepositoryPermission(Permission.NAMESPACE_MNGMT);
+            nsRegistry.registerNamespace(prefix, uri);
+        }
+
+        public void unregisterNamespace(String prefix) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+            session.getAccessManager().checkRepositoryPermission(Permission.NAMESPACE_MNGMT);
+            nsRegistry.unregisterNamespace(prefix);
+        }
+
+        public String[] getPrefixes() throws RepositoryException {
+            return nsRegistry.getPrefixes();
+        }
+
+        public String[] getURIs() throws RepositoryException {
+            return nsRegistry.getURIs();
+        }
+
+        public String getURI(String prefix) throws NamespaceException, RepositoryException {
+            return nsRegistry.getURI(prefix);
+        }
+
+        public String getPrefix(String uri) throws NamespaceException, RepositoryException {
+            return nsRegistry.getPrefix(uri);
+        }
+    }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/AccessControlImporter.java Fri Sep 30 14:03:11 2011
@@ -130,8 +130,7 @@ public class AccessControlImporter exten
             return false;
         }
 
-        if (AccessControlConstants.N_POLICY.equals(protectedParent.getQName())
-                && protectedParent.isNodeType(AccessControlConstants.NT_REP_ACL)) {
+        if (isPolicyNode(protectedParent)) {
             acl = getACL(protectedParent.getParent().getPath());
             if (acl == null) {
                 log.warn("AccessControlImporter cannot be started: no ACL for {}.", protectedParent.getParent().getPath());
@@ -297,6 +296,12 @@ public class AccessControlImporter exten
         }
     }
 
+    private static boolean isPolicyNode(NodeImpl node) throws RepositoryException {
+        Name nodeName = node.getQName();
+        return (AccessControlConstants.N_POLICY.equals(nodeName) || AccessControlConstants.N_REPO_POLICY.equals(nodeName))
+                && node.isNodeType(AccessControlConstants.NT_REP_ACL);
+    }
+
     private static void checkDefinition(NodeInfo nInfo, Name expName, Name expNodeTypeName) throws ConstraintViolationException {
         if (expName != null && !expName.equals(nInfo.getName())) {
             // illegal name

Modified: jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd Fri Sep 30 14:03:11 2011
@@ -554,6 +554,10 @@
   mixin
   + rep:policy (rep:Policy) protected IGNORE
 
+[rep:RepoAccessControllable]
+  mixin
+  + rep:repoPolicy (rep:Policy) protected IGNORE
+
 [rep:Policy]
   abstract
 

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/authorization/PrivilegeManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/authorization/PrivilegeManagerTest.java?rev=1177668&r1=1177667&r2=1177668&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/authorization/PrivilegeManagerTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/security/authorization/PrivilegeManagerTest.java Fri Sep 30 14:03:11 2011
@@ -21,6 +21,7 @@ import org.apache.jackrabbit.core.Sessio
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
 import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 
 import javax.jcr.NamespaceException;
@@ -71,7 +72,12 @@ public class PrivilegeManagerTest extend
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_WRITE)));
+        // including repo-level operation privileges
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NAMESPACE_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_WORKSPACE_MANAGEMENT.toString())));
         assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_PRIVILEGE_MANAGEMENT)));
+
         assertTrue(l.isEmpty());
     }
 
@@ -96,14 +102,18 @@ public class PrivilegeManagerTest extend
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_WRITE)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_WRITE)));
+        // including repo-level operation privileges
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NAMESPACE_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_WORKSPACE_MANAGEMENT.toString())));
         assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_PRIVILEGE_MANAGEMENT)));
+        
         assertTrue(l.isEmpty());
 
         l = new ArrayList<Privilege>(Arrays.asList(p.getDeclaredAggregatePrivileges()));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_READ)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_WRITE)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_WRITE)));
-        assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_PRIVILEGE_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_READ_ACCESS_CONTROL)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT)));
@@ -111,6 +121,12 @@ public class PrivilegeManagerTest extend
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_RETENTION_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_VERSION_MANAGEMENT)));
         assertTrue(l.remove(privilegeMgr.getPrivilege(Privilege.JCR_NODE_TYPE_MANAGEMENT)));
+        // including repo-level operation privileges
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NAMESPACE_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(NameConstants.JCR_WORKSPACE_MANAGEMENT.toString())));
+        assertTrue(l.remove(privilegeMgr.getPrivilege(PrivilegeRegistry.REP_PRIVILEGE_MANAGEMENT)));
+        
         assertTrue(l.isEmpty());
     }
 

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=1177668&r1=1177667&r2=1177668&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 Fri Sep 30 14:03:11 2011
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.core.secur
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -286,4 +285,4 @@ public abstract class AbstractEntryTest 
         assertEquals(testRestrictions, entryRestrictions);
 
     }
-}
\ No newline at end of file
+}