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/03/19 14:57:11 UTC

svn commit: r638834 [5/14] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/principal/ jackr...

Added: 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=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,145 @@
+/*
+ * 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
+import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.core.security.SystemPrincipal;
+import org.apache.jackrabbit.spi.Path;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.Iterator;
+import java.util.Set;
+import java.security.Principal;
+
+/**
+ * <code>AbstractAccessControlProvider</code>...
+ */
+public abstract class AbstractAccessControlProvider implements AccessControlProvider {
+
+    private static Logger log = LoggerFactory.getLogger(AbstractAccessControlProvider.class);
+
+    private final String policyName;
+    private final String policyDesc;
+
+    protected boolean initialized;
+
+    protected AbstractAccessControlProvider() {
+        this(AbstractAccessControlProvider.class.getName() + ": default Policy", null);
+    }
+
+    protected AbstractAccessControlProvider(String defaultPolicyName, String defaultPolicyDesc) {
+        policyName = defaultPolicyName;
+        policyDesc = defaultPolicyDesc;
+    }
+
+    /**
+     *
+     */
+    protected void checkInitialized() {
+        if (!initialized) {
+            throw new IllegalStateException("Not initialized or already closed.");
+        }
+    }
+
+    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;
+    }
+
+    protected static CompiledPermissions getAdminPermissions() {
+        return new CompiledPermissions() {
+            public void close() {
+                //nop
+            }
+            public boolean grants(Path absPath, int permissions) throws RepositoryException {
+                return true;
+            }
+            public int getPrivileges(Path absPath) throws RepositoryException {
+                return PrivilegeRegistry.ALL;
+            }
+        };
+    }
+
+    protected static CompiledPermissions getReadOnlyPermissions() {
+        return new CompiledPermissions() {
+            public void close() {
+                //nop
+            }
+            public boolean grants(Path absPath, int permissions) throws RepositoryException {
+                return permissions == Permission.READ;
+            }
+            public int getPrivileges(Path absPath) throws RepositoryException {
+                return PrivilegeRegistry.READ;
+            }
+        };
+    }
+
+    //----------------------------------------------< AccessControlProvider >---
+    /**
+     * @see AccessControlProvider#close()
+     */
+    public void close() {
+        checkInitialized();
+        initialized = false;
+    }
+
+    /**
+     * @see AccessControlProvider#getPolicy(NodeId)
+     */
+    public AccessControlPolicy getPolicy(NodeId nodeId) throws ItemNotFoundException, RepositoryException {
+        checkInitialized();
+        return new AccessControlPolicy() {
+            public String getName() throws RepositoryException {
+                return policyName;
+            }
+            public String getDescription() throws RepositoryException {
+                return policyDesc;
+            }
+        };
+    }
+
+    /**
+     * @see AccessControlProvider#getAccessControlEntries(NodeId)
+     */
+    public AccessControlEntry[] getAccessControlEntries(NodeId nodeId) 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

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: 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=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,116 @@
+/*
+ * 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.commons.collections.map.LRUMap;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>AbstractCompiledPermissions</code>...
+ */
+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;
+
+    protected AbstractCompiledPermissions() {
+        cache = new LRUMap(1000);
+    }
+
+    /**
+     *
+     * @param absPath
+     * @return
+     */
+    protected Result getResult(Path absPath) throws RepositoryException {
+        Result result;
+        synchronized (cache) {
+            result = (Result) cache.get(absPath);
+            if (result == null) {
+                result = buildResult(absPath);
+                cache.put(absPath, result);
+            }
+        }
+        return result;
+    }
+
+    /**
+     *
+     * @param absPath
+     * @return
+     * @throws RepositoryException
+     */
+    protected abstract Result buildResult(Path absPath) throws RepositoryException;
+
+    /**
+     *
+     */
+    protected void clearCache() {
+        synchronized (cache) {
+            cache.clear();
+        }
+    }
+
+    //------------------------------------------------< CompiledPermissions >---
+    /**
+     * @see CompiledPermissions#close()
+     */
+    public void close() {
+        clearCache();
+    }
+
+    /**
+     * @see CompiledPermissions#grants(Path, int)
+     */
+    public boolean grants(Path absPath, int permissions) throws RepositoryException {
+        return getResult(absPath).grants(permissions);
+    }
+
+    /**
+     * @see CompiledPermissions#getPrivileges(Path)
+     */
+    public int getPrivileges(Path absPath) throws RepositoryException {
+        return getResult(absPath).getPrivileges();
+    }
+
+    //--------------------------------------------------------< inner class >---
+
+    protected class Result {
+
+        private final int permissions;
+        private final int privileges;
+
+        public Result(int permissions, int privileges) {
+            this.permissions = permissions;
+            this.privileges = privileges;
+        }
+
+        public boolean grants(int permissions) {
+            return (this.permissions | ~permissions) == -1;
+        }
+
+        public int getPrivileges() {
+            return privileges;
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: 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=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,92 @@
+/*
+ * 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.spi.NameFactory;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+
+/**
+ * <code>AccessControlConstants</code>...
+ */
+public interface AccessControlConstants {
+
+    NameFactory NF = NameFactoryImpl.getInstance();
+
+    //---------------------------------------------------------< node names >---
+    /**
+     * rep:policy node name
+     */
+    Name N_POLICY = NF.create(Name.NS_REP_URI, "policy");
+
+    /**
+     * Combined-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.
+     */
+    Name N_ACCESSCONTROL = NF.create(Name.NS_REP_URI, "accesscontrol");
+
+    //-----------------------------------------------------< property names >---
+    /**
+     * rep:privileges property name
+     */
+    Name P_PRIVILEGES = NF.create(Name.NS_REP_URI, "privileges");
+    /**
+     * 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 >---
+    /**
+     * rep:AccessControl nodetype
+     */
+    Name NT_REP_ACCESS_CONTROL = NF.create(Name.NS_REP_URI, "AccessControl");
+    /**
+     * rep:AccessControllable nodetype
+     */
+    Name NT_REP_ACCESS_CONTROLLABLE = NF.create(Name.NS_REP_URI, "AccessControllable");
+    /**
+     * rep:ACL nodetype
+     */
+    Name NT_REP_ACL = NF.create(Name.NS_REP_URI, "ACL");
+    /**
+     * rep:ACE nodetype
+     */
+    Name NT_REP_ACE = NF.create(Name.NS_REP_URI, "ACE");
+    /**
+     * rep:GrantACE nodetype
+     */
+    Name NT_REP_GRANT_ACE = NF.create(Name.NS_REP_URI, "GrantACE");
+    /**
+     * rep:DenyACE nodetype
+     */
+    Name NT_REP_DENY_ACE = NF.create(Name.NS_REP_URI, "DenyACE");
+
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlConstants.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,164 @@
+/*
+ * 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.NodeId;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlException;
+import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.ItemNotFoundException;
+import java.security.Principal;
+
+/**
+ * <code>AccessControlEditor</code> is used to edit the access control policy
+ * and entry objects provided by the respective service.
+ */
+public interface AccessControlEditor {
+
+    /**
+     * Retrieves the policy template for the Node identified by the given
+     * <code>NodeId</code>. In contrast to {@link #editPolicyTemplate} this method
+     * returns <code>null</code> if no policy has been applied before by calling
+     * {@link #setPolicyTemplate}). Still the returned PolicyTemplate is detached from
+     * the AccessControlProvider and is only an external representation.
+     * Modification will therefore not take effect, until it is written back to
+     * the editor and persisted.
+     * <p/>
+     * Compared to the policy returned by {@link AccessControlProvider#getPolicy(NodeId)},
+     * the scope of the PolicyTemplate it limited to the Node itself and does
+     * not take inherited elements into account.
+     *
+     * @param id the id of the Node to retrievethe PolicyTemplate for.
+     * @return the PolicyTemplate or <code>null</code> no policy has been
+     * applied to the node before.
+     * @throws AccessControlException If the Node identified by the given id does
+     * not allow ACL modifications.
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if an error occurs
+     */
+    PolicyTemplate getPolicyTemplate(NodeId id) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Retrieves an editable policy template for the Node identified by the given
+     * <code>NodeId</code>. If the node does not yet have an policy set an
+     * new (empty) template is created (see also {@link #getPolicyTemplate(NodeId)}.<br>
+     * The PolicyTemplate returned is detached from the underlying
+     * <code>AccessControlProvider</code> and is only an external
+     * representation. Modification will therefore not take effect, until it is
+     * written back to the editor and persisted.
+     * <p/>
+     * Compared to the policy returned by {@link AccessControlProvider#getPolicy(NodeId)},
+     * the scope of the PolicyTemplate it limited to the Node itself and does
+     * never not take inherited elements into account.
+     *
+     * @param id the id of the Node to retrieve (or create) the PolicyTemplate for.
+     * @return the PolicyTemplate
+     * @throws AccessControlException If the Node identified by the given id does
+     * not allow ACL modifications.
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if an error occurs
+     */
+    PolicyTemplate editPolicyTemplate(NodeId id) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Stores the policy template to the respective node.
+     *
+     * @param id the id of the node to write the template for. Note, that a
+     * {@link javax.jcr.Session#save()} is required to persist the changes. Upon
+     * 'setPolicyTemplate' the modifications are applied in the transient space only.
+     * @param template the <code>PolicyTemplate</code> to store.
+     * @throws AccessControlException If the PolicyTemplate is <code>null</code> or
+     * if it is not applicable to the Node identified by the given id.
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if an other error occurs.
+     */
+    void setPolicyTemplate(NodeId id, PolicyTemplate template) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Removes the template from the respective node.
+     *
+     * @param id the id of the node to remove the acl from.
+     * @return the PolicyTemplate that has been remove or <code>null</code>
+     * if there was no policy to remove.
+     * @throws AccessControlException If the Node identified by the given id
+     * does not allow policy modifications.
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if an other error occurs
+     */
+    PolicyTemplate removePolicyTemplate(NodeId id) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Returns the access control entries present with the node
+     * identified by  <code>id</code>, that have
+     * been added using {@link #addAccessControlEntry(NodeId,Principal,Privilege[])}.
+     * The implementation may return other entries, if they can be removed
+     * using {@link #removeAccessControlEntry(NodeId,AccessControlEntry)}.
+     *
+     * @param id
+     * @return the (granting) access control entries present with the node
+     * identified by  <code>id</code>.
+     * @throws AccessControlException
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException
+     */
+    AccessControlEntry[] getAccessControlEntries(NodeId id) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Adds an access control entry to the node identified by
+     * <code>id</code>. An implementation that always keeps entries with an
+     * existing <code>AccessControlPolicy</code> may choose to treat this
+     * method as short-cut for {@link #editPolicyTemplate(NodeId)} and
+     * subsequent template modification.
+     * Note, that in addition an implementation may only allow granting
+     * ACEs as specified by JSR 283.
+     *
+     * @param id
+     * @param principal
+     * @param privileges
+     * @return The entry that results from adding the specified
+     * privileges for the specified principal.
+     * @throws AccessControlException If the Node identified by the given id
+     * does not allow access control modifications, if the principal does not
+     * exist or if any of the specified privileges is unknown.
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if an other error occurs
+     */
+    AccessControlEntry addAccessControlEntry(NodeId id, Principal principal, Privilege[] privileges) throws AccessControlException, ItemNotFoundException, RepositoryException;
+
+    /**
+     * Removes the access control entry represented by the given
+     * <code>template</code> from the node identified by
+     * <code>id</code>. An implementation that always keeps entries with an
+     * existing <code>AccessControlPolicy</code> may choose to treat this
+     * method as short-cut for {@link #getPolicyTemplate(NodeId)} and
+     * subsequent template modification.
+     * Note that only <code>PolicyEntry</code>s accessible through
+     * {@link #getAccessControlEntries(NodeId)} can be removed by this call.
+     *
+     * @param id
+     * @param entry
+     * @return true if entry was contained could be successfully removed.
+     * @throws AccessControlException If an access control specific exception
+     * occurs (e.g. invalid entry implementation, entry cannot be removed
+     * by this call, etc.).
+     * @throws ItemNotFoundException if no node exists for the given id.
+     * @throws RepositoryException if another error occurs.
+     */
+    boolean removeAccessControlEntry(NodeId id, AccessControlEntry entry) throws AccessControlException, ItemNotFoundException, RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEditor.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,125 @@
+/*
+ * 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.NodeId;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
+
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The AccessControlProvider is used to provide access control policy and entry
+ * objects that apply to an item in a single workspace. The provider is bound
+ * to a system session in contrast to the <code>AccessControlManager</code> that
+ * is bound to a specific session/subject.
+ * <p/>
+ * Please note following additional special conditions:
+ * <ul>
+ * <li>The detection of access control policy/entries is an implementation
+ * detail. They may be resource based or retrieved by other means.</li>
+ * <li>An access control policy/entry may be inherited across the item hierarchy.
+ * The details are left to the implementation</li>
+ * <li>If no policy can be determined for a particular Item the implementation
+ * must return some implementation specific default policy.</li>
+ * <li>Transient (NEW) items created within a regular Session object are unknown
+ * to and cannot be handled by the <code>AccessControlProvider</code>.</li>
+ * <li>If the item id passed to the corresponding calls doesn't point to an
+ * existing item, <code>ItemNotFoundException</code> will be thrown. It is
+ * therefore recommended to evaluate the id of the closest not-new ancestor
+ * node before calling any methods on the provider.</li>
+ * <li>Changes to access control policy and entries made through the
+ * <code>AccessControlEditor</code> are not effective unless
+ * they are persisted by calling <code>Session.save()</code> on the session
+ * that has been used to obtain the editor.</li>
+ * </ul>
+ *
+ * @see AccessControlProviderFactory
+ */
+public interface AccessControlProvider {
+
+    /**
+     * Allows the {@link AccessControlProviderFactory} to pass a session
+     * and configuration options to the <code>AccessControlProvider</code>.
+     *
+     * @param systemSession
+     * @param options
+     */
+    void init(Session systemSession, Map options) throws RepositoryException;
+
+    /**
+     * Closes this provider when it is no longer used by the respective
+     * workspace and release resources bound by this provider.
+     */
+    void close();
+
+    /**
+     * Returns the effective policy for the specified node.
+     *
+     * @param nodeId
+     * @return The effective policy that applies at <code>nodeId</code>.
+     * @throws ItemNotFoundException If no Node with the specified
+     * <code>nodeId</code> exists.
+     * @throws RepositoryException If another error occurs.
+     * @see org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager#getEffectivePolicy(String)
+     */
+    AccessControlPolicy getPolicy(NodeId nodeId) throws ItemNotFoundException, RepositoryException;
+
+    /**
+     * Returns the effective 'grant' access control entries for the specified
+     * item. An implementation may retrieve the entries from the effective
+     * policy or by other implementation specific means.
+     *
+     * @param nodeId
+     * @return The effective access control entries or an empty array if
+     * no entries apply at <code>nodeId</code>.
+     * @throws ItemNotFoundException If no Node with the specified
+     * <code>nodeId</code> exists.
+     * @throws RepositoryException If an error occurs.
+     * @see org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager#getEffectiveAccessControlEntries(String)
+     */
+    AccessControlEntry[] getAccessControlEntries(NodeId nodeId) throws RepositoryException;
+
+    /**
+     * Returns an <code>AccessControlEditor</code> for the given Session object
+     * or <code>null</code> if the implementation does not support editing
+     * of access control policies.
+     *
+     * @param session
+     * @return the ACL editor or <code>null</code>
+     */
+    AccessControlEditor getEditor(Session session);
+
+    /**
+     * Compiles the effective policy for the specified set of
+     * <code>Principal</code>s.
+     *
+     * @param principals Set of principals to compile the permissions for. If
+     * the order of evaluating permissions for principals is meaningful, the
+     * caller is adviced to pass a Set that respects the order of insertion.
+     * @return The effective, compiled CompiledPolicy that applies for the
+     * specified set of principals.
+     * @throws ItemNotFoundException If no Node with the specified
+     * <code>nodeId</code> exists.
+     * @throws RepositoryException If another error occurs.
+     */
+    CompiledPermissions compilePermissions(Set principals) throws ItemNotFoundException, RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProvider.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,76 @@
+/*
+ * 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.security.JackrabbitSecurityManager;
+import org.apache.jackrabbit.core.config.WorkspaceSecurityConfig;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+/**
+ * The <code>AccessControlProviderFactory</code> is used to create
+ * {@link AccessControlProvider}s for the various workspaces present in the
+ * repository. If a provider is no longer used by the workspace, it is
+ * {@link AccessControlProvider#close() closed}.
+ * <p/>
+ * The factory does not need to cache the created {@link AccessControlProvider}s.
+ * They are used during the entire lifetime of their workspace, and are cached
+ * together with the respective workspace related objects by the repository
+ * implementation.
+ * <p/>
+ * The {@link AccessControlProvider}s are requested using a
+ * {@link Session system Session}. The system sessions have a distinct access
+ * control rules in order to prevent chicken-egg problems when setting up
+ * security for a workspace.
+ */
+public interface AccessControlProviderFactory {
+
+    /**
+     * Initalize the Factory with JackrabbitSecurityManager.
+     * This allows to access Repsoitory's Security objects
+     *
+     * @param securityManager
+     */
+    void init(JackrabbitSecurityManager securityManager) throws RepositoryException;
+
+    /**
+     * Dispose this <code>AccessControlProviderFactory</code> and its resources.
+     *
+     * @throws RepositoryException if an error occurs.
+     */
+    void close() throws RepositoryException;
+
+    /**
+     * Creates an AccessControlProvider for the workspace of the given
+     * system session. If the passed configuration is <code>null</code> or
+     * does not have a provider entry, this factory must create a default
+     * provider. In any case the provider must be initialized before it
+     * is returned to the caller.
+     *
+     * @param systemSession the system session for the workspace the
+     * <code>AccessControlProvider</code> should be created for.
+     * @param config The security configuration for that workspace or
+     * <code>null</code> if the config entry is present. In this case the
+     * factory must use its default. The configuration is used to determine
+     * the implementation of <code>AccessControlProvider</code> to be used
+     * and to retrieve eventual configuration parameters.
+     * @return a new, initialized AccessControlProvider.
+     * @throws RepositoryException if an error occurs
+     */
+    AccessControlProvider createProvider(Session systemSession, WorkspaceSecurityConfig config) throws RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactory.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,88 @@
+/*
+ * 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.config.BeanConfig;
+import org.apache.jackrabbit.core.config.WorkspaceSecurityConfig;
+import org.apache.jackrabbit.core.security.JackrabbitSecurityManager;
+import org.apache.jackrabbit.core.security.authorization.acl.ACLProvider;
+import org.apache.jackrabbit.core.security.user.UserAccessControlProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Default implementation of the AccessControlProviderFactory
+ */
+public class AccessControlProviderFactoryImpl implements AccessControlProviderFactory {
+
+    /**
+     * the default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(AccessControlProviderFactoryImpl.class);
+
+    /**
+     * The name of the security workspace (containing users...)
+     */
+    private String secWorkspaceName = null;
+
+    //---------------------------------------< AccessControlProviderFactory >---
+    /**
+     * @see AccessControlProviderFactory#init(JackrabbitSecurityManager)
+     */
+    public void init(JackrabbitSecurityManager securityMgr) throws RepositoryException {
+        secWorkspaceName = securityMgr.getSecurityConfig().getSecurityManagerConfig().getWorkspaceName();
+    }
+
+    /**
+     * @see AccessControlProviderFactory#close()
+     */
+    public void close() throws RepositoryException {
+        // nothing to do
+    }
+
+    /**
+     * @see AccessControlProviderFactory#createProvider(Session, WorkspaceSecurityConfig)
+     */
+    public AccessControlProvider createProvider(Session systemSession, WorkspaceSecurityConfig config)
+            throws RepositoryException {
+        String workspaceName = systemSession.getWorkspace().getName();
+        AccessControlProvider prov;
+        Map props;
+        if (config != null && config.getAccessControlProviderConfig() != null) {
+            BeanConfig bc = config.getAccessControlProviderConfig();
+            prov = (AccessControlProvider) bc.newInstance();
+            props = bc.getParameters();
+        } else {
+            log.debug("No ac-provider configuration for workspace " + workspaceName + " -> using defaults.");
+            if (workspaceName.equals(secWorkspaceName)) {
+                prov = new UserAccessControlProvider();
+            } else {
+                prov = new ACLProvider();
+            }
+            log.debug("Default provider for workspace " + workspaceName + " = " + prov.getClass().getName());
+            props = Collections.EMPTY_MAP;
+        }
+
+        prov.init(systemSession, props);
+        return prov;
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,63 @@
+/*
+ * 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.spi.Path;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.ItemNotFoundException;
+
+/**
+ * <code>CompiledPermissions</code> represents the evaluation of an
+ * <code>AccessControlPolicy</code> that applies for a given set of
+ * <code>Principal</code>s (normally obtained from the Subject
+ * of a Session).
+ */
+public interface CompiledPermissions {
+
+    /**
+     * Indicate to this <code>CompiledPermissions</code> object that it is
+     * not used any more.
+     */
+    void close();
+
+    /**
+     * Returns <code>true</code> if the specified permissions are granted
+     * on the item identified by the given <code>path</code>.
+     *
+     * @param absPath Absolute path pointing to an item. If the item does
+     * not exist yet (asking for 'add-node' and 'set-property' permission),
+     * it's direct ancestor must exist.
+     * @param permissions A combination of one or more of permission constants
+     * defined by {@link Permission} encoded as a bitmask value
+     * @return <code>true</code> if the specified permissions are granted,
+     * <code>false</code> otherwise.
+     * @throws ItemNotFoundException if neither the path nor its direct
+     * ancestor point to an existing item.
+     */
+    boolean grants(Path absPath, int permissions) throws RepositoryException;
+
+    /**
+     * Returns the <code>Privilege</code>s granted by the underlying policy
+     * if the given <code>absPath</code> denotes an existing <code>Node</code>,
+     * otherwise it returns zero.
+     *
+     * @return the granted privileges at <code>absPath</code> or zero if
+     * the path does not denote an existing <code>Node</code>.
+     */
+    int getPrivileges(Path absPath) throws RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,90 @@
+/*
+ * 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Item;
+
+/**
+ * <code>GlobPattern</code>... TODO IMPROVE
+ */
+public class GlobPattern {
+
+    private static Logger log = LoggerFactory.getLogger(GlobPattern.class);
+
+    public static final String WILDCARD_ALL = "*";
+
+    private final String pattern;
+
+    private GlobPattern(String pattern)  {
+        this.pattern = pattern;
+    }
+
+    public static GlobPattern create(String pattern) {
+        if (pattern == null) {
+            throw new IllegalArgumentException();
+        }
+        return new GlobPattern(pattern);
+    }
+
+    public boolean matches(String toMatch) {
+        // shortcut
+        if (WILDCARD_ALL.equals(pattern) || pattern.equals(toMatch)) {
+            return true;
+        }
+
+        // TODO
+        return false;
+    }
+
+    public boolean matches(Item itemToMatch) {
+        // TODO
+        return false;
+    }
+
+    //-------------------------------------------------------------< Object >---
+
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode() {
+        return pattern.hashCode();
+    }
+
+    /**
+     * @see Object#toString()
+     */
+    public String toString() {
+        return pattern;
+    }
+
+    /**
+     * @see Object#equals(Object)
+     */
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof GlobPattern) {
+            return pattern.equals(((GlobPattern)obj).pattern);
+        }
+        return false;
+    }
+
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/GlobPattern.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+/**
+ * <code>Permission</code>...
+ */
+public final class Permission {
+
+    public static final int NONE = 0;
+
+    public static final int READ = 1;
+
+    public static final int ADD_NODE = 4;
+
+    public static final int REMOVE_NODE = 8;
+
+    public static final int SET_PROPERTY = 2;
+
+    public static final int REMOVE_PROPERTY = 16;
+
+    public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE | REMOVE_PROPERTY);
+
+    /**
+     * Build the permissions granted by evaluating the given privileges. If
+     * <code>protectesPolicy</code> is <code>true</code> read and write
+     * permission are only granted if the corresponding ac-privilege is
+     * present.
+     *
+     * @param privs The privileges granted on the Node itself (for properties
+     * the ACL of the direct ancestor).
+     * @param parentPrivs The privileges granted on the parent of the Node. Not
+     * relevant for properties since it only is used to determine permissions
+     * on a Node (add_node, remove).
+     * @param protectsPolicy
+     * @return the permissions granted evaluating the given privileges.
+     */
+    public static int calculatePermissions(int privs, int parentPrivs, boolean protectsPolicy) {
+        int perm = Permission.NONE;
+        if (protectsPolicy) {
+            if ((parentPrivs & PrivilegeRegistry.READ_AC) == PrivilegeRegistry.READ_AC) {
+                perm |= Permission.READ;
+            }
+            if ((parentPrivs & PrivilegeRegistry.MODIFY_AC) == PrivilegeRegistry.MODIFY_AC) {
+                perm |= Permission.ADD_NODE;
+                perm |= Permission.SET_PROPERTY;
+                perm |= Permission.REMOVE_NODE;
+                perm |= Permission.REMOVE_PROPERTY;
+            }
+        } else {
+            if ((privs & PrivilegeRegistry.READ) == PrivilegeRegistry.READ) {
+                perm |= Permission.READ;
+            }
+            if ((privs & PrivilegeRegistry.MODIFY_PROPERTIES) == PrivilegeRegistry.MODIFY_PROPERTIES) {
+                perm |= Permission.SET_PROPERTY;
+                perm |= Permission.REMOVE_PROPERTY;
+            }
+            // the following permissions are granted through privilege on the parent.
+            if ((parentPrivs & PrivilegeRegistry.ADD_CHILD_NODES) == PrivilegeRegistry.ADD_CHILD_NODES) {
+                perm |= Permission.ADD_NODE;
+            }
+            if ((parentPrivs & PrivilegeRegistry.REMOVE_CHILD_NODES) == PrivilegeRegistry.REMOVE_CHILD_NODES) {
+                perm |= Permission.REMOVE_NODE;
+            }
+        }
+        return perm;
+    }
+
+    /**
+     * Returns those bits from <code>permissions</code> that are not present in
+     * the <code>otherPermissions</code>, i.e. subtracts the other permissions
+     * from permissions.<br>
+     * If the specified <code>otherBits</code> do not intersect with
+     * <code>bits</code>,  <code>bits</code> are returned.<br>
+     * If <code>bits</code> is included <code>otherBits</code>,
+     * {@link #NONE} is returned.
+     *
+     * @param permissions
+     * @param otherPermissions
+     * @return the differences of the 2 permissions or <code>{@link #NONE}</code>.
+     */
+    public static int diff(int permissions, int otherPermissions) {
+        return permissions & ~otherPermissions;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,39 @@
+/*
+ * 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.security.jsr283.security.AccessControlEntry;
+
+/**
+ * This is one Entry in an {@link PolicyTemplate} or an
+ * {@link org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy}<p>
+ * In the previous case the entry must be detached from the effective ac-content.
+ */
+public interface PolicyEntry extends AccessControlEntry {
+
+    /**
+     * @return true if this entry adds <code>Privilege</code>s for the principal;
+     * false otherwise.
+     */
+    boolean isAllow();
+
+    // TODO: eventually add
+    // String getNodePath();
+    // String getGlob();
+    // String[] getRestrictionNames();
+    // Value getRestriction(String restrictionName);
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyEntry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,85 @@
+/*
+ * 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.security.jsr283.security.AccessControlException;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlPolicy;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * PolicyTemplate is the editable view of an AccessControlPolicy and detached
+ * from the later. Therefore modifications made to the template will not take
+ * effect, until it is
+ * {@link org.apache.jackrabbit.core.security.jsr283.security.AccessControlManager#setPolicy(String, AccessControlPolicy)
+ * written back} and {@link javax.jcr.Session#save() saved}.
+ */
+public interface PolicyTemplate extends AccessControlPolicy {
+
+    /**
+     * Returns <code>true</code> if this template does not yet define any
+     * entries.
+     *
+     * @return If no entries are present.
+     */
+    boolean isEmpty();
+
+    /**
+     * Returns the number of entries.
+     *
+     * @return The number of entries present.
+     */
+    int size();
+
+    /**
+     * Returns all {@link PolicyEntry entries} of this
+     * <code>PolicyTemplate</code>.
+     *
+     * @return the {@link PolicyEntry entries} present in this
+     * <code>PolicyTemplate</code>.
+     */
+    PolicyEntry[] getEntries();
+
+    /**
+     * Set the parameters defined by the given <code>entry</code> to this
+     * policy template. If this policy already contains that entry this method
+     * will return <code>false</code>. If the entry differs from an existing
+     * entry only by the privileges defined, that entry will be replaced.
+     *
+     * @param entry
+     * @return true if this policy has changed by incorporating the given entry;
+     * false otherwise.
+     * @throws AccessControlException If the given entry cannot be handled,
+     * contains invalid parameters or if some other access control specific
+     * exception occurs.
+     * @throws RepositoryException If another error occurs.
+     */
+    boolean setEntry(PolicyEntry entry) throws AccessControlException, RepositoryException;
+
+    /**
+     * Removes the specified entry. Returns true, if the entry was successfully
+     * removed, false otherwise.
+     *
+     * @param entry the <code>PolicyEntry</code> to remove
+     * @return true if this policy contained the specified entry and it could
+     * be successfully removed; false otherwise.
+     * @throws AccessControlException If an access control specific exception
+     * occurs (e.g. invalid entry implementation).
+     * @throws RepositoryException If another error occurs.
+     */
+    boolean removeEntry(PolicyEntry entry) throws AccessControlException, RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PolicyTemplate.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,435 @@
+/*
+ * 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.security.jsr283.security.Privilege;
+import org.apache.jackrabbit.core.security.jsr283.security.AccessControlException;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Collections;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The <code>PrivilegeSet</code> represents a set of {@link Privilege}s.
+ */
+public final class PrivilegeRegistry {
+
+    private static final Map REGISTERED_PRIVILEGES = new HashMap(10);
+    private static final Map BITS_TO_PRIVILEGES = new HashMap();
+
+    public static final int NO_PRIVILEGE = 0;
+    public static final int READ = 1;
+    public static final int MODIFY_PROPERTIES = 2;
+    public static final int ADD_CHILD_NODES = 4;
+    public static final int REMOVE_CHILD_NODES = 8;
+    public static final int READ_AC = 16;
+    public static final int MODIFY_AC =32;
+    public static final int WRITE = 14;
+    public static final int ALL = 63;
+
+    public static final Privilege READ_PRIVILEGE = registerPrivilege(Privilege.READ, READ);
+    public static final Privilege MODIFY_PROPERTIES_PRIVILEGE = registerPrivilege(Privilege.MODIFY_PROPERTIES, MODIFY_PROPERTIES);
+    public static final Privilege ADD_CHILD_NODES_PRIVILEGE = registerPrivilege(Privilege.ADD_CHILD_NODES, ADD_CHILD_NODES);
+    public static final Privilege REMOVE_CHILD_NODES_PRIVILEGE = registerPrivilege(Privilege.REMOVE_CHILD_NODES, REMOVE_CHILD_NODES);
+    public static final Privilege READ_AC_PRIVILEGE = registerPrivilege(Privilege.READ_ACCESS_CONTROL, READ_AC);
+    public static final Privilege MODIFY_AC_PRIVILEGE = registerPrivilege(Privilege.MODIFY_ACCESS_CONTROL, MODIFY_AC);
+    public static final Privilege WRITE_PRIVILEGE = registerPrivilege(Privilege.WRITE, new PrivilegeImpl[] {
+            (PrivilegeImpl) MODIFY_PROPERTIES_PRIVILEGE,
+            (PrivilegeImpl) ADD_CHILD_NODES_PRIVILEGE,
+            (PrivilegeImpl) REMOVE_CHILD_NODES_PRIVILEGE });
+    public static final Privilege ALL_PRIVILEGE = registerPrivilege(new AllPrivilege());
+
+    public static Privilege[] getRegisteredPrivileges() {
+        return (Privilege[]) REGISTERED_PRIVILEGES.values().toArray(new Privilege[REGISTERED_PRIVILEGES.size()]);
+    }
+
+    public static Privilege[] getPrivileges(String[] privilegeNames) throws AccessControlException {
+        if (privilegeNames == null || privilegeNames.length == 0) {
+            throw new AccessControlException();
+        }
+        PrivilegeImpl[] privileges = new PrivilegeImpl[privilegeNames.length];
+        for (int i = 0; i < privilegeNames.length; i++) {
+            String name = privilegeNames[i];
+            if (REGISTERED_PRIVILEGES.containsKey(name)) {
+                privileges[i] = (PrivilegeImpl) REGISTERED_PRIVILEGES.get(name);
+            } else {
+                throw new AccessControlException("Unknown privilege " + name);
+            }
+        }
+        return privileges;
+    }
+
+    /**
+     *
+     * @param privilegeNames
+     * @return
+     * @throws AccessControlException if the specified <code>privilegeNames</code>
+     * are <code>null</code>, an empty array or if any of the names is not known
+     * to this registry.
+     */
+    public static int getBits(String[] privilegeNames) throws AccessControlException {
+        if (privilegeNames == null || privilegeNames.length == 0) {
+            throw new AccessControlException();
+        }
+        PrivilegeImpl[] privileges = new PrivilegeImpl[privilegeNames.length];
+        for (int i = 0; i < privilegeNames.length; i++) {
+            String name = privilegeNames[i];
+            if (REGISTERED_PRIVILEGES.containsKey(name)) {
+                privileges[i] = (PrivilegeImpl) REGISTERED_PRIVILEGES.get(name);
+            } else {
+                throw new AccessControlException("Unknown privilege " + name);
+            }
+        }
+        return PrivilegeImpl.getBits(privileges, false);
+    }
+
+    /**
+     * @param privileges
+     * @return
+     * @throws AccessControlException If the specified array is null
+     * or if it contains an unregistered privilege.
+     */
+    public static int getBits(Privilege[] privileges) throws AccessControlException {
+        if (privileges == null || privileges.length == 0) {
+            throw new AccessControlException();
+        }
+        return PrivilegeImpl.getBits(privileges, false);
+    }
+
+    /**
+     * Returns an array of registered <code>Privilege</code>s. If the specified
+     * <code>bits</code> represent a registered privilege the returned array
+     * contains a single element. Otherwise the returned array contains the
+     * individual registered privileges that are combined in the givent
+     * <code>bits</code>. If <code>bits</code> is {@link #NO_PRIVILEGE 0} or
+     * does not match to any registered privilege an empty array will be returned.
+     *
+     * @param bits
+     * @return Array of <code>Privilege</code>s that are presented by the given it
+     * or an empty array if <code>bits</code> is lower than {@link #READ} or
+     * cannot be resolved to registered <code>Privilege</code>s.
+     */
+    public static Privilege[] getPrivileges(int bits) {
+        Privilege[] privs = new Privilege[0];
+        if (bits > NO_PRIVILEGE) {
+            PrivilegeImpl privilege = getPrivilege(bits);
+            if (REGISTERED_PRIVILEGES.containsKey(privilege.getName())) {
+                privs = new Privilege[] {privilege};
+            } else {
+                privs = privilege.getDeclaredAggregatePrivileges();
+            }
+        }
+        return privs;
+    }
+
+    /**
+     * Returns those bits from <code>bits</code> that are not present in
+     * the <code>otherBits</code>, i.e. subtracts the other privileges from
+     * this one.<br>
+     * If the specified <code>otherBits</code> do not intersect with
+     * <code>bits</code>,  <code>bits</code> are returned.<br>
+     * If <code>bits</code> is included <code>otherBits</code>,
+     * {@link #NO_PRIVILEGE} is returned.
+     *
+     * @param bits
+     * @param otherBits
+     * @return the differences of the 2 privileges or <code>{@link #NO_PRIVILEGE}</code>.
+     */
+    public static int diff(int bits, int otherBits) {
+        return bits & ~otherBits;
+    }
+
+    /**
+     *
+     * @param name
+     * @param description
+     * @param privileges
+     * @return new aggregate from the specified privileges.
+     */
+    private static PrivilegeImpl getPrivilege(String name, String description, PrivilegeImpl[] privileges) {
+        return new AggregatePrivilege(name, description, privileges);
+    }
+
+    /**
+     *
+     * @param bits
+     * @return PrivilegeImpl that corresponds to the given bits.
+     */
+    private static PrivilegeImpl getPrivilege(int bits) {
+        PrivilegeImpl priv = null;
+        Object key = new Integer(bits);
+        if (BITS_TO_PRIVILEGES.containsKey(key)) {
+            return (PrivilegeImpl) BITS_TO_PRIVILEGES.get(key);
+        } else {
+            // shortcut
+            if ((bits & ALL) == ALL) {
+                return (PrivilegeImpl) ALL_PRIVILEGE;
+            }
+
+            List privileges = new ArrayList();
+            if ((bits & READ) == READ) {
+                privileges.add(READ_PRIVILEGE);
+            }
+            if ((bits & WRITE) == WRITE) {
+                privileges.add(WRITE_PRIVILEGE);
+            } else {
+                if ((bits & MODIFY_PROPERTIES) == MODIFY_PROPERTIES) {
+                    privileges.add(MODIFY_PROPERTIES_PRIVILEGE);
+                }
+                if ((bits & ADD_CHILD_NODES) == ADD_CHILD_NODES) {
+                    privileges.add(ADD_CHILD_NODES_PRIVILEGE);
+                }
+                if ((bits & REMOVE_CHILD_NODES) == REMOVE_CHILD_NODES) {
+                    privileges.add(REMOVE_CHILD_NODES_PRIVILEGE);
+                }
+            }
+            if ((bits & READ_AC) == READ_AC) {
+                privileges.add(READ_AC_PRIVILEGE);
+            }
+            if ((bits & MODIFY_AC) == MODIFY_AC) {
+                privileges.add(MODIFY_AC_PRIVILEGE);
+            }
+
+            if (!privileges.isEmpty()) {
+                if (privileges.size() == 1) {
+                    priv = (PrivilegeImpl) privileges.get(0);
+                } else {
+                    String name = "AggregatePrivilege" + bits;
+                    priv = getPrivilege(name, null, (PrivilegeImpl[]) privileges.toArray(new PrivilegeImpl[privileges.size()]));
+                }
+                BITS_TO_PRIVILEGES.put(key, priv);
+            }
+            return priv;
+        }
+    }
+
+    private static Privilege registerPrivilege(String name, int bits) {
+        PrivilegeImpl priv = new SimplePrivilege(name, null, bits);
+        return registerPrivilege(priv);
+    }
+
+    private static Privilege registerPrivilege(String name, PrivilegeImpl[] privileges) {
+        PrivilegeImpl priv = getPrivilege(name, null, privileges);
+        return registerPrivilege(priv);
+    }
+
+    private static Privilege registerPrivilege(PrivilegeImpl privilege) {
+        REGISTERED_PRIVILEGES.put(privilege.getName(), privilege);
+        BITS_TO_PRIVILEGES.put(new Integer(privilege.getBits()), privilege);
+        return privilege;
+    }
+
+    //--------------------------------------------------------------------------
+    /**
+     * Avoid instanciation of the <code>PrivilegeRegistry</code>.
+     */
+    private PrivilegeRegistry() {}
+
+    //--------------------------------------------------------------------------
+    /**
+     *
+     */
+    private static abstract class PrivilegeImpl implements Privilege {
+
+        static final Privilege[] EMPTY_ARRAY = new Privilege[0];
+
+        private final String name;
+        private final String description;
+
+        private PrivilegeImpl(String name, String description) {
+            if (name == null) {
+                throw new IllegalArgumentException("A privilege must have a name.");
+            }
+            this.name = name;
+            this.description = description;
+        }
+
+        abstract int getBits();
+
+        //------------------------------------------------------< Privilege >---
+        public String getName() {
+            return name;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public boolean isAbstract() {
+            return false;
+        }
+
+        /**
+         * @param  privileges to get the bit representation for
+         * @param ignoreUnkown
+         * @return bit representing the Action
+         * @throws AccessControlException If <code>ignoreUnkown</code> is false
+         * and any of the specified privileges not a registered privilege.
+         */
+        private static int getBits(Privilege[] privileges, boolean ignoreUnkown) throws AccessControlException {
+            int bits = NO_PRIVILEGE;
+            for (int i = 0; i < privileges.length; i++) {
+                Privilege priv = privileges[i];
+                if (priv instanceof PrivilegeImpl) {
+                    bits |= ((PrivilegeImpl) priv).getBits();
+                } else if (priv.isAggregate()) {
+                    // try to resolve the aggregates
+                    bits |= getBits(priv.getDeclaredAggregatePrivileges(), ignoreUnkown);
+                } else {
+                    PrivilegeImpl p = (PrivilegeImpl) REGISTERED_PRIVILEGES.get(priv.getName());
+                    if (p != null) {
+                        bits |= p.getBits();
+                    } else if (!ignoreUnkown) {
+                        throw new AccessControlException("Unknown privilege '" + priv.getName() + "'.");
+                    }
+                }
+            }
+            return bits;
+        }
+
+        //---------------------------------------------------------< Object >---
+        public int hashCode() {
+            return getBits();
+        }
+
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof PrivilegeImpl) {
+                return getBits() == ((PrivilegeImpl) obj).getBits();
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Simple (non-aggregate) privilege.
+     */
+    private static class SimplePrivilege extends PrivilegeImpl {
+
+        private final int bits;
+
+        private SimplePrivilege(String name, String description, int bits) {
+            super(name, description);
+            this.bits = bits;
+        }
+
+        int getBits() {
+            return bits;
+        }
+
+        //------------------------------------------------------< Privilege >---
+
+        public boolean isAggregate() {
+            return false;
+        }
+
+        public Privilege[] getDeclaredAggregatePrivileges() {
+            return EMPTY_ARRAY;
+        }
+
+        public Privilege[] getAggregatePrivileges() {
+            return EMPTY_ARRAY;
+        }
+    }
+
+    /**
+     * Aggregate privilege
+     */
+    private static class AggregatePrivilege extends PrivilegeImpl {
+
+        private final Privilege[] declaredAggregates;
+        private final Set aggregates;
+        private final int bits;
+
+        private AggregatePrivilege(String name, String description, PrivilegeImpl[] declaredAggregates) {
+            super(name, description);
+            this.declaredAggregates = declaredAggregates;
+            Set aggrgt = new HashSet();
+            int bts = 0;
+            for (int i = 0; i < declaredAggregates.length; i++) {
+                PrivilegeImpl priv = declaredAggregates[i];
+                bts |= priv.getBits();
+                if (priv.isAggregate()) {
+                    aggrgt.addAll(Arrays.asList(priv.getAggregatePrivileges()));
+                } else {
+                    aggrgt.add(priv);
+                }
+            }
+            aggregates = Collections.unmodifiableSet(aggrgt);
+            bits = bts;
+        }
+
+        int getBits() {
+            return bits;
+        }
+
+        //------------------------------------------------------< Privilege >---
+        public boolean isAggregate() {
+            return true;
+        }
+
+        public Privilege[] getDeclaredAggregatePrivileges() {
+            return declaredAggregates;
+        }
+
+        public Privilege[] getAggregatePrivileges() {
+            return (Privilege[]) aggregates.toArray(new Privilege[aggregates.size()]);
+        }
+    }
+
+    /**
+     * The ALL privilege
+     */
+    private static class AllPrivilege extends PrivilegeImpl {
+
+        private AllPrivilege() {
+            super(Privilege.ALL, null);
+        }
+
+        int getBits() {
+            return PrivilegeRegistry.ALL;
+        }
+
+        //------------------------------------------------------< Privilege >---
+        public boolean isAggregate() {
+            return true;
+        }
+
+        public Privilege[] getDeclaredAggregatePrivileges() {
+            return getAggregatePrivileges();
+        }
+
+        public Privilege[] getAggregatePrivileges() {
+            Set all = new HashSet(REGISTERED_PRIVILEGES.values());
+            for (Iterator it = all.iterator(); it.hasNext();) {
+                Privilege priv = (Privilege) it.next();
+                if (priv.isAggregate()) {
+                    it.remove();
+                }
+            }
+            return (Privilege[]) all.toArray(new Privilege[all.size()]);
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,56 @@
+/*
+ * 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.security.JackrabbitSecurityManager;
+
+import javax.jcr.RepositoryException;
+import java.util.Set;
+
+/**
+ * The <code>WorkspaceAccessManager</code> is responsible for workspace access.
+ * In contrast to Items that are identified, workspaces are named Objects
+ * on different class hierarchy.
+ */
+public interface WorkspaceAccessManager {
+
+    /**
+     * Initialize this <code>WorkspaceAccessManager</code>.
+     *
+     * @param securityManager
+     * @throws RepositoryException if an error occurs.
+     */
+    void init(JackrabbitSecurityManager securityManager) throws RepositoryException;
+
+    /**
+     * Dispose this <code>WorkspaceAccessManager</code> and its resources.
+     *
+     * @throws RepositoryException if an error occurs.
+     */
+    void close() throws RepositoryException;
+
+    /**
+     * Returns true if access to the workspace with the given name is granted to
+     * the to any of the specified principals.
+     *
+     * @param principals
+     * @param workspaceName
+     * @return true if the given set of principals is allowed to access the
+     * workspace with the specified name. 
+     */
+    boolean grants(Set principals, String workspaceName) throws RepositoryException;
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java?rev=638834&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java Wed Mar 19 06:56:13 2008
@@ -0,0 +1,135 @@
+/*
+ * 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.acl;
+
+import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.security.authorization.PolicyEntry;
+import org.apache.jackrabbit.core.security.jsr283.security.Privilege;
+
+import java.security.Principal;
+
+/**
+ * Simple, immutable implementation of the
+ * {@link org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry}
+ * and the {@link PolicyEntry} interfaces.
+ * 
+ * @see PolicyEntry
+ */
+class ACEImpl implements PolicyEntry {
+
+    /**
+     * Privileges contained in this entry
+     */
+    private final int privileges;
+
+    /**
+     * if the actions contained are allowed or denied
+     */
+    private final boolean allow;
+
+    /**
+     * the Principal of this entry
+     */
+    private final Principal principal;
+
+    /**
+     * Hash code being calculated on demand.
+     */
+    private final int hashCode;
+
+    /**
+     * Construct an access control entry for the given principal, privileges and
+     * a polarity (deny or allow)
+     *
+     * @param principal
+     * @param privileges
+     * @param allow
+     */
+    ACEImpl(Principal principal, int privileges, boolean allow) {
+        this.principal = principal;
+        this.privileges = privileges;
+        this.allow = allow;
+
+        int h = 17;
+        h = 37 * h + principal.getName().hashCode();
+        h = 37 * h + privileges;
+        h = 37 * h + Boolean.valueOf(allow).hashCode();
+        hashCode = h;
+    }
+
+    /**
+     * @return the int representation of the privileges defined for this entry.
+     * @see #getPrivileges() 
+     */
+    int getPrivilegeBits() {
+        return privileges;
+    }
+
+    //-------------------------------------------------< AccessControlEntry >---
+    /**
+     * @see org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry#getPrincipal()
+     */
+    public Principal getPrincipal() {
+        return principal;
+    }
+
+    /**
+     * @see org.apache.jackrabbit.core.security.jsr283.security.AccessControlEntry#getPrivileges()
+     */
+    public Privilege[] getPrivileges() {
+        return PrivilegeRegistry.getPrivileges(privileges);
+    }
+
+    //--------------------------------------------------------< PolicyEntry >---
+    /**
+     * @see PolicyEntry#isAllow()
+     */
+    public boolean isAllow() {
+        return allow;
+    }
+
+    //-------------------------------------------------------------< Object >---
+    /**
+     * @see Object#hashCode()
+     */
+    public int hashCode() {
+        return hashCode;
+    }
+
+    /**
+     * Returns true if the principal, the allow-flag and all privileges are
+     * equal / the same.
+     *
+     * @param obj
+     * @return
+     * @see Object#equals(Object)
+     */
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj instanceof ACEImpl) {
+            ACEImpl tmpl = (ACEImpl) obj;
+            // TODO: check again if comparing principal-name is sufficient
+            return principal.getName().equals(tmpl.principal.getName()) &&
+                   allow == tmpl.allow &&
+                   privileges == tmpl.privileges;
+        }
+        return false;
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACEImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url