Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 65309 invoked from network); 19 Mar 2008 13:59:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 Mar 2008 13:59:20 -0000 Received: (qmail 89854 invoked by uid 500); 19 Mar 2008 13:59:12 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 89805 invoked by uid 500); 19 Mar 2008 13:59:12 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 89776 invoked by uid 99); 19 Mar 2008 13:59:12 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Mar 2008 06:59:12 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Mar 2008 13:58:19 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 57A861A984E; Wed, 19 Mar 2008 06:58:37 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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... Date: Wed, 19 Mar 2008 13:57:11 -0000 To: commits@jackrabbit.apache.org From: angela@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080319135837.57A861A984E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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; + +/** + * AbstractAccessControlProvider... + */ +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; + +/** + * AbstractCompiledPermissions... + */ +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; + +/** + * AccessControlConstants... + */ +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; + +/** + * AccessControlEditor 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 + * NodeId. In contrast to {@link #editPolicyTemplate} this method + * returns null 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. + *

+ * 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 null 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 + * NodeId. If the node does not yet have an policy set an + * new (empty) template is created (see also {@link #getPolicyTemplate(NodeId)}.
+ * The PolicyTemplate returned is detached from the underlying + * AccessControlProvider and is only an external + * representation. Modification will therefore not take effect, until it is + * written back to the editor and persisted. + *

+ * 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 PolicyTemplate to store. + * @throws AccessControlException If the PolicyTemplate is null 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 null + * 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 id, 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 id. + * @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 + * id. An implementation that always keeps entries with an + * existing AccessControlPolicy 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 + * template from the node identified by + * id. An implementation that always keeps entries with an + * existing AccessControlPolicy may choose to treat this + * method as short-cut for {@link #getPolicyTemplate(NodeId)} and + * subsequent template modification. + * Note that only PolicyEntrys 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 AccessControlManager that + * is bound to a specific session/subject. + *

+ * Please note following additional special conditions: + *

    + *
  • The detection of access control policy/entries is an implementation + * detail. They may be resource based or retrieved by other means.
  • + *
  • An access control policy/entry may be inherited across the item hierarchy. + * The details are left to the implementation
  • + *
  • If no policy can be determined for a particular Item the implementation + * must return some implementation specific default policy.
  • + *
  • Transient (NEW) items created within a regular Session object are unknown + * to and cannot be handled by the AccessControlProvider.
  • + *
  • If the item id passed to the corresponding calls doesn't point to an + * existing item, ItemNotFoundException 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.
  • + *
  • Changes to access control policy and entries made through the + * AccessControlEditor are not effective unless + * they are persisted by calling Session.save() on the session + * that has been used to obtain the editor.
  • + *
+ * + * @see AccessControlProviderFactory + */ +public interface AccessControlProvider { + + /** + * Allows the {@link AccessControlProviderFactory} to pass a session + * and configuration options to the AccessControlProvider. + * + * @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 nodeId. + * @throws ItemNotFoundException If no Node with the specified + * nodeId 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 nodeId. + * @throws ItemNotFoundException If no Node with the specified + * nodeId 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 AccessControlEditor for the given Session object + * or null if the implementation does not support editing + * of access control policies. + * + * @param session + * @return the ACL editor or null + */ + AccessControlEditor getEditor(Session session); + + /** + * Compiles the effective policy for the specified set of + * Principals. + * + * @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 + * nodeId 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 AccessControlProviderFactory 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}. + *

+ * 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. + *

+ * 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 AccessControlProviderFactory 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 null 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 + * AccessControlProvider should be created for. + * @param config The security configuration for that workspace or + * null if the config entry is present. In this case the + * factory must use its default. The configuration is used to determine + * the implementation of AccessControlProvider 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; + +/** + * CompiledPermissions represents the evaluation of an + * AccessControlPolicy that applies for a given set of + * Principals (normally obtained from the Subject + * of a Session). + */ +public interface CompiledPermissions { + + /** + * Indicate to this CompiledPermissions object that it is + * not used any more. + */ + void close(); + + /** + * Returns true if the specified permissions are granted + * on the item identified by the given path. + * + * @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 true if the specified permissions are granted, + * false 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 Privileges granted by the underlying policy + * if the given absPath denotes an existing Node, + * otherwise it returns zero. + * + * @return the granted privileges at absPath or zero if + * the path does not denote an existing Node. + */ + 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; + +/** + * GlobPattern... 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; + +/** + * Permission... + */ +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 + * protectesPolicy is true 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 permissions that are not present in + * the otherPermissions, i.e. subtracts the other permissions + * from permissions.
+ * If the specified otherBits do not intersect with + * bits, bits are returned.
+ * If bits is included otherBits, + * {@link #NONE} is returned. + * + * @param permissions + * @param otherPermissions + * @return the differences of the 2 permissions or {@link #NONE}. + */ + 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}

+ * 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 Privileges 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 true 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 + * PolicyTemplate. + * + * @return the {@link PolicyEntry entries} present in this + * PolicyTemplate. + */ + PolicyEntry[] getEntries(); + + /** + * Set the parameters defined by the given entry to this + * policy template. If this policy already contains that entry this method + * will return false. 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 PolicyEntry 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 PrivilegeSet 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 privilegeNames + * are null, 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 Privileges. If the specified + * bits 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 + * bits. If bits is {@link #NO_PRIVILEGE 0} or + * does not match to any registered privilege an empty array will be returned. + * + * @param bits + * @return Array of Privileges that are presented by the given it + * or an empty array if bits is lower than {@link #READ} or + * cannot be resolved to registered Privileges. + */ + 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 bits that are not present in + * the otherBits, i.e. subtracts the other privileges from + * this one.
+ * If the specified otherBits do not intersect with + * bits, bits are returned.
+ * If bits is included otherBits, + * {@link #NO_PRIVILEGE} is returned. + * + * @param bits + * @param otherBits + * @return the differences of the 2 privileges or {@link #NO_PRIVILEGE}. + */ + 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 PrivilegeRegistry. + */ + 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 ignoreUnkown 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 WorkspaceAccessManager 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 WorkspaceAccessManager. + * + * @param securityManager + * @throws RepositoryException if an error occurs. + */ + void init(JackrabbitSecurityManager securityManager) throws RepositoryException; + + /** + * Dispose this WorkspaceAccessManager 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