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 2008/08/27 17:12:07 UTC

svn commit: r689499 [3/11] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/retention/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/sec...

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=689499&r1=689498&r2=689499&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 Wed Aug 27 08:12:04 2008
@@ -16,14 +16,11 @@
  */
 package org.apache.jackrabbit.core.security;
 
-import org.apache.jackrabbit.api.jsr283.security.AccessControlEntry;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlException;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
-import org.apache.jackrabbit.api.jsr283.security.Hold;
 import org.apache.jackrabbit.api.jsr283.security.Privilege;
-import org.apache.jackrabbit.api.jsr283.security.RetentionPolicy;
 import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.slf4j.Logger;
@@ -33,8 +30,6 @@
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.lock.LockException;
-import javax.jcr.version.VersionException;
 import java.security.Principal;
 
 /**
@@ -56,7 +51,17 @@
         checkValidNodePath(absPath);
 
         // return all known privileges everywhere.
-        return PrivilegeRegistry.getRegisteredPrivileges();
+        return getPrivilegeRegistry().getRegisteredPrivileges();
+    }
+
+    /**
+     * @see AccessControlManager#privilegeFromName(String)
+     */
+    public Privilege privilegeFromName(String privilegeName)
+            throws AccessControlException, RepositoryException {
+        checkInitialized();
+
+        return getPrivilegeRegistry().getPrivilege(privilegeName);
     }
 
     /**
@@ -66,12 +71,12 @@
      * @return always returns <code>null</code>.
      * @see AccessControlManager#getApplicablePolicies(String)
      */
-    public AccessControlPolicy getPolicy(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
+    public AccessControlPolicy[] getPolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
 
-        log.debug("Implementation does not provide applicable policies -> getPolicy() always returns null.");
-        return null;
+        log.debug("Implementation does not provide applicable policies -> getPolicy() always returns an empty array.");
+        return new AccessControlPolicy[0];
     }
 
     /**
@@ -88,7 +93,7 @@
         log.debug("Implementation does not provide applicable policies -> returning empty iterator.");
         return AccessControlPolicyIteratorAdapter.EMPTY;
     }
-    
+
     /**
      * Always throws <code>AccessControlException</code>
      *
@@ -98,99 +103,29 @@
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
 
-        throw new AccessControlException("AccessControlPolicy " + policy.getName() + " cannot be applied.");
+        throw new AccessControlException("AccessControlPolicy " + policy + " cannot be applied.");
     }
 
     /**
      * Always throws <code>AccessControlException</code>
      *
-     * @see AccessControlManager#removePolicy(String)
+     * @see AccessControlManager#removePolicy(String, AccessControlPolicy)
      */
-    public AccessControlPolicy removePolicy(String absPath) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
+    public void removePolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
 
         throw new AccessControlException("No AccessControlPolicy has been set through this API -> Cannot be removed.");
     }
 
-    /**
-     * Returns an empty array.
-     *
-     * @return always returns an empty array.
-     * @see AccessControlManager#getAccessControlEntries(String)
-     */
-    public AccessControlEntry[] getAccessControlEntries(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
-
-        return new AccessControlEntry[0];
-    }
 
+    //-------------------------------------< JackrabbitAccessControlManager >---
     /**
-     * Always throws <code>UnsupportedRepositoryOperationException</code>
-     *
-     * @see AccessControlManager#addAccessControlEntry(String, Principal, Privilege[])
+     * {@inheritDoc}
      */
-    public AccessControlEntry addAccessControlEntry(String absPath, Principal principal, Privilege[] privileges) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new UnsupportedRepositoryOperationException("Adding access control entry is not supported by this AccessControlManager (" + getClass().getName()+ ").");
-    }
-
-    /**
-     * Always throws <code>AccessControlException</code>
-     * 
-     * @see AccessControlManager#removeAccessControlEntry(String, AccessControlEntry)
-     */
-    public void removeAccessControlEntry(String absPath, AccessControlEntry ace) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new AccessControlException("Invalid access control entry, that has not been applied through this API.");
-    }
-
-    public Hold[] getHolds(String absPath) throws PathNotFoundException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
-    }
-
-    public Hold addHold(String absPath, String name, boolean isDeep) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
-    }
-
-    public void removeHold(String absPath, Hold hold) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
-    }
-
-    public RetentionPolicy getRetentionPolicy(String absPath) throws PathNotFoundException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
-
-    }
-
-    public void setRetentionPolicy(String absPath, RetentionPolicy retentionPolicy) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
-    }
-
-    public void removeRetentionPolicy(String absPath) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
-        throw new UnsupportedRepositoryOperationException("Retention & Hold are not supported by this AccessControlManager (" + getClass().getName()+ ").");
+    public AccessControlPolicy[] getApplicablePolicies(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
+        log.debug("Implementation does not provide applicable policies -> returning empty array.");        
+        return new AccessControlPolicy[0];
     }
 
     //--------------------------------------------------------------------------
@@ -215,6 +150,12 @@
     protected abstract void checkPrivileges(String absPath, int privileges) throws AccessDeniedException, PathNotFoundException, RepositoryException;
 
     /**
+     * @return the privilege registry
+     * @throws RepositoryException
+     */
+    protected abstract PrivilegeRegistry getPrivilegeRegistry() throws RepositoryException;
+
+    /**
      * Build a qualified path from the specified <code>absPath</code> and test
      * if it is really absolute and points to an existing node.
      *

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/CredentialsCallbackHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/CredentialsCallbackHandler.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/CredentialsCallbackHandler.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/CredentialsCallbackHandler.java Wed Aug 27 08:12:04 2008
@@ -16,10 +16,7 @@
  */
 package org.apache.jackrabbit.core.security;
 
-import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
-
 import javax.jcr.Credentials;
-import javax.jcr.Session;
 
 /**
  * A <code>CallbackHandlerImpl</code> ...
@@ -29,12 +26,6 @@
 public class CredentialsCallbackHandler extends org.apache.jackrabbit.core.security.authentication.CallbackHandlerImpl {
 
     public CredentialsCallbackHandler(Credentials credentials) {
-        super(credentials, null, null);
-    }
-
-    public CredentialsCallbackHandler(Credentials credentials,
-                                      Session session,
-                                      PrincipalProviderRegistry principalProviderRegistry) {
-        super(credentials, session, principalProviderRegistry);
+        super(credentials, null, null, null, null);
     }
 }

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=689499&r1=689498&r2=689499&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 Wed Aug 27 08:12:04 2008
@@ -16,14 +16,11 @@
  */
 package org.apache.jackrabbit.core.security;
 
-import org.apache.jackrabbit.api.jsr283.security.AccessControlEntry;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlException;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
-import org.apache.jackrabbit.api.jsr283.security.Hold;
 import org.apache.jackrabbit.api.jsr283.security.Privilege;
-import org.apache.jackrabbit.api.jsr283.security.RetentionPolicy;
 import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
 import org.apache.jackrabbit.core.HierarchyManager;
 import org.apache.jackrabbit.core.ItemId;
@@ -31,7 +28,6 @@
 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.PolicyTemplate;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
@@ -47,14 +43,13 @@
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.lock.LockException;
-import javax.jcr.version.VersionException;
 import javax.security.auth.Subject;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.Arrays;
 
 /**
  * The <code>DefaultAccessManager</code> controls access by evaluating access
@@ -81,6 +76,21 @@
 public class DefaultAccessManager extends AbstractAccessControlManager implements AccessManager {
 
     private static final Logger log = LoggerFactory.getLogger(DefaultAccessManager.class);
+    private static final CompiledPermissions NO_PERMISSION = new CompiledPermissions() {
+        public void close() {
+            //nop
+        }
+        public boolean grants(Path absPath, int permissions) {
+            // deny everything
+            return false;
+        }
+        public int getPrivileges(Path absPath) {
+            return PrivilegeRegistry.NO_PRIVILEGE;
+        }
+        public boolean canReadAll() {
+            return false;
+        }
+    };
 
     private boolean initialized;
 
@@ -92,6 +102,8 @@
 
     private AccessControlEditor editor;
 
+    private PrivilegeRegistry privilegeRegistry;
+
     /**
      * the workspace access
      */
@@ -105,6 +117,9 @@
     /**
      * 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
+     * TODO  should ev. be recalculated. currently those modifications are only
+     * TODO  reflected upon re-login to the repository.
      */
     private CompiledPermissions compiledPermissions;
 
@@ -134,30 +149,15 @@
         principals = (subject == null) ? Collections.EMPTY_SET : subject.getPrincipals();
 
         wspAccess = new WorkspaceAccess(wspAccessManager, isSystemOrAdmin(subject));
+        privilegeRegistry = new PrivilegeRegistry(resolver);
 
         if (acProvider != null) {
             editor = acProvider.getEditor(amContext.getSession());
             compiledPermissions = acProvider.compilePermissions(principals);
         } else {
-            // TODO: review expected default-permissions here.
             log.warn("No AccessControlProvider defined -> no access is granted.");
             editor = null;
-            compiledPermissions = new CompiledPermissions() {
-                public void close() {
-                    //nop
-                }
-                public boolean grants(Path absPath, int permissions) throws RepositoryException {
-                    // deny everything
-                    return false;
-                }
-                public int getPrivileges(Path absPath) throws RepositoryException {
-                    return 0;
-                }
-
-                public boolean canReadAll() throws RepositoryException {
-                    return false;
-                }
-            };
+            compiledPermissions = NO_PERMISSION;
         }
 
         initialized = true;
@@ -222,6 +222,9 @@
         }
     }
 
+    /**
+     * @see AccessManager#isGranted(Path, int)
+     */
     public boolean isGranted(Path absPath, int permissions) throws RepositoryException {
         checkInitialized();
         if (!absPath.isAbsolute()) {
@@ -230,6 +233,9 @@
         return compiledPermissions.grants(absPath, permissions);
     }
 
+    /**
+     * @see AccessManager#isGranted(Path, Name, int)
+     */
     public boolean isGranted(Path parentPath, Name childName, int permissions) throws RepositoryException {
         Path p = PathFactoryImpl.getInstance().create(parentPath, childName, true);
         return isGranted(p, permissions);
@@ -239,7 +245,6 @@
      * @see AccessManager#canRead(Path)
      */
     public boolean canRead(Path itemPath) throws RepositoryException {
-        Path path;
         if (compiledPermissions.canReadAll()) {
             return true;
         } else {
@@ -267,7 +272,7 @@
             log.debug("No privileges defined for hasPrivilege test.");
             return true;
         } else {
-            int privs = PrivilegeRegistry.getBits(privileges);
+            int privs = privilegeRegistry.getBits(privileges);
             return internalHasPrivileges(absPath, privs);
         }
     }
@@ -278,33 +283,37 @@
     public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
         checkInitialized();
         checkValidNodePath(absPath);
-        int privs = compiledPermissions.getPrivileges(resolver.getQPath(absPath));
-        return (privs == 0) ? new Privilege[0] : PrivilegeRegistry.getPrivileges(privs);
+        int bits = compiledPermissions.getPrivileges(resolver.getQPath(absPath));
+        return (bits == PrivilegeRegistry.NO_PRIVILEGE) ?
+                new Privilege[0] :
+                privilegeRegistry.getPrivileges(bits);
     }
 
     /**
-     * @see AccessControlManager#getPolicy(String)
+     * @see AccessControlManager#getPolicies(String)
      */
-    public AccessControlPolicy getPolicy(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
+    public AccessControlPolicy[] getPolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
 
-        AccessControlPolicy policy = null;
+        AccessControlPolicy[] policies;
         if (editor != null) {
-            policy = editor.getPolicyTemplate(absPath);
+            policies = editor.getPolicies(absPath);
+        } else {
+            policies = new AccessControlPolicy[0];
         }
-        return policy;
+        return policies;
     }
 
     /**
-     * @see AccessControlManager#getEffectivePolicy(String)
+     * @see AccessControlManager#getEffectivePolicies(String)
      */
-    public AccessControlPolicy getEffectivePolicy(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
+    public AccessControlPolicy[] getEffectivePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
 
         // TODO: acProvider may not retrieve the correct policy in case of transient modifications
-        return acProvider.getPolicy(getPath(absPath));
+        return acProvider.getEffectivePolicies(getPath(absPath));
     }
 
     /**
@@ -315,9 +324,11 @@
         checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
 
         if (editor != null) {
-            PolicyTemplate applicable = editor.editPolicyTemplate(absPath);
-            if (applicable != null) {
-                return new AccessControlPolicyIteratorAdapter(Collections.singletonList(applicable));
+            try {
+                AccessControlPolicy[] applicable = editor.editAccessControlPolicies(absPath);
+                return new AccessControlPolicyIteratorAdapter(Arrays.asList(applicable));
+            } catch (AccessControlException e) {
+                log.debug("No applicable policy at " + absPath);
             }
         }
         // no applicable policies -> return empty iterator.
@@ -329,148 +340,35 @@
      */
     public void setPolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        if (policy instanceof PolicyTemplate) {
-            checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-            if (editor == null) {
-                throw new UnsupportedRepositoryOperationException("Modification of AccessControlPolicies is not supported. ");
-            }
-            editor.setPolicyTemplate(absPath, (PolicyTemplate) policy);
-        } else {
-            throw new AccessControlException("Access control policy '" + policy + "' not applicable");
-        }
-    }
-
-    /**
-     * @see AccessControlManager#removePolicy(String)
-     */
-    public AccessControlPolicy removePolicy(String absPath) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-        if (editor == null) {
-            throw new UnsupportedRepositoryOperationException("Removal of AccessControlPolicies is not supported.");
-        }
-        return editor.removePolicyTemplate(absPath);
-    }
-
-    /**
-     * @see AccessControlManager#getAccessControlEntries(String)
-     */
-    public AccessControlEntry[] getAccessControlEntries(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
-
-        AccessControlEntry[] entries = new AccessControlEntry[0];
-        if (editor != null) {
-            entries = editor.getAccessControlEntries(absPath);
-        }
-        return entries;
-    }
-
-    /**
-     * @see AccessControlManager#getEffectiveAccessControlEntries(String)
-     */
-    public AccessControlEntry[] getEffectiveAccessControlEntries(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
-
-        return acProvider.getAccessControlEntries(getPath(absPath));
-    }
-
-    /**
-     * @see AccessControlManager#addAccessControlEntry(String, Principal, Privilege[])
-     */
-    public AccessControlEntry addAccessControlEntry(String absPath, Principal principal, Privilege[] privileges) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
-        checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-
         if (editor == null) {
-            throw new UnsupportedRepositoryOperationException("Adding access control entries is not supported.");
-        } else {
-            return editor.addAccessControlEntry(absPath, principal, privileges);
+            throw new UnsupportedRepositoryOperationException("Modification of AccessControlPolicies is not supported. ");
         }
+        editor.setPolicy(absPath, policy);
     }
 
     /**
-     * @see AccessControlManager#removeAccessControlEntry(String, AccessControlEntry)
+     * @see AccessControlManager#removePolicy(String, AccessControlPolicy)
      */
-    public void removeAccessControlEntry(String absPath, AccessControlEntry ace) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
+    public void removePolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
         checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
         if (editor == null) {
-            throw new UnsupportedRepositoryOperationException("Removal of access control entries is not supported.");
-        }
-        if (!editor.removeAccessControlEntry(absPath, ace)) {
-            throw new AccessControlException("AccessControlEntry " + ace + " has not been assigned though this API.");
+            throw new UnsupportedRepositoryOperationException("Removal of AccessControlPolicies is not supported.");
         }
+        editor.removePolicy(absPath, policy);
     }
 
-    /**
-     * @see AccessControlManager#getHolds(String)
-     */
-    public Hold[] getHolds(String absPath) throws PathNotFoundException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        // TODO: add implementation
-        return super.getHolds(absPath);
-    }
-
-    /**
-     * @see AccessControlManager#addHold(String, String, boolean)
-     */
-    public Hold addHold(String absPath, String name, boolean isDeep) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        // TODO: add implementation
-        return super.addHold(absPath, name, isDeep);
-    }
-
-    /**
-     * @see AccessControlManager#removeHold(String, Hold)
-     */
-    public void removeHold(String absPath, Hold hold) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        // TODO: add implementation
-        super.removeHold(absPath, hold);
-    }
-
-    /**
-     * @see AccessControlManager#getRetentionPolicy(String)
-     */
-    public RetentionPolicy getRetentionPolicy(String absPath) throws PathNotFoundException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
-        // TODO: add implementation
-        return super.getRetentionPolicy(absPath);
-    }
-
-    /**
-     * @see AccessControlManager#setRetentionPolicy(String, RetentionPolicy)
-     */
-    public void setRetentionPolicy(String absPath, RetentionPolicy retentionPolicy) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        // TODO: add implementation
-        super.setRetentionPolicy(absPath, retentionPolicy);
-    }
-
-    /**
-     * @see AccessControlManager#removeRetentionPolicy(String)
-     */
-    public void removeRetentionPolicy(String absPath) throws PathNotFoundException, AccessControlException, AccessDeniedException, UnsupportedRepositoryOperationException, LockException, VersionException, RepositoryException {
-        // TODO: add implementation
-        super.removeRetentionPolicy(absPath);
-    }
     //-------------------------------------< JackrabbitAccessControlManager >---
     /**
-     * @see JackrabbitAccessControlManager#editPolicy(String)
+     * @see JackrabbitAccessControlManager#getApplicablePolicies(Principal)
      */
-    public PolicyTemplate editPolicy(String absPath) throws AccessDeniedException, AccessControlException, RepositoryException {
-        checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
-        if (editor == null) {
-            throw new UnsupportedRepositoryOperationException("Editing of access control policies is not supported.");
-        }
-
-        return editor.editPolicyTemplate(absPath);
-    }
-
-    public PolicyTemplate editPolicy(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
+    public AccessControlPolicy[] getApplicablePolicies(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
         checkInitialized();
         if (editor == null) {
             throw new UnsupportedRepositoryOperationException("Editing of access control policies is not supported.");
         }
-        return editor.editPolicyTemplate(principal);
+        return editor.editAccessControlPolicies(principal);
     }
 
     //---------------------------------------< AbstractAccessControlManager >---
@@ -506,6 +404,14 @@
         }
     }
 
+    /**
+     * @see AbstractAccessControlManager#getPrivilegeRegistry()
+     */
+    protected PrivilegeRegistry getPrivilegeRegistry() throws RepositoryException {
+        checkInitialized();
+        return privilegeRegistry;
+    }
+
     //------------------------------------------------------------< private >---
     /**
      *
@@ -546,7 +452,7 @@
         private final WorkspaceAccessManager wspAccessManager;
 
         private final boolean isAdmin;
-        // TODO: entries must be cleared if access permission to wsp change.
+        // TODO: entries must be cleared if access permission to wsp changes.
         private final List allowed;
         private final List denied;
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitAccessControlManager.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitAccessControlManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitAccessControlManager.java Wed Aug 27 08:12:04 2008
@@ -18,10 +18,9 @@
 
 import org.apache.jackrabbit.api.jsr283.security.AccessControlException;
 import org.apache.jackrabbit.api.jsr283.security.AccessControlManager;
-import org.apache.jackrabbit.core.security.authorization.PolicyTemplate;
+import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
 
 import javax.jcr.AccessDeniedException;
-import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import java.security.Principal;
@@ -32,36 +31,19 @@
 public interface JackrabbitAccessControlManager extends AccessControlManager {
 
     /**
-     * Returns a policy template for the existing node at <code>absPath</code>.
-     * 
-     * @return policy template for the node at <code>absPath</code>.
-     * @throws PathNotFoundException if no node exists for the given
-     * <code>nodePath</code>.
-     * @throws AccessDeniedException if the session lacks
-     * <code>MODIFY_ACCESS_CONTROL</code> privilege for the <code>absPath</code>
-     * node.
-     * @throws AccessControlException if this implementation does not allow to
-     * edit the policy at <code>absPath</code> of if same other access
-     * control related exception occurs.
-     * @throws UnsupportedRepositoryOperationException if editing the policy
-     * is not supported.
-     * @throws RepositoryException if another error occurs.
-     */
-    PolicyTemplate editPolicy(String absPath) throws PathNotFoundException, AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException;
-
-    /**
-     * Returns a policy template for the specified <code>principal.</code>
+     * Returns the editable policies for the specified <code>principal</code>.
      *
-     * @return policy template for the specified <code>principal</code>.
+     * @return array of policies for the specified <code>principal</code>. Note
+     * that the policy object returned must reveal the path of the node where
+     * they can be applied later on.
      * @throws AccessDeniedException if the session lacks
      * <code>MODIFY_ACCESS_CONTROL</code> privilege.
-     * @throws AccessControlException if the specified principal does not exist,
-     * if this implementation does provide policy tempates for principals or
-     * if same other access control related exception occurs.
+     * @throws AccessControlException if the specified principal does not exist
+     * or if same other access control related exception occurs.
      * @throws UnsupportedRepositoryOperationException if editing the policy
      * is not supported.
      * @throws RepositoryException if another error occurs.
      */
-    PolicyTemplate editPolicy(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException;
+    AccessControlPolicy[] getApplicablePolicies(Principal principal) throws AccessDeniedException, AccessControlException, UnsupportedRepositoryOperationException, RepositoryException;
 
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java Wed Aug 27 08:12:04 2008
@@ -17,7 +17,7 @@
 package org.apache.jackrabbit.core.security.authentication;
 
 import org.apache.commons.collections.set.ListOrderedSet;
-import org.apache.jackrabbit.api.security.principal.PrincipalIterator;
+import org.apache.jackrabbit.api.jsr283.GuestCredentials;
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.api.security.user.Impersonation;
 import org.apache.jackrabbit.api.security.user.User;
@@ -47,19 +47,17 @@
 import java.util.Set;
 
 /**
- * This Abstract class provides the means for the common Authentication tasks,
- * within the Repository.<p />
- * It implements an authentication by User-ID / Password - Credentials
- * {@link SimpleCredentials}<p />
- * On successfull authentication it relates this credentials to principals
- * by the use of * the {@link PrincipalProvider} configured for this LoginModule<p />
- * Jackrabbit knows about two typs of Login, the one for its "own" Credentials and one
- * for Impersonation.<br>
- * {@link #login()}-method dispatches to
+ * <code>AbstractLoginModule</code> provides the means for the common
+ * authentication tasks within the Repository.
+ * <p/>
+ * On successfull authentication it associates the credentials to principals
+ * using the {@link PrincipalProvider} configured for this LoginModule<p />
+ * Jackrabbit distinguishes between Login and Impersonation dispatching the
+ * the correspoding Repository/Session methods to
  * {@link #authenticate(java.security.Principal, javax.jcr.Credentials)} and
- * {@link #impersonate(java.security.Principal, javax.jcr.Credentials)} for the
- * two cases for implemenations.<br>
- * This LoginModule imlements default behaviours for this methods.
+ * {@link #impersonate(java.security.Principal, javax.jcr.Credentials)}, respectively.
+ * <br>
+ * This LoginModule implements default behaviors for both methods.
  *
  * @see LoginModule
  */
@@ -67,12 +65,12 @@
 
     private static final Logger log = LoggerFactory.getLogger(AbstractLoginModule.class);
 
-    private static final String KEY_SIMPLE_CREDENTIALS = "org.apache.jackrabbit.credentials.simple";
+    private static final String KEY_CREDENTIALS = "org.apache.jackrabbit.credentials";
     private static final String KEY_LOGIN_NAME = "javax.security.auth.login.name";
 
     protected String adminId;
     protected String anonymousId;
-    protected String defaultUserId;
+    private String principalProviderClassName;
 
     private CallbackHandler callbackHandler;
     private boolean initialized;
@@ -90,7 +88,6 @@
      * <ul>
      * <li>{@link PrincipalManager} for group-membership resoultion</li>
      * <li>{@link PrincipalProvider} for user-{@link Principal} resolution.</li>
-     * <li>{@link LoginModuleConfig#PARAM_DEFAULT_USERID} option is evaluated</li>
      * <li>{@link LoginModuleConfig#PARAM_ADMIN_ID} option is evaluated</li>
      * <li>{@link LoginModuleConfig#PARAM_ANONYMOUS_ID} option is evaluated</li>
      * </ul>
@@ -112,18 +109,25 @@
      */
     public void initialize(Subject subject, CallbackHandler callbackHandler,
                            Map sharedState, Map options) {
+        // common jaas state variables
+        this.callbackHandler = callbackHandler;
+        this.subject = subject;
+        this.sharedState = sharedState;
+
+        // initialize the login module
         try {
             log.debug("Initalize LoginModule: ");
-            //Properties configProps = new Properties();
-            //configProps.putAll(options);
             RepositoryCallback repositoryCb = new RepositoryCallback();
             callbackHandler.handle(new Callback[]{repositoryCb});
 
-            // retrieve the principal-provider configured for this module
+            // retrieve the principal-provider configured for this module.
+            // if not configured -> retrieve the provider from the callback.
             PrincipalProviderRegistry registry = repositoryCb.getPrincipalProviderRegistry();
             if (options.containsKey(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS)) {
-                String providerName = (String) options.get(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS);
-                principalProvider = registry.getProvider(providerName);
+                principalProviderClassName = (String) options.get(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS);
+                principalProvider = registry.getProvider(principalProviderClassName);
+            } else if (principalProviderClassName != null) {
+                principalProvider = registry.getProvider(principalProviderClassName);
             }
             if (principalProvider == null) {
                 principalProvider = registry.getDefault();
@@ -133,23 +137,24 @@
             }
             log.debug("- PrincipalProvider -> '" + principalProvider.getClass().getName() + "'");
 
-            //call implementation for additional setup
+            // call implementation for additional setup
             doInit(callbackHandler, repositoryCb.getSession(), options);
 
+            // adminId: if not present in options -> retrieve from callback
             if (options.containsKey(LoginModuleConfig.PARAM_ADMIN_ID)) {
                 adminId = (String) options.get(LoginModuleConfig.PARAM_ADMIN_ID);
             }
+            if (adminId == null) {
+                adminId = repositoryCb.getAdminId();
+            }
+            // anonymousId: if not present in options -> retrieve from callback
             if (options.containsKey(LoginModuleConfig.PARAM_ANONYMOUS_ID)) {
                 anonymousId = (String) options.get(LoginModuleConfig.PARAM_ANONYMOUS_ID);
             }
-            if (options.containsKey(LoginModuleConfig.PARAM_DEFAULT_USERID)) {
-                defaultUserId = (String) options.get(LoginModuleConfig.PARAM_DEFAULT_USERID);
+            if (anonymousId == null) {
+                anonymousId = repositoryCb.getAnonymousId();
             }
 
-            //common jaas state variables
-            this.callbackHandler = callbackHandler;
-            this.subject = subject;
-
             //log config values for debug
             if (log.isDebugEnabled()) {
                 Iterator itr = options.keySet().iterator();
@@ -159,8 +164,6 @@
 
                 }
             }
-
-            this.sharedState = sharedState;
             initialized = (this.subject != null);
 
         } catch (Exception e) {
@@ -264,7 +267,7 @@
             return false;
         }
 
-        //check for availablity of Credentials;
+        // check for availablity of Credentials;
         Credentials creds = getCredentials();
         if (creds == null) {
             log.warn("No credentials available -> try default (anonymous) authentication.");
@@ -286,7 +289,7 @@
                 authenticated = authenticate(userPrincipal, creds);
             }
 
-            // process authenticated user or return false
+            // process authenticated user
             if (authenticated) {
                 if (creds instanceof SimpleCredentials) {
                     credentials = (SimpleCredentials) creds;
@@ -305,11 +308,11 @@
     /**
      * Method to commit the authentication process (phase 2).
      * <p/>
-     * <p> This method is called if the LoginContext's overall authentication
+     * This method is called if the LoginContext's overall authentication
      * succeeded (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL
      * LoginModules succeeded).
      * <p/>
-     * <p> If this LoginModule's own authentication attempt succeeded (checked
+     * If this LoginModule's own authentication attempt succeeded (checked
      * by retrieving the private state saved by the <code>login</code> method),
      * then this method associates relevant Principals and Credentials with the
      * <code>Subject</code> located in the <code>LoginModule</code>.  If this
@@ -317,12 +320,12 @@
      * removes/destroys any state that was originally saved.
      * <p/>
      * The login is considers as succeeded if the credentials field is set. If
-     * there is no principalstate. the login is considered as ignored.
+     * there is no principal set the login is considered as ignored.
      * <p/>
      * The implementation stores the principal associated to the UserID and all
      * the Groups it is member of. {@link PrincipalManager#getGroupMembership(Principal)}
      * An instance of (#link SimpleCredentials} containing only the UserID used
-     * to login is set to the Subject's public Credentials
+     * to login is set to the Subject's public Credentials.
      *
      * @return true if this method succeeded, or false if this
      *         <code>LoginModule</code> should be ignored.
@@ -339,7 +342,8 @@
             return false;
         }
 
-        subject.getPrincipals().addAll(getPrincipals());
+        Set principals = getPrincipals();
+        subject.getPrincipals().addAll(principals);
         subject.getPublicCredentials().add(credentials);
         return true;
     }
@@ -365,7 +369,7 @@
         if (!isInitialized()) {
             return false;
         } else {
-            sharedState.remove(KEY_SIMPLE_CREDENTIALS);
+            sharedState.remove(KEY_CREDENTIALS);
             callbackHandler = null;
             principal = null;
             credentials = null;
@@ -423,22 +427,6 @@
     }
 
     /**
-     * @return a Collection of principals that contains the current user
-     * principal and all groups it is member of.
-     */
-    protected Set getPrincipals() {
-        // use ListOrderedSet instead of Hashset in order to maintain the order
-        // of principals (as in the Subject).
-        Set principals = new ListOrderedSet();
-        principals.add(principal);
-        Iterator groups = principalProvider.getGroupMembership(principal);
-        while (groups.hasNext()) {
-            principals.add(groups.next());
-        }
-        return principals;
-    }
-
-    /**
      * Test if the current request is an Impersonation attempt. The default
      * implementation returns <code>true</code> if an
      * {@link #getImpersonatorSubject(Credentials) subject} for the
@@ -508,38 +496,41 @@
         return impersonator;
     }
 
-    //------------------------------------------------------------< private >---
     /**
      * Method tries to resolve the {@link Credentials} used for login. It takes
-     * into account, that an authentication-extension of an allready
-     * authenticate {@link Subject} could take place<p/> Therefore the
-     * credentials are searchred for in the following search-order: <ol> <li>
-     * Ask CallbackHandler for Credentials with use of {@link
+     * authentication-extension of an already authenticated {@link Subject} into
+     * accout.
+     * <p/>
+     * Therefore the credentials are searchred as follows:
+     * <ol>
+     * <li>Test if the shared state contains credentials.</li>
+     * <li>Ask CallbackHandler for Credentials with using a {@link
      * CredentialsCallback}. Expects {@link CredentialsCallback#getCredentials}
-     * to return an instance of {@link SimpleCredentials}.</li> <li> Ask the
-     * Subject for its public credentials {@link Subject#getPublicCredentials(Class)},
-     * with {@link SimpleCredentials#getClass()} as argument.<p> This enables to
-     * preauthenticate the Subject.</li> </ol> NOTE: While the method signiture
-     * works with {@link Credentials} it actually searches and returns {@link
-     * SimpleCredentials}.<br> This is done to allow implementations to make use
-     * of this abstract class, without beeing bound to a {@link Credentials}
-     * implementation.
+     * to return an instance of {@link Credentials}.</li>
+     * <li>Ask the Subject for its public <code>SimpleCredentials</code> see
+     * {@link Subject#getPublicCredentials(Class)}, thus enabling to
+     * preauthenticate the Subject.</li>
+     * </ol>
      *
      * @return Credentials or null if not found
      * @see #login()
      */
-    private Credentials getCredentials() {
-        SimpleCredentials credentials = null;
-        if (sharedState.containsKey(KEY_SIMPLE_CREDENTIALS)) {
-            credentials = (SimpleCredentials) sharedState.get(KEY_SIMPLE_CREDENTIALS);
+    protected Credentials getCredentials() {
+        Credentials credentials = null;
+        if (sharedState.containsKey(KEY_CREDENTIALS)) {
+            credentials = (Credentials) sharedState.get(KEY_CREDENTIALS);
         } else {
             try {
                 CredentialsCallback callback = new CredentialsCallback();
                 callbackHandler.handle(new Callback[]{callback});
                 Credentials creds = callback.getCredentials();
-                if (null != creds && creds instanceof SimpleCredentials) {
-                    credentials = (SimpleCredentials) creds;
-                    sharedState.put(KEY_SIMPLE_CREDENTIALS, credentials);
+                if (null != creds) {
+                    if (creds instanceof SimpleCredentials) {
+                       credentials = (SimpleCredentials) creds;
+                    } else if (creds instanceof GuestCredentials) {
+                       credentials = (GuestCredentials) creds;
+                    }
+                    sharedState.put(KEY_CREDENTIALS, credentials);
                 }
             } catch (UnsupportedCallbackException e) {
                 log.warn("Credentials-Callback not supported try Name-Callback");
@@ -549,21 +540,24 @@
         }
         // ask subject if still no credentials
         if (null == credentials) {
+            // try if subject contains SimpleCredentials
             Set preAuthCreds = subject.getPublicCredentials(SimpleCredentials.class);
             if (!preAuthCreds.isEmpty()) {
-                credentials = (SimpleCredentials) subject.getPublicCredentials(SimpleCredentials.class).iterator().next();
+                credentials = (Credentials) preAuthCreds.iterator().next();
             }
         }
         return credentials;
     }
 
     /**
-     * Method supports tries to acquire a UserID in the follwing order: <ol>
+     * Method supports tries to acquire a UserID in the follwing order:
+     * <ol>
+     * <li>If passed credentials are {@link GuestCredentials} the anonymous user id
+     * is returned.</li>
      * <li>Try to access it from the {@link Credentials} via {@link
      * SimpleCredentials#getUserID()}</li>
      * <li>Ask CallbackHandler for User-ID with use of {@link NameCallback}.</li>
      * <li>Test if the 'sharedState' contains a login name.</li>
-     * <li>Test a defaultUserID is present in the LoginModule configuration.</li>
      * <li>Fallback: return the anonymous UserID.</li>
      * </ol>
      *
@@ -572,10 +566,12 @@
      * described above.
      * @see #login()
      */
-    private String getUserID(Credentials credentials) {
+    protected String getUserID(Credentials credentials) {
         String userId = null;
         if (credentials != null) {
-            if (credentials instanceof SimpleCredentials) {
+            if (credentials instanceof GuestCredentials) {
+                userId = anonymousId;
+            } else if (credentials instanceof SimpleCredentials) {
                 userId = ((SimpleCredentials) credentials).getUserID();
             } else {
                 try {
@@ -593,17 +589,11 @@
             userId = (String) sharedState.get(KEY_LOGIN_NAME);
         }
 
-        // still no userId -> if a defaultUserID has been specified or return
-        // the anonymous UserID.
+        // still no userId -> anonymousID if its has been defined.
         // TODO: check again if correct when used with 'extendedAuth'
         if (userId == null) {
-            if (defaultUserId != null) {
-                userId = defaultUserId;
-            } else {
-                userId = anonymousId;
-            }
+            userId = anonymousId;
         }
-
         return userId;
     }
 
@@ -613,36 +603,41 @@
      * @param credentials
      * @return true if is anonymous
      */
-    private boolean isAnonymous(Credentials credentials) {
-        // TODO: check again. former simple-login-module treated 'null' as anonymous and had no anonymous config entry.
-        String userId = getUserID(credentials);
-        if (anonymousId == null) {
-            return userId == null;
+    protected boolean isAnonymous(Credentials credentials) {
+        if (credentials instanceof GuestCredentials) {
+            return true;
         } else {
-            return anonymousId.equals(userId);
+            // TODO: review again. former simple-login-module treated 'null' as anonymous (probably wrong).
+            String userId = getUserID(credentials);
+            return (anonymousId == null) ? userId == null : anonymousId.equals(userId);
         }
     }
 
+
     /**
      * Authentication process associates a Principal to Credentials<br>
-     * This method resolves the Principal for the given Credentials. If there
-     * is no Principal for the Credentials, the LoginModule should be ignored.<p>
-     * This Abstract implementation uses the {@link PrincipalProvider} configured
-     * for it, to resolve this association.
-     * It takes the {@link PrincipalProvider#findPrincipals(String)} for the User-ID
-     * resolved by  {@link #getUserID(Credentials)}
+     * This method resolves the Principal for the given Credentials. If no valid
+     * Principal can be determined, the LoginModule should be ignored.
      *
      * @param credentials
-     * @return if credentials are associated to one or null if none found
+     * @return the principal associated with the given credentials or <code>null</code>.
      */
-    private Principal getPrincipal(Credentials credentials) {
-        Principal principal = null;
-        String userId = isAnonymous(credentials) ? anonymousId : getUserID(credentials);
-        PrincipalIterator res = principalProvider.findPrincipals(userId, PrincipalManager.SEARCH_TYPE_NOT_GROUP);
-        if (res.hasNext()) {
-            principal = res.nextPrincipal();
-        } // no matching principal -> return null
-        return principal;
+    protected abstract Principal getPrincipal(Credentials credentials);
+
+    /**
+     * @return a Collection of principals that contains the current user
+     * principal and all groups it is member of.
+     */
+    protected Set getPrincipals() {
+        // use ListOrderedSet instead of Hashset in order to maintain the order
+        // of principals (as in the Subject).
+        Set principals = new ListOrderedSet();
+        principals.add(principal);
+        Iterator groups = principalProvider.getGroupMembership(principal);
+        while (groups.hasNext()) {
+            principals.add(groups.next());
+        }
+        return principals;
     }
 
     //--------------------------------------------------------------------------
@@ -683,21 +678,20 @@
     }
 
     /**
-     * Returns the default user id.
+     * Returns the configured name of the principal provider class.
      *
-     * @return default user id
+     * @return name of the principal provider class.
      */
-    public String getDefaultUserId() {
-        return defaultUserId;
+    public String getPrincipalProvider() {
+        return principalProviderClassName;
     }
 
     /**
-     * Sets the default user id to be used when no login credentials
-     * are presented.
+     * Sets the configured name of the principal provider class
      *
-     * @param defaultUserId default user id
+     * @param principalProvider Name of the principal provider class.
      */
-    public void setDefaultUserId(String defaultUserId) {
-        this.defaultUserId = defaultUserId;
+    public void setPrincipalProvider(String principalProvider) {
+        this.principalProviderClassName = principalProvider;
     }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java Wed Aug 27 08:12:04 2008
@@ -74,9 +74,11 @@
     }
 
     /**
-     * @param credentials to authenticate
-     * @param subject subject to extend authentication
-     * @param session Session to pass to the login-modules
+     *
+     * @param credentials
+     * @param subject
+     * @param session
+     * @param principalProviderRegistry
      * @return context of for authentication and log-out
      * @throws RepositoryException in case neither an <code>JAASContext</code>
      * nor a <code>LocalContext</code> can be successfully created.
@@ -84,10 +86,12 @@
     public AuthContext getAuthContext(Credentials credentials,
                                       Subject subject,
                                       Session session,
-                                      PrincipalProviderRegistry principalProviderRegistry)
+                                      PrincipalProviderRegistry principalProviderRegistry,
+                                      String adminId,
+                                      String anonymousId)
             throws RepositoryException {
 
-        CallbackHandler cbHandler = new CallbackHandlerImpl(credentials, session, principalProviderRegistry);
+        CallbackHandler cbHandler = new CallbackHandlerImpl(credentials, session, principalProviderRegistry, adminId, anonymousId);
 
         if (isJAAS()) {
             return new JAASAuthContext(appName, cbHandler, subject);

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CallbackHandlerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CallbackHandlerImpl.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CallbackHandlerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CallbackHandlerImpl.java Wed Aug 27 08:12:04 2008
@@ -48,17 +48,23 @@
     private final Session session;
     private final Credentials credentials;
     private final PrincipalProviderRegistry principalProviderRegistry;
+    private final String adminId;
+    private final String anonymousId;
 
     /**
      * Instanciate with the data needed to handle callbacks
+     *
      * @param credentials
      * @param session
      */
     public CallbackHandlerImpl(Credentials credentials, Session session,
-                               PrincipalProviderRegistry principalProviderRegistry) {
+                               PrincipalProviderRegistry principalProviderRegistry,
+                               String adminId, String anonymousId) {
         this.credentials = credentials;
         this.session = session;
         this.principalProviderRegistry = principalProviderRegistry;
+        this.adminId = adminId;
+        this.anonymousId = anonymousId;
 
         if (session == null) {
             log.debug("Session is null -> CallbackHandler won't be able to handle RepositoryCallback.");
@@ -90,8 +96,11 @@
                 if (session == null || principalProviderRegistry == null) {
                     throw new UnsupportedCallbackException(callback);
                 }
-                ((RepositoryCallback) callback).setSession(session);
-                ((RepositoryCallback) callback).setPrincipalProviderRegistry(principalProviderRegistry);
+                RepositoryCallback rcb = (RepositoryCallback) callback;
+                rcb.setSession(session);
+                rcb.setPrincipalProviderRegistry(principalProviderRegistry);
+                rcb.setAdminId(adminId);
+                rcb.setAnonymousId(anonymousId);
             } else if (credentials != null && credentials instanceof SimpleCredentials) {
                 SimpleCredentials simpleCreds = (SimpleCredentials) credentials;
                 if (callback instanceof NameCallback) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/DefaultLoginModule.java Wed Aug 27 08:12:04 2008
@@ -33,6 +33,7 @@
 import javax.security.auth.login.LoginException;
 import java.security.Principal;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * The <code>DefaultLoginModule</code> authenticates Credentials related to
@@ -49,6 +50,7 @@
 
     private static final Logger log = LoggerFactory.getLogger(AbstractLoginModule.class);
 
+    private User user;
     private UserManager userManager;
 
     /**
@@ -69,17 +71,44 @@
         }
     }
 
-    protected Authentication getAuthentication(Principal principal, Credentials creds) throws RepositoryException {
-        Authorizable authrz = userManager.getAuthorizable(principal);
-        if (authrz == null || authrz.isGroup()) {
-            return null;
+    /**
+     * Resolves the userID from the given credentials and obtains the
+     * principal from the User object associated with the given userID.
+     * If the the userID cannot be resolved to a User or if obtaining the
+     * principal fail, <code>null</code> is returned.
+     *
+     * @param credentials
+     * @return a user principal or <code>null</code>.
+     * @see AbstractLoginModule#getPrincipal(Credentials)
+     */
+    protected Principal getPrincipal(Credentials credentials) {
+        Principal principal = null;
+        String userId = getUserID(credentials);
+        try {
+            Authorizable authrz = userManager.getAuthorizable(userId);
+            if (authrz != null && !authrz.isGroup()) {
+                user = (User) authrz;
+                principal = user.getPrincipal();
+            }
+        } catch (RepositoryException e) {
+            // should not get here
+            log.warn("Error while retrieving principal.", e.getMessage());
         }
-        Authentication authentication = new SimpleCredentialsAuthentication((User) authrz);
-        if (authentication.canHandle(creds)) {
-            return authentication;
-        } else {
-            return null;
+        return principal;
+    }
+
+    /**
+     * @see AbstractLoginModule#getAuthentication(Principal, Credentials)
+     */
+    protected Authentication getAuthentication(Principal principal, Credentials creds) throws RepositoryException {
+        if (user != null) {
+            Authentication authentication = new SimpleCredentialsAuthentication(user);
+            if (authentication.canHandle(creds)) {
+                return authentication;
+            }
         }
+        // no valid user or authencation could not handle the given creds.
+        return null;
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/RepositoryCallback.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/RepositoryCallback.java?rev=689499&r1=689498&r2=689499&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/RepositoryCallback.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/RepositoryCallback.java Wed Aug 27 08:12:04 2008
@@ -29,6 +29,8 @@
 
     private Session session;
     private PrincipalProviderRegistry principalProviderRegistry;
+    private String adminId;
+    private String anonymousId;
 
     public void setSession(Session session) {
         this.session = session;
@@ -45,4 +47,20 @@
     public PrincipalProviderRegistry getPrincipalProviderRegistry() {
         return principalProviderRegistry;
     }
+
+    public String getAdminId() {
+        return adminId;
+    }
+
+    public void setAdminId(String adminId) {
+        this.adminId = adminId;
+    }
+
+    public String getAnonymousId() {
+        return anonymousId;
+    }
+
+    public void setAnonymousId(String anonymousId) {
+        this.anonymousId = anonymousId;
+    }
 }

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=689499&r1=689498&r2=689499&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 Wed Aug 27 08:12:04 2008
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.core.security.authorization;
 
-import org.apache.jackrabbit.api.jsr283.security.AccessControlEntry;
-import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicy;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.SystemPrincipal;
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
@@ -26,7 +24,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.jcr.ItemNotFoundException;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.observation.ObservationManager;
@@ -38,34 +35,27 @@
 /**
  * <code>AbstractAccessControlProvider</code>...
  */
-public abstract class AbstractAccessControlProvider implements AccessControlProvider {
+public abstract class AbstractAccessControlProvider implements AccessControlProvider, AccessControlUtils {
 
     private static Logger log = LoggerFactory.getLogger(AbstractAccessControlProvider.class);
 
-    private final String policyName;
-    private final String policyDesc;
+    public static final String PARAM_OMIT_DEFAULT_PERMISSIONS = "omit-default-permission";
 
     /**
-     * Returns the system session this provider has been created for.
+     * the system session this provider has been created for.
      */
     protected SessionImpl session;
     protected ObservationManager observationMgr;
     protected NamePathResolver resolver;
 
     private boolean initialized;
-    private Principal everyone;
 
     protected AbstractAccessControlProvider() {
-        this(AbstractAccessControlProvider.class.getName() + ": default Policy", null);
-    }
-
-    protected AbstractAccessControlProvider(String defaultPolicyName, String defaultPolicyDesc) {
-        policyName = defaultPolicyName;
-        policyDesc = defaultPolicyDesc;
     }
 
     /**
-     *
+     * Throws <code>IllegalStateException</code> if the provider has not
+     * been initialized or has been closed.
      */
     protected void checkInitialized() {
         if (!initialized) {
@@ -74,65 +64,38 @@
     }
 
     /**
-     * Simple test if the specified path points to an item that defines AC
-     * information.
-     * 
-     * @param absPath
-     * @return
-     */
-    protected abstract boolean isAcItem(Path absPath) throws RepositoryException;
-
-    /**
-     *
-     * @param principals
-     * @return
-     */
-    protected static boolean isAdminOrSystem(Set principals) {
-        for (Iterator it = principals.iterator(); it.hasNext();) {
-            Principal p = (Principal) it.next();
-            if (p instanceof AdminPrincipal || p instanceof SystemPrincipal) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     *
-     * @return
+     * Returns compiled permissions for the administrator i.e. permissions
+     * that grants everything and returns {@link PrivilegeRegistry#ALL}
+     * upon {@link CompiledPermissions#getPrivileges(Path)} for all
+     * paths.
+     *
+     * @return an implementation of <code>CompiledPermissions</code> that
+     * grants everything and always returns {@link PrivilegeRegistry#ALL}
+     * upon {@link CompiledPermissions#getPrivileges(Path)}.
      */
     protected static CompiledPermissions getAdminPermissions() {
         return new CompiledPermissions() {
             public void close() {
                 //nop
             }
-            public boolean grants(Path absPath, int permissions) throws RepositoryException {
+            public boolean grants(Path absPath, int permissions) {
                 return true;
             }
-            public int getPrivileges(Path absPath) throws RepositoryException {
+            public int getPrivileges(Path absPath) {
                 return PrivilegeRegistry.ALL;
             }
-            public boolean canReadAll() throws RepositoryException {
+            public boolean canReadAll() {
                 return true;
             }
         };
     }
 
     /**
-     * Simple implementation to determine if the given set of principals
-     * only will result in read-only access.
+     * Returns compiled permissions for a read-only user i.e. permissions
+     * that grants READ permission for all non-AC items.
      *
-     * @param principals
-     * @return true if the given set only contains the everyone group.
-     */
-    protected boolean isReadOnly(Set principals) {
-        // TODO: improve. need to detect if 'anonymous' is included.
-        return principals.size() == 1 && principals.contains(everyone);
-    }
-
-    /**
-     *
-     * @return
+     * @return an implementation of <code>CompiledPermissions</code> that
+     * grants READ permission for all non-AC items.
      */
     protected CompiledPermissions getReadOnlyPermissions() {
         return new CompiledPermissions() {
@@ -154,12 +117,34 @@
                     return PrivilegeRegistry.READ;
                 }
             }
-            public boolean canReadAll() throws RepositoryException {
+            public boolean canReadAll() {
                 return false;
             }
         };
     }
 
+    //-------------------------------------------------< AccessControlUtils >---
+    /**
+     * @see AccessControlUtils#isAdminOrSystem(Set)
+     */
+    public boolean isAdminOrSystem(Set principals) {
+        for (Iterator it = principals.iterator(); it.hasNext();) {
+            Principal p = (Principal) it.next();
+            if (p instanceof AdminPrincipal || p instanceof SystemPrincipal) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @see AccessControlUtils#isReadOnly(Set)
+     */
+    public boolean isReadOnly(Set principals) {
+        // TODO: find ways to determine read-only status
+        return false;
+    }
+
     //----------------------------------------------< AccessControlProvider >---
     /**
      * Tests if the given <code>systemSession</code> is a SessionImpl and
@@ -170,7 +155,7 @@
      * <code>SessionImpl</code> or if retrieving the observation manager fails.
      * @see AccessControlProvider#init(Session, Map)
      */
-    public void init(Session systemSession, Map options) throws RepositoryException {
+    public void init(Session systemSession, Map configuration) throws RepositoryException {
         if (initialized) {
             throw new IllegalStateException("already initialized");
         }
@@ -180,9 +165,6 @@
         session = (SessionImpl) systemSession;
         observationMgr = systemSession.getWorkspace().getObservationManager();
         resolver = (SessionImpl) systemSession;
-
-        everyone = session.getPrincipalManager().getEveryone();
-
         initialized = true;
     }
 
@@ -193,40 +175,4 @@
         checkInitialized();
         initialized = false;
     }
-
-    /**
-     * @see AccessControlProvider#getPolicy(Path)
-     * @param absPath
-     */
-    public AccessControlPolicy getPolicy(Path absPath) throws ItemNotFoundException, RepositoryException {
-        checkInitialized();
-        return new AccessControlPolicy() {
-            public String getName() throws RepositoryException {
-                return policyName;
-            }
-            public String getDescription() throws RepositoryException {
-                return policyDesc;
-            }
-        };
-    }
-
-    /**
-     * @see AccessControlProvider#getAccessControlEntries(Path)
-     * @param absPath
-     */
-    public AccessControlEntry[] getAccessControlEntries(Path absPath) throws RepositoryException {
-        checkInitialized();
-        // always empty array, since aces will never be changed using the api.
-        return new AccessControlEntry[0];
-    }
-
-    /**
-     * @see AccessControlProvider#getEditor(Session)
-     */
-    public AccessControlEditor getEditor(Session session) {
-        checkInitialized();
-        // not editable at all: policy is always the default and cannot be
-        // changed using the JCR API.
-        return null;
-    }
 }
\ No newline at end of file

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=689499&r1=689498&r2=689499&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 Wed Aug 27 08:12:04 2008
@@ -18,8 +18,6 @@
 
 import org.apache.commons.collections.map.LRUMap;
 import org.apache.jackrabbit.spi.Path;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
 
@@ -28,8 +26,6 @@
  */
 public abstract class AbstractCompiledPermissions implements CompiledPermissions {
 
-    private static Logger log = LoggerFactory.getLogger(AbstractCompiledPermissions.class);
-
     // cache mapping a Path to a 'Result' containing permissions and privileges.
     private final LRUMap cache;
 
@@ -40,9 +36,9 @@
     /**
      *
      * @param absPath
-     * @return
+     * @return the <code>Result</code> for the give <code>absPath</code>.
      */
-    protected Result getResult(Path absPath) throws RepositoryException {
+    public Result getResult(Path absPath) throws RepositoryException {
         Result result;
         synchronized (cache) {
             result = (Result) cache.get(absPath);
@@ -101,23 +97,72 @@
     }
 
     //--------------------------------------------------------< inner class >---
+    /**
+     *
+     */
+    public static class Result {
 
-    protected class Result {
-
-        private final int permissions;
-        private final int privileges;
+        public static final Result EMPTY = new Result(Permission.NONE, Permission.NONE, PrivilegeRegistry.NO_PRIVILEGE, PrivilegeRegistry.NO_PRIVILEGE);
 
-        public Result(int permissions, int privileges) {
-            this.permissions = permissions;
-            this.privileges = privileges;
+        private final int allows;
+        private final int denies;
+        private final int allowPrivileges;
+        private final int denyPrivileges;
+
+        private final int hashCode;
+
+        public Result(int allows, int denies, int allowPrivileges, int denyPrivileges) {
+            this.allows = allows;
+            this.denies = denies;
+            this.allowPrivileges = allowPrivileges;
+            this.denyPrivileges = denyPrivileges;
+
+            int h = 17;
+            h = 37 * h + allows;
+            h = 37 * h + denies;
+            h = 37 * h + allowPrivileges;
+            h = 37 * h + denyPrivileges;
+            hashCode = h;
         }
 
         public boolean grants(int permissions) {
-            return (this.permissions | ~permissions) == -1;
+            return (this.allows | ~permissions) == -1;
         }
 
         public int getPrivileges() {
-            return privileges;
+            return allowPrivileges;
+        }
+
+        public Result combine(Result other) {
+            int cAllows =  allows | Permission.diff(other.allows, denies);
+            int cDenies = denies | Permission.diff(other.denies, allows);
+            int cAPrivs = allowPrivileges | Permission.diff(other.allowPrivileges, denyPrivileges);
+            int cDPrivs = denyPrivileges | Permission.diff(other.denyPrivileges, allowPrivileges);
+            return new Result(cAllows, cDenies, cAPrivs, cDPrivs);
+        }
+
+        /**
+         * @see Object#hashCode()
+         */
+        public int hashCode() {
+            return hashCode;
+        }
+
+        /**
+         * @see Object#equals(Object)
+         */
+        public boolean equals(Object object) {
+            if (object == this) {
+                return true;
+            }
+            if (object instanceof Result) {
+                Result other = (Result) object;
+                return allows == other.allows &&
+                       denies == other.denies &&
+                       allowPrivileges == other.allowPrivileges &&
+                       denyPrivileges == other.denyPrivileges;
+            }
+            return false;
         }
     }
 }
\ No newline at end of file

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=689499&r1=689498&r2=689499&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 Wed Aug 27 08:12:04 2008
@@ -29,12 +29,12 @@
 
     //---------------------------------------------------------< node names >---
     /**
-     * rep:policy node name
+     * Default name for a node of type rep:Policy.
      */
     Name N_POLICY = NF.create(Name.NS_REP_URI, "policy");
 
     /**
-     * Combined-ACL:
+     * PrincipalBased-ACL:
      * Name of the root-node of all access-control-nodes that store the
      * privileges for individual principals. This node is created upon
      * initializing this provider.
@@ -50,18 +50,6 @@
      * rep:principalName property name
      */
     Name P_PRINCIPAL_NAME = NF.create(Name.NS_REP_URI, "principalName");
-    /**
-     * rep:nodePath property name (optional if the ACL is stored with the
-     * node itself).
-     */
-    Name P_NODE_PATH = NF.create(Name.NS_REP_URI, "nodePath");
-    /**
-     * rep:glob property name used to restrict the number of child nodes
-     * or properties that are affected by the privileges applied at
-     * rep:nodePath
-     */
-    Name P_GLOB = NF.create(Name.NS_REP_URI, "glob");
-
 
     //----------------------------------------------------< node type names >---
     /**