Author: angela Date: Fri Feb 18 21:24:10 2011 New Revision: 1072154 URL: http://svn.apache.org/viewvc?rev=1072154&view=rev Log: JCR-2887 : Split PrivilegeRegistry in a per-session manager instance and a repository level registry [work in progress] Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java (with props) jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManagerTest.java - copied, changed from r1066459, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistryTest.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SystemSession.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AMContext.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/DefaultAccessManager.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.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/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/ACLTemplate.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/principalbased/ACLProvider.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/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/test/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplateTest.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/AbstractNodeTypeManagementTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractWriteTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlListTest.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/TestAll.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplateTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EntryTest.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/NamespaceRegistryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java Fri Feb 18 21:24:10 2011 @@ -324,6 +324,18 @@ public class NamespaceRegistryImpl imple eventChannel.setListener(this); } + /** + * Returns true if the specified uri is one of the reserved + * URIs defined in this registry. + * + * @param uri The URI to test. + * @return true if the specified uri is reserved; + * false otherwise. + */ + public boolean isReservedURI(String uri) { + return reservedURIs.contains(uri); + } + //-------------------------------------------------------< StringIndex >-- /** @@ -457,7 +469,6 @@ public class NamespaceRegistryImpl imple return uriToPrefix.keySet().toArray(new String[uriToPrefix.keySet().size()]); } - //---------------------------------------------------< NamespaceRegistry > /** * {@inheritDoc} */ Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryContext.java Fri Feb 18 21:24:10 2011 @@ -23,6 +23,7 @@ import org.apache.jackrabbit.core.id.Nod import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.security.JackrabbitSecurityManager; +import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry; import org.apache.jackrabbit.core.state.ItemStateCacheFactory; import org.apache.jackrabbit.core.version.InternalVersionManagerImpl; import org.apache.jackrabbit.util.Timer; @@ -52,6 +53,11 @@ public class RepositoryContext { private NodeTypeRegistry nodeTypeRegistry; /** + * The privilege registry for this repository. + */ + private PrivilegeRegistry privilegeRegistry; + + /** * The internal version manager of this repository. */ private InternalVersionManagerImpl internalVersionManager; @@ -167,6 +173,25 @@ public class RepositoryContext { } /** + * Returns the privilege registry of this repository. + * + * @return the privilege registry of this repository. + */ + public PrivilegeRegistry getPrivilegeRegistry() { + return privilegeRegistry; + } + + /** + * Sets the privilege registry of this repository. + * + * @param privilegeRegistry + */ + void setPrivilegeRegistry(PrivilegeRegistry privilegeRegistry) { + assert privilegeRegistry != null; + this.privilegeRegistry = privilegeRegistry; + } + + /** * Returns the internal version manager of this repository. * * @return internal version manager Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Fri Feb 18 21:24:10 2011 @@ -96,6 +96,7 @@ import org.apache.jackrabbit.core.retent import org.apache.jackrabbit.core.retention.RetentionRegistryImpl; import org.apache.jackrabbit.core.security.JackrabbitSecurityManager; import org.apache.jackrabbit.core.security.authentication.AuthContext; +import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry; import org.apache.jackrabbit.core.security.authentication.token.TokenBasedAuthentication; import org.apache.jackrabbit.core.security.simple.SimpleSecurityManager; import org.apache.jackrabbit.core.cache.CacheManager; @@ -298,6 +299,7 @@ public class RepositoryImpl extends Abst // create registries context.setNamespaceRegistry(createNamespaceRegistry()); context.setNodeTypeRegistry(createNodeTypeRegistry()); + context.setPrivilegeRegistry(new PrivilegeRegistry(context.getNamespaceRegistry(), context.getFileSystem())); // Create item state cache manager context.setItemStateCacheFactory( Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java Fri Feb 18 21:24:10 2011 @@ -349,6 +349,7 @@ public class SessionImpl extends Abstrac this, subject, context.getHierarchyManager(), + context.getPrivilegeManager(), this, wspName); return repositoryContext.getSecurityManager().getAccessManager(this, ctx); 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=1072154&r1=1072153&r2=1072154&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 Feb 18 21:24:10 2011 @@ -36,7 +36,7 @@ import org.apache.jackrabbit.core.securi import org.apache.jackrabbit.core.security.AccessManager; import org.apache.jackrabbit.core.security.SystemPrincipal; import org.apache.jackrabbit.core.security.authorization.AccessControlProvider; -import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry; +import org.apache.jackrabbit.core.security.authorization.PrivilegeManager; import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager; import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.spi.Path; @@ -128,10 +128,7 @@ class SystemSession extends SessionImpl */ private class SystemAccessManager extends AbstractAccessControlManager implements AccessManager { - private final PrivilegeRegistry privilegeRegistry; - SystemAccessManager() { - privilegeRegistry = new PrivilegeRegistry(SystemSession.this); } //----------------------------------------------------< AccessManager > @@ -244,11 +241,11 @@ class SystemSession extends SessionImpl } /** - * @see AbstractAccessControlManager#getPrivilegeRegistry() + * @see AbstractAccessControlManager#getPrivilegeManager() */ - protected PrivilegeRegistry getPrivilegeRegistry() - throws RepositoryException { - return privilegeRegistry; + @Override + protected PrivilegeManager getPrivilegeManager() throws RepositoryException { + return context.getPrivilegeManager(); } /** @@ -283,7 +280,7 @@ class SystemSession extends SessionImpl public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException { checkValidNodePath(absPath); - return new Privilege[] {getPrivilegeRegistry().getPrivilege(Privilege.JCR_ALL)}; + return new Privilege[] {getPrivilegeManager().getPrivilege(Privilege.JCR_ALL)}; } /** 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=1072154&r1=1072153&r2=1072154&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 Feb 18 21:24:10 2011 @@ -53,6 +53,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.PrivilegeManager; import org.apache.jackrabbit.core.session.SessionContext; import org.apache.jackrabbit.core.state.ItemStateCacheFactory; import org.apache.jackrabbit.core.state.LocalItemStateManager; @@ -544,6 +545,17 @@ public class WorkspaceImpl extends Abstr return retentionRegistry; } + /** + * Return the PrivilegeManager. + * + * @return + * @throws RepositoryException + */ + public PrivilegeManager getPrivilegeManager() throws RepositoryException { + sanityCheck(); + return context.getPrivilegeManager(); + } + //------------------------------------------------------------< Workspace > /** * {@inheritDoc} Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AMContext.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AMContext.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AMContext.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AMContext.java Fri Feb 18 21:24:10 2011 @@ -18,6 +18,7 @@ package org.apache.jackrabbit.core.secur import org.apache.jackrabbit.core.HierarchyManager; import org.apache.jackrabbit.core.fs.FileSystem; +import org.apache.jackrabbit.core.security.authorization.PrivilegeManager; import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import javax.jcr.Session; @@ -56,6 +57,11 @@ public class AMContext { private final HierarchyManager hierMgr; /** + * The privilege manager + */ + private final PrivilegeManager privilegeMgr; + + /** * name and path resolver for resolving JCR name/path strings to internal * Name/Path objects (and vice versa). */ @@ -74,6 +80,7 @@ public class AMContext { * @param session the session. * @param subject subject whose access rights should be reflected * @param hierMgr hierarchy manager + * @param privilegeMgr privilege manager * @param resolver name and path resolver * @param workspaceName workspace name */ @@ -82,6 +89,7 @@ public class AMContext { Session session, Subject subject, HierarchyManager hierMgr, + PrivilegeManager privilegeMgr, NamePathResolver resolver, String workspaceName) { this.physicalHomeDir = physicalHomeDir; @@ -89,6 +97,7 @@ public class AMContext { this.session = session; this.subject = subject; this.hierMgr = hierMgr; + this.privilegeMgr = privilegeMgr; this.resolver = resolver; this.workspaceName = workspaceName; } @@ -140,6 +149,15 @@ public class AMContext { } /** + * Returns the privilege manager + * + * @return the privilege manager + */ + public PrivilegeManager getPrivilegeManager() { + return privilegeMgr; + } + + /** * Returns the namespace resolver * * @return the namespace resolver 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=1072154&r1=1072153&r2=1072154&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 Feb 18 21:24:10 2011 @@ -20,7 +20,7 @@ import org.apache.jackrabbit.api.securit import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy; import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter; import org.apache.jackrabbit.core.security.authorization.Permission; -import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry; +import org.apache.jackrabbit.core.security.authorization.PrivilegeManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +53,7 @@ public abstract class AbstractAccessCont checkValidNodePath(absPath); // return all known privileges everywhere. - return getPrivilegeRegistry().getRegisteredPrivileges(); + return getPrivilegeManager().getRegisteredPrivileges(); } /** @@ -63,7 +63,7 @@ public abstract class AbstractAccessCont throws AccessControlException, RepositoryException { checkInitialized(); - return getPrivilegeRegistry().getPrivilege(privilegeName); + return getPrivilegeManager().getPrivilege(privilegeName); } /** @@ -164,10 +164,10 @@ public abstract class AbstractAccessCont protected abstract void checkPermission(String absPath, int permission) throws AccessDeniedException, PathNotFoundException, RepositoryException; /** - * @return the privilege registry + * @return the privilege manager * @throws RepositoryException If another error occurs. */ - protected abstract PrivilegeRegistry getPrivilegeRegistry() throws RepositoryException; + protected abstract PrivilegeManager getPrivilegeManager() throws RepositoryException; /** * Tests if the given absPath is absolute and points to an existing node. 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=1072154&r1=1072153&r2=1072154&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 Feb 18 21:24:10 2011 @@ -25,6 +25,7 @@ import org.apache.jackrabbit.core.securi import org.apache.jackrabbit.core.security.authorization.AccessControlProvider; import org.apache.jackrabbit.core.security.authorization.CompiledPermissions; import org.apache.jackrabbit.core.security.authorization.Permission; +import org.apache.jackrabbit.core.security.authorization.PrivilegeManager; import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry; import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager; import org.apache.jackrabbit.spi.Name; @@ -88,8 +89,6 @@ public class DefaultAccessManager extend private AccessControlEditor editor; - private PrivilegeRegistry privilegeRegistry; - /** * the workspace access */ @@ -101,6 +100,11 @@ public class DefaultAccessManager extend private HierarchyManager hierMgr; /** + * The privilege manager + */ + private PrivilegeManager privilegeManager; + + /** * The permissions that apply for the principals, that are present with * the session subject this manager has been created for. * TODO: if the users group-membership gets modified the compiledPermissions @@ -139,7 +143,7 @@ public class DefaultAccessManager extend } wspAccess = new WorkspaceAccess(wspAccessManager, isSystemOrAdmin(amContext.getSession())); - privilegeRegistry = new PrivilegeRegistry(resolver); + privilegeManager = amContext.getPrivilegeManager(); if (acProvider != null) { editor = acProvider.getEditor(amContext.getSession()); @@ -273,7 +277,7 @@ public class DefaultAccessManager extend log.debug("No privileges passed -> allowed."); return true; } else { - int privs = PrivilegeRegistry.getBits(privileges); + int privs = privilegeManager.getBits(privileges); Path p = resolver.getQPath(absPath); return (compiledPermissions.getPrivileges(p) | ~privs) == -1; } @@ -288,7 +292,7 @@ public class DefaultAccessManager extend int bits = compiledPermissions.getPrivileges(resolver.getQPath(absPath)); return (bits == PrivilegeRegistry.NO_PRIVILEGE) ? new Privilege[0] : - privilegeRegistry.getPrivileges(bits); + privilegeManager.getPrivileges(bits); } /** @@ -410,7 +414,7 @@ public class DefaultAccessManager extend log.debug("No privileges passed -> allowed."); return true; } else { - int privs = PrivilegeRegistry.getBits(privileges); + int privs = privilegeManager.getBits(privileges); Path p = resolver.getQPath(absPath); CompiledPermissions perms = acProvider.compilePermissions(principals); try { @@ -434,7 +438,7 @@ public class DefaultAccessManager extend int bits = perms.getPrivileges(resolver.getQPath(absPath)); return (bits == PrivilegeRegistry.NO_PRIVILEGE) ? new Privilege[0] : - privilegeRegistry.getPrivileges(bits); + privilegeManager.getPrivileges(bits); } finally { perms.close(); } @@ -478,12 +482,12 @@ public class DefaultAccessManager extend } /** - * @see AbstractAccessControlManager#getPrivilegeRegistry() + * @see AbstractAccessControlManager#getPrivilegeManager() */ @Override - protected PrivilegeRegistry getPrivilegeRegistry() throws RepositoryException { + protected PrivilegeManager getPrivilegeManager() throws RepositoryException { checkInitialized(); - return privilegeRegistry; + return privilegeManager; } //------------------------------------------------------------< private >--- Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java?rev=1072154&r1=1072153&r2=1072154&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java Fri Feb 18 21:24:10 2011 @@ -28,6 +28,7 @@ import javax.jcr.security.Privilege; import org.apache.jackrabbit.core.ItemImpl; import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.WorkspaceImpl; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; import org.apache.jackrabbit.core.security.SystemPrincipal; @@ -61,9 +62,6 @@ public abstract class AbstractAccessCont protected ObservationManager observationMgr; protected NamePathResolver resolver; - protected int privAll; - protected int privRead; - private boolean initialized; protected AbstractAccessControlProvider() { @@ -97,8 +95,8 @@ public abstract class AbstractAccessCont public boolean grants(Path absPath, int permissions) { return true; } - public int getPrivileges(Path absPath) { - return privAll; + public int getPrivileges(Path absPath) throws RepositoryException { + return ((WorkspaceImpl) session.getWorkspace()).getPrivilegeManager().getBits(new String[] {Privilege.JCR_ALL}); } public boolean canReadAll() { return true; @@ -133,7 +131,7 @@ public abstract class AbstractAccessCont if (isAcItem(absPath)) { return PrivilegeRegistry.NO_PRIVILEGE; } else { - return privRead; + return ((WorkspaceImpl) session.getWorkspace()).getPrivilegeManager().getBits(new String[] {Privilege.JCR_READ}); } } public boolean canReadAll() { @@ -221,9 +219,6 @@ public abstract class AbstractAccessCont observationMgr = systemSession.getWorkspace().getObservationManager(); resolver = (NamePathResolver) systemSession; - privAll = PrivilegeRegistry.getBits(new Privilege[] {session.getAccessControlManager().privilegeFromName(Privilege.JCR_ALL)}); - privRead = PrivilegeRegistry.getBits(new Privilege[] {session.getAccessControlManager().privilegeFromName(Privilege.JCR_READ)}); - initialized = true; } 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=1072154&r1=1072153&r2=1072154&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 Fri Feb 18 21:24:10 2011 @@ -111,7 +111,7 @@ public abstract class AccessControlEntry } this.principal = principal; this.privileges = privileges; - this.privilegeBits = PrivilegeRegistry.getBits(privileges); + this.privilegeBits = getPrivilegeManager().getBits(privileges); this.allow = isAllow; if (restrictions == null) { @@ -143,7 +143,7 @@ public abstract class AccessControlEntry } this.principal = base.principal; this.privileges = privileges; - this.privilegeBits = PrivilegeRegistry.getBits(privileges); + this.privilegeBits = getPrivilegeManager().getBits(privileges); this.allow = isAllow; if (base.restrictions == null) { @@ -204,6 +204,11 @@ public abstract class AccessControlEntry protected abstract ValueFactory getValueFactory(); /** + * @return The privilege manager in use. + */ + protected abstract PrivilegeManager getPrivilegeManager(); + + /** * Build the hash code. * * @return the hash code. Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java?rev=1072154&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java Fri Feb 18 21:24:10 2011 @@ -0,0 +1,380 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.security.authorization; + +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.spi.Name; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.AccessDeniedException; +import javax.jcr.NamespaceException; +import javax.jcr.RepositoryException; +import javax.jcr.security.AccessControlException; +import javax.jcr.security.Privilege; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * PrivilegeManager... + */ +public final class PrivilegeManager implements PrivilegeRegistry.Listener { + + /** + * logger instance + */ + private static final Logger log = LoggerFactory.getLogger(PrivilegeManager.class); + + private static final Privilege[] EMPTY_ARRAY = new Privilege[0]; + + /** + * + */ + private final PrivilegeRegistry registry; + + /** + * The name resolver used to determine the correct privilege + * {@link javax.jcr.security.Privilege#getName() name} depending on the sessions namespace + * mappings. + */ + private final NameResolver resolver; + + /** + * Per instance map containing the namespace aware representation of + * the registered privileges. + */ + private final Map cache; + + public PrivilegeManager(PrivilegeRegistry registry, NameResolver nameResolver) { + this.registry = registry; + this.resolver = nameResolver; + this.cache = new HashMap(); + + // listen to privilege registration (due to weak references no explicit + // stop-listening call required + registry.addListener(this); + } + + /** + * Returns all registered privileges. + * + * @return all registered privileges. + */ + public Privilege[] getRegisteredPrivileges() throws RepositoryException { + PrivilegeRegistry.PrivilegeDefinition[] allDefs = registry.getAll(); + if (allDefs.length != cache.size()) { + synchronized (cache) { + for (PrivilegeRegistry.PrivilegeDefinition def : allDefs) { + if (!cache.containsKey(def.getName())) { + cache.put(def.getName(), new PrivilegeImpl(def)); + } + } + } + } + return cache.values().toArray(new Privilege[allDefs.length]); + } + + /** + * Returns the privilege with the specified privilegeName. + * + * @param privilegeName Name of the principal. + * @return the privilege with the specified privilegeName. + * @throws javax.jcr.security.AccessControlException If no privilege with the given name exists. + * @throws javax.jcr.RepositoryException If another error occurs. + */ + public Privilege getPrivilege(String privilegeName) throws AccessControlException, RepositoryException { + Name name = resolver.getQName(privilegeName); + return getPrivilege(name); + } + + /** + * Register a new custom privilege with the specified characteristics.

+ * + *

The current implementation has the following limitations and constraints:

+ * + * + * + * Please note
+ * Custom privilege(s) will not be enforced for any kind of repository + * operations. Those are exclusively covered by the built-in privileges. + * This also implies that the {@link Permission}s are not effected by + * custom privileges.

+ * Applications making use of the custom privilege(s) are in charge of + * asserting whether the privileges are granted/denied according to their + * application specific needs. + * + * @param privilegeName The name of the new custom privilege. + * @param isAbstract Boolean flag indicating if the privilege is abstract. + * @param declaredAggregateNames An array of privilege names referring to + * registered privileges being aggregated by this new custom privilege. + * In case of a non aggregate privilege an empty array should be passed. + * @return the new privilege. + * @throws AccessDeniedException If the session this manager has been created + * for isn't the administrator. + * @throws RepositoryException If the privilege could not be registered due + * to constraint violations or if persisting the custom privilege fails. + */ + public Privilege registerPrivilege(String privilegeName, boolean isAbstract, + String[] declaredAggregateNames) + throws AccessDeniedException, RepositoryException { + boolean isAdmin = (resolver instanceof SessionImpl) ? ((SessionImpl) resolver).isAdmin() : false; + if (!isAdmin) { + throw new AccessDeniedException("Registering privileges is only allowed to administrator."); + } + + Name name = resolver.getQName(privilegeName); + Set daNames; + if (declaredAggregateNames == null || declaredAggregateNames.length == 0) { + daNames = Collections.emptySet(); + } else { + daNames = new HashSet(declaredAggregateNames.length); + for (String declaredAggregateName : declaredAggregateNames) { + daNames.add(resolver.getQName(declaredAggregateName)); + } + } + registry.registerDefinition(name, isAbstract, daNames); + + return getPrivilege(privilegeName); + } + + /** + * @param privileges An array of privileges. + * @return The privilege bits. + * @throws AccessControlException If the specified array is null, empty + * or if it contains an unregistered privilege. + * @see #getPrivileges(int) + */ + public int getBits(Privilege[] privileges) throws AccessControlException { + if (privileges == null || privileges.length == 0) { + throw new AccessControlException("Privilege array is empty or null."); + } + int bits = PrivilegeRegistry.NO_PRIVILEGE; + for (Privilege priv : privileges) { + if (priv instanceof PrivilegeImpl) { + bits |= ((PrivilegeImpl) priv).definition.getBits(); + } else { + throw new AccessControlException("Unknown privilege '" + priv.getName() + "'."); + } + } + return bits; + } + + /** + * + * @param privilegeNames + * @return + * @throws AccessControlException + * @throws RepositoryException + */ + public int getBits(String[] privilegeNames) throws AccessControlException { + if (privilegeNames == null || privilegeNames.length == 0) { + throw new AccessControlException("Privilege name array is null or empty."); + } + int bits = PrivilegeRegistry.NO_PRIVILEGE; + for (String privName : privilegeNames) { + try { + PrivilegeRegistry.PrivilegeDefinition def = registry.get(resolver.getQName(privName)); + if (def == null) { + throw new AccessControlException("Unknown privilege name '" + privName + "'."); + } else { + bits |= def.getBits(); + } + } catch (NamespaceException e) { + throw new AccessControlException("Invalid privilege name '" + privName + "'."); + } catch (IllegalNameException e) { + throw new AccessControlException("Invalid privilege name '" + privName + "'."); + } + } + return bits; + } + + /** + * Returns an array of registered Privileges. If the specified + * bits represent a single registered privilege the returned array + * contains a single element. Otherwise the returned array contains the + * individual registered privileges that are combined in the given + * bits. If bits does not match to any registered + * privilege an empty array will be returned. + * + * @param bits Privilege bits as obtained from {@link #getBits(Privilege[])}. + * @return Array of Privileges that are presented by the given + * bits or an empty array if bits cannot be + * resolved to registered Privileges. + * @see #getBits(Privilege[]) + * @see #getBits(String[]) + */ + public Privilege[] getPrivileges(int bits) { + Name[] names = registry.getNames(bits); + if (names.length == 0) { + return EMPTY_ARRAY; + } else { + Privilege[] privs = new Privilege[names.length]; + for (int i = 0; i < names.length; i++) { + try { + privs[i] = getPrivilege(names[i]); + } catch (RepositoryException e) { + log.error("Internal error: invalid privilege name " + names[i].toString()); + } + } + return privs; + } + } + + private Privilege getPrivilege(Name name) throws AccessControlException, RepositoryException { + Privilege privilege; + synchronized (cache) { + if (cache.containsKey(name)) { + privilege = cache.get(name); + } else { + PrivilegeRegistry.PrivilegeDefinition def = registry.get(name); + if (def != null) { + privilege = new PrivilegeImpl(def); + cache.put(name, privilege); + } else { + throw new AccessControlException("Unknown privilege " + resolver.getJCRName(name)); + } + } + } + return privilege; + } + + //-----------------------------------------< PrivilegeRegistry.Listener >--- + + /** + * @see PrivilegeRegistry.Listener#privilegeRegistered(org.apache.jackrabbit.spi.Name) + */ + public void privilegeRegistered(Name privilegeName) { + // force recalculation of jcr:all privilege + synchronized (cache) { + cache.remove(NameConstants.JCR_ALL); + } + } + + //----------------------------------------------------------< Privilege >--- + /** + * Simple wrapper used to provide an public representation of the + * registered internal privileges properly exposing the JCR name. + */ + private class PrivilegeImpl implements Privilege { + + private final PrivilegeRegistry.PrivilegeDefinition definition; + + private final Privilege[] declaredAggregates; + private final Privilege[] aggregates; + + private PrivilegeImpl(PrivilegeRegistry.PrivilegeDefinition definition) throws RepositoryException { + this.definition = definition; + + Name[] aggrNames = definition.getDeclaredAggregateNames(); + if (aggrNames.length == 0) { + declaredAggregates = EMPTY_ARRAY; + aggregates = EMPTY_ARRAY; + } else { + declaredAggregates = new Privilege[aggrNames.length]; + for (int i = 0; i < aggrNames.length; i++) { + declaredAggregates[i] = getPrivilege(aggrNames[i]); + } + + Set aggr = new HashSet(); + for (Privilege decl : declaredAggregates) { + aggr.add(decl); + if (decl.isAggregate()) { + aggr.addAll(Arrays.asList(decl.getAggregatePrivileges())); + } + } + aggregates = aggr.toArray(new Privilege[aggr.size()]); + } + } + + /** + * @see Privilege#getName() + */ + public String getName() { + try { + return resolver.getJCRName(definition.getName()); + } catch (NamespaceException e) { + // should not occur -> return internal name representation. + return definition.getName().toString(); + } + } + + /** + * @see Privilege#isAbstract() + */ + public boolean isAbstract() { + return definition.isAbstract(); + } + + /** + * @see Privilege#isAggregate() + */ + public boolean isAggregate() { + return declaredAggregates.length > 0; + } + + /** + * @see Privilege#getDeclaredAggregatePrivileges() + */ + public Privilege[] getDeclaredAggregatePrivileges() { + return declaredAggregates; + } + + /** + * @see Privilege#getAggregatePrivileges() + */ + public Privilege[] getAggregatePrivileges() { + return aggregates; + } + + //---------------------------------------------------------< Object >--- + @Override + public String toString() { + return getName(); + } + + @Override + public int hashCode() { + return definition.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof PrivilegeImpl) { + PrivilegeImpl other = (PrivilegeImpl) obj; + return definition.equals(other.definition); + } + return false; + } + } +} \ No newline at end of file Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeManager.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL