jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1421458 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: security/authorization/ security/authorization/restriction/ spi/security/authorization/ spi/security/authorization/restriction/ spi/xml/
Date Thu, 13 Dec 2012 19:56:46 GMT
Author: angela
Date: Thu Dec 13 19:56:44 2012
New Revision: 1421458

URL: http://svn.apache.org/viewvc?rev=1421458&view=rev
Log:
OAK-51 : Access Control Management

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlImporter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionImpl.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlHook.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/PermissionValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACE.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACL.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionDefinition.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/PropInfo.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/TextValue.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java Thu Dec 13 19:56:44 2012
@@ -25,6 +25,7 @@ import javax.jcr.security.AccessControlM
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionProviderImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
 import org.apache.jackrabbit.oak.spi.security.Context;
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
@@ -32,6 +33,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authorization.PermissionProvider;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
 
 /**
  * {@code AccessControlConfigurationImpl} ... TODO
@@ -51,6 +53,12 @@ public class AccessControlConfigurationI
         return AccessControlContext.getInstance();
     }
 
+    @Nonnull
+    @Override
+    public List<ProtectedItemImporter> getProtectedItemImporters() {
+        return Collections.<ProtectedItemImporter>singletonList(new AccessControlImporter(securityProvider));
+    }
+
     //-----------------------------------------< AccessControlConfiguration >---
     @Override
     public AccessControlManager getAccessControlManager(Root root, NamePathMapper namePathMapper) {
@@ -69,11 +77,11 @@ public class AccessControlConfigurationI
         return new PermissionProviderImpl();
     }
 
-//    @Nonnull
-//    @Override
-//    public List<CommitHook> getCommitHooks() {
-//        return Collections.<CommitHook>singletonList(new AccessControlHook());
-//    }
+    @Nonnull
+    @Override
+    public List<CommitHook> getCommitHooks() {
+        return Collections.<CommitHook>singletonList(new AccessControlHook());
+    }
 
     @Override
     public List<ValidatorProvider> getValidatorProviders() {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java Thu Dec 13 19:56:44 2012
@@ -30,6 +30,10 @@ public interface AccessControlConstants 
     String REP_PRIVILEGES = "rep:privileges";
     String REP_PRINCIPAL_NAME = "rep:principalName";
     String REP_GLOB = "rep:glob";
+    String REP_NODE_PATH = "rep:nodePath";
+    /**
+     * @since OAK 1.0
+     */
     String REP_RESTRICTIONS = "rep:restrictions";
 
 
@@ -40,6 +44,9 @@ public interface AccessControlConstants 
     String NT_REP_ACE = "rep:ACE";
     String NT_REP_GRANT_ACE = "rep:GrantACE";
     String NT_REP_DENY_ACE = "rep:DenyACE";
+    /**
+     * @since OAK 1.0
+     */
     String NT_REP_RESTRICTIONS = "rep:Restrictions";
 
     Collection<String> AC_PROPERTY_NAMES = ImmutableSet.of(REP_PRINCIPAL_NAME, REP_PRIVILEGES, REP_GLOB);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlHook.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlHook.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlHook.java Thu Dec 13 19:56:44 2012
@@ -32,7 +32,7 @@ public class AccessControlHook implement
     @Nonnull
     @Override
     public NodeState processCommit(NodeState before, NodeState after) throws CommitFailedException {
-        // TODO
-        throw new UnsupportedOperationException("not yet implemented");
+        // TODO: add implementation
+        return after;
     }
 }
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlImporter.java?rev=1421458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlImporter.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlImporter.java Thu Dec 13 19:56:44 2012
@@ -0,0 +1,269 @@
+/*
+ * 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.oak.security.authorization;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
+import org.apache.jackrabbit.oak.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.oak.spi.xml.NodeInfo;
+import org.apache.jackrabbit.oak.spi.xml.PropInfo;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedNodeImporter;
+import org.apache.jackrabbit.oak.spi.xml.ReferenceChangeTracker;
+import org.apache.jackrabbit.oak.spi.xml.TextValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * AccessControlImporter... TODO
+ */
+class AccessControlImporter implements ProtectedNodeImporter, AccessControlConstants {
+
+    private static final Logger log = LoggerFactory.getLogger(AccessControlImporter.class);
+
+    private static final int CHILD_STATUS_UNDEFINED = 0;
+    private static final int CHILD_STATUS_ACE = 1;
+    private static final int CHILD_STATUS_RESTRICTION = 2;
+
+    private final SecurityProvider securityProvider;
+
+    private NamePathMapper namePathMapper;
+    private AccessControlManager acMgr;
+    private PrincipalProvider principalProvider;
+    private ReadOnlyNodeTypeManager ntMgr;
+
+    private boolean initialized = false;
+    private int childStatus;
+
+    private JackrabbitAccessControlList acl;
+    private MutableEntry entry;
+
+    AccessControlImporter(SecurityProvider securityProvider) {
+        this.securityProvider = securityProvider;
+    }
+
+    //----------------------------------------------< ProtectedItemImporter >---
+
+    @Override
+    public boolean init(Session session, Root root, NamePathMapper namePathMapper, boolean isWorkspaceImport, int uuidBehavior, ReferenceChangeTracker referenceTracker) {
+        if (initialized) {
+            throw new IllegalStateException("Already initialized");
+        }
+        try {
+            this.namePathMapper = namePathMapper;
+            AccessControlConfiguration config = securityProvider.getAccessControlConfiguration();
+            if (isWorkspaceImport) {
+                acMgr = config.getAccessControlManager(root, namePathMapper);
+            } else {
+                acMgr = session.getAccessControlManager();
+            }
+            principalProvider = securityProvider.getPrincipalConfiguration().getPrincipalProvider(root, namePathMapper);
+            ntMgr = ReadOnlyNodeTypeManager.getInstance(root, namePathMapper);
+            initialized = true;
+        } catch (RepositoryException e) {
+            log.warn("Error while initializing access control importer", e);
+        }
+        return initialized;
+    }
+
+    @Override
+    public void processReferences() throws RepositoryException {
+        // nothing to do.
+    }
+
+    //----------------------------------------------< ProtectedNodeImporter >---
+
+    @Override
+    public boolean start(Tree protectedParent) throws IllegalStateException, RepositoryException {
+        checkInitialized();
+
+        // the acl node must have been added during the regular inport before
+        // this importer is only successfully started if an valid ACL was created.
+        acl = getACL(protectedParent);
+        return acl != null;
+    }
+
+    @Override
+    public void end(Tree protectedParent) throws RepositoryException {
+        if (acl != null) {
+            acMgr.setPolicy(acl.getPath(), acl);
+            acl = null;
+        } else {
+            throw new IllegalStateException("End reached without ACL to write back.");
+        }
+    }
+
+    @Override
+    public void startChildInfo(NodeInfo childInfo, List<PropInfo> propInfos) throws RepositoryException {
+        checkInitialized();
+        String ntName = childInfo.getPrimaryTypeName();
+        if (NT_REP_GRANT_ACE.equals(ntName) || NT_REP_DENY_ACE.equals(ntName)) {
+            if (entry != null) {
+                throw new ConstraintViolationException("Invalid child node sequence: ACEs may not be nested.");
+            }
+            entry = new MutableEntry(NT_REP_GRANT_ACE.equals(ntName));
+            for (PropInfo prop : propInfos) {
+                String name = prop.getName();
+                if (REP_PRINCIPAL_NAME.equals(name)) {
+                    entry.setPrincipal(prop.getTextValue());
+                } else if (REP_PRIVILEGES.equals(name)) {
+                    entry.setPrivilegeNames(prop.getTextValues());
+                } else {
+                    entry.addRestriction(prop);
+                }
+            }
+            childStatus = CHILD_STATUS_ACE;
+        } else if (NT_REP_RESTRICTIONS.equals(ntName)) {
+            if (entry == null) {
+                throw new ConstraintViolationException("Invalid child node sequence: Restriction must be associated with an ACE");
+            }
+            entry.addRestrictions(propInfos);
+            childStatus = CHILD_STATUS_RESTRICTION;
+        } else {
+            throw new ConstraintViolationException("Invalid child node with type " + ntName);
+        }
+    }
+
+    @Override
+    public void endChildInfo() throws RepositoryException {
+        checkInitialized();
+        switch (childStatus) {
+            case CHILD_STATUS_ACE:
+                // write the ace to the policy
+                entry.applyTo(acl);
+                entry = null;
+                childStatus = CHILD_STATUS_UNDEFINED;
+                break;
+            case CHILD_STATUS_RESTRICTION:
+                // back to ace status
+                childStatus = CHILD_STATUS_ACE;
+                break;
+            default:
+                throw new ConstraintViolationException("Invalid child node sequence.");
+        }
+    }
+
+    //------------------------------------------------------------< private >---
+    private void checkInitialized() {
+        if (!initialized) {
+            throw new IllegalStateException("Not initialized");
+        }
+    }
+
+    @CheckForNull
+    private JackrabbitAccessControlList getACL(Tree tree) throws RepositoryException {
+        String nodeName = tree.getName();
+        Tree parent = tree.getParent();
+
+        if (parent != null) {
+            if (AccessControlConstants.REP_POLICY.equals(nodeName)
+                    && ntMgr.isNodeType(tree, AccessControlConstants.NT_REP_ACL)) {
+                return getACL(parent.getPath());
+            } else if (AccessControlConstants.REP_REPO_POLICY.equals(nodeName)
+                    && ntMgr.isNodeType(tree, AccessControlConstants.NT_REP_ACL)
+                    && parent.isRoot()) {
+                return getACL((String) null);
+            }
+        }
+
+        return null;
+    }
+
+    @CheckForNull
+    private JackrabbitAccessControlList getACL(String path) throws RepositoryException {
+        JackrabbitAccessControlList acl = null;
+        for (AccessControlPolicy p: acMgr.getPolicies(path)) {
+            if (p instanceof JackrabbitAccessControlList) {
+                acl = (JackrabbitAccessControlList) p;
+                break;
+            }
+        }
+        return acl;
+    }
+
+    //--------------------------------------------------------------------------
+    private class MutableEntry {
+
+        final boolean isAllow;
+        Principal principal;
+        List<Privilege> privileges;
+        Map<String, Value> restrictions = new HashMap<String, Value>();
+
+        private MutableEntry(boolean isAllow) {
+            this.isAllow = isAllow;
+        }
+
+        private void setPrincipal(TextValue txtValue) {
+            String principalName = txtValue.getString();
+            principal = principalProvider.getPrincipal(principalName);
+            // TODO: review handling of unknown principals
+            if (principal == null) {
+                principal = new PrincipalImpl(principalName);
+            }
+        }
+
+        private void setPrivilegeNames(TextValue[] txtValues) throws RepositoryException {
+            privileges = new ArrayList<Privilege>();
+            for (TextValue value : txtValues) {
+                // FIXME: proper namespace handling (in case of local remapping)
+                Value privilegeName = value.getValue(PropertyType.NAME, namePathMapper);
+                privileges.add(acMgr.privilegeFromName(privilegeName.getString()));
+            }
+        }
+
+        private void addRestriction(PropInfo propInfo) throws RepositoryException {
+            // FIXME: proper namespace handling (in case of local remapping)
+            String restrictionName = propInfo.getName();
+            int targetType = acl.getRestrictionType(restrictionName);
+            // FIXME: proper namespace handling (in case of local remapping)
+            restrictions.put(propInfo.getName(), propInfo.getValue(targetType, namePathMapper));
+        }
+
+        private void addRestrictions(List<PropInfo> propInfos) throws RepositoryException {
+            for (PropInfo prop : propInfos) {
+                addRestriction(prop);
+            }
+        }
+
+        private void applyTo(JackrabbitAccessControlList acl) throws RepositoryException {
+            checkNotNull(acl);
+            acl.addEntry(principal, privileges.toArray(new Privilege[privileges.size()]), isAllow, restrictions);
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java?rev=1421458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java Thu Dec 13 19:56:44 2012
@@ -0,0 +1,559 @@
+/*
+ * 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.oak.security.authorization;
+
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.Query;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.PropertyValue;
+import org.apache.jackrabbit.oak.api.QueryEngine;
+import org.apache.jackrabbit.oak.api.Result;
+import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryPropertyBuilder;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
+import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
+import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionDefinitionImpl;
+import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionImpl;
+import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionProviderImpl;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.ACE;
+import org.apache.jackrabbit.oak.spi.security.authorization.ACL;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.oak.spi.state.PropertyBuilder;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AccessControlManagerImpl... TODO
+ */
+public class AccessControlManagerImpl implements JackrabbitAccessControlManager, AccessControlConstants {
+
+    private static final Logger log = LoggerFactory.getLogger(AccessControlManagerImpl.class);
+
+    private final Root root;
+    private final NamePathMapper namePathMapper;
+    private final SecurityProvider securityProvider;
+
+    private final PrivilegeManager privilegeManager;
+    private final PrincipalProvider principalProvider;
+    private final RestrictionProvider restrictionProvider;
+    private final ReadOnlyNodeTypeManager ntMgr;
+
+    public AccessControlManagerImpl(Root root, NamePathMapper namePathMapper,
+                                    SecurityProvider securityProvider) {
+        this.root = root;
+        this.namePathMapper = namePathMapper;
+        this.securityProvider = securityProvider;
+
+        privilegeManager = securityProvider.getPrivilegeConfiguration().getPrivilegeManager(root, namePathMapper);
+        principalProvider = securityProvider.getPrincipalConfiguration().getPrincipalProvider(root, namePathMapper);
+        restrictionProvider = securityProvider.getAccessControlConfiguration().getRestrictionProvider(namePathMapper);
+        ntMgr = ReadOnlyNodeTypeManager.getInstance(root, namePathMapper);
+    }
+
+    //-----------------------------------------------< AccessControlManager >---
+    @Override
+    public Privilege[] getSupportedPrivileges(String absPath) throws RepositoryException {
+        checkValidPath(absPath);
+        return privilegeManager.getRegisteredPrivileges();
+    }
+
+    @Override
+    public Privilege privilegeFromName(String privilegeName) throws RepositoryException {
+        return privilegeManager.getPrivilege(privilegeName);
+    }
+
+    @Override
+    public boolean hasPrivileges(String absPath, Privilege[] privileges) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+
+        // TODO
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public Privilege[] getPrivileges(String absPath) throws PathNotFoundException, RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+
+        // TODO
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public AccessControlPolicy[] getPolicies(String absPath) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+        checkIsAccessControlContent(tree);
+
+        AccessControlPolicy policy = readAccessControlPolicy(absPath, tree);
+        if (policy != null) {
+            return new AccessControlPolicy[] {policy};
+        } else {
+            return new AccessControlPolicy[0];
+        }
+    }
+
+    @Override
+    public AccessControlPolicy[] getEffectivePolicies(String absPath) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+        checkIsAccessControlContent(tree);
+
+        List<AccessControlPolicy> effective = new ArrayList<AccessControlPolicy>();
+        AccessControlPolicy policy = readAccessControlPolicy(absPath, tree);
+        if (policy != null) {
+            effective.add(policy);
+        }
+        if (absPath != null) {
+            String parentPath = Text.getRelativeParent(tree.getPath(), 1);
+            while (!parentPath.isEmpty()) {
+                Tree t = root.getTree(parentPath);
+                AccessControlPolicy plc = readAccessControlPolicy(parentPath, t);
+                if (plc != null) {
+                    effective.add(plc);
+                }
+                parentPath = (PathUtils.denotesRoot(parentPath)) ? "" : Text.getRelativeParent(parentPath, 1);
+            }
+        }
+        return effective.toArray(new AccessControlPolicy[effective.size()]);
+    }
+
+    @Override
+    public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+        checkIsAccessControlContent(tree);
+
+        AccessControlPolicy policy = null;
+        NodeUtil aclNode = getAclNode(absPath, tree);
+        if (aclNode == null) {
+            // create an empty acl unless the node is protected or cannot have
+            // mixin set (e.g. due to a lock) or
+            // has colliding rep:policy or rep:repoPolicy child node set.
+            String aclName = getAclName(absPath);
+            if (tree.hasChild(aclName)) {
+                // policy child node without node being access controlled
+                log.warn("Colliding policy child without node being access controllable ({}).", absPath);
+            } else {
+                String mixinName = getMixinName(absPath);
+                if (ntMgr.isNodeType(tree, mixinName) || ntMgr.getEffectiveNodeType(tree).supportsMixin(mixinName)) {
+                    policy = new ACL(absPath, restrictionProvider, namePathMapper);
+                } else {
+                    log.warn("Node {} cannot be made access controllable.", absPath);
+                }
+            }
+        } // else: acl already present -> getPolicies must be used.
+
+        if (policy == null) {
+            return AccessControlPolicyIteratorAdapter.EMPTY;
+        } else {
+            return new AccessControlPolicyIteratorAdapter(Collections.singleton(policy));
+        }
+    }
+
+    @Override
+    public void setPolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+        checkIsAccessControlContent(tree);
+        checkValidPolicy(absPath, policy);
+
+        NodeUtil aclNode = getAclNode(absPath, tree);
+        if (aclNode != null) {
+            // remove all existing aces
+            for (Tree aceTree : aclNode.getTree().getChildren()) {
+                aceTree.remove();
+            }
+        } else {
+            aclNode = createAclTree(absPath, tree);
+        }
+
+        ACL acl = (ACL) policy;
+        for (ACE ace : acl.getACEs()) {
+            String nodeName = generateAceName(aclNode, ace.isAllow());
+            String ntName = (ace.isAllow()) ? NT_REP_GRANT_ACE : NT_REP_DENY_ACE;
+
+            NodeUtil aceNode = aclNode.addChild(nodeName, ntName);
+            aceNode.setString(REP_PRINCIPAL_NAME, ace.getPrincipal().getName());
+            aceNode.setNames(REP_PRIVILEGES, ace.getPrivilegeNames());
+            restrictionProvider.writeRestrictions(absPath, aceNode.getTree(), ace.getRestrictionSet());
+        }
+    }
+
+    @Override
+    public void removePolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+        checkIsAccessControlContent(tree);
+        checkValidPolicy(absPath, policy);
+
+        NodeUtil aclNode = getAclNode(absPath, tree);
+        if (aclNode != null) {
+            aclNode.getTree().remove();
+        } else {
+            throw new AccessControlException("No policy to remove at " + absPath);
+        }
+    }
+
+    //-------------------------------------< JackrabbitAccessControlManager >---
+    @Override
+    public JackrabbitAccessControlPolicy[] getApplicablePolicies(Principal principal) throws RepositoryException {
+        Result aceResult = searchAces(Collections.<Principal>singleton(principal));
+        if (aceResult.getSize() > 0) {
+            return new JackrabbitAccessControlPolicy[0];
+        } else {
+            return new JackrabbitAccessControlPolicy[] {getPrincipalACL(principal, null)};
+        }
+    }
+
+    @Override
+    public JackrabbitAccessControlPolicy[] getPolicies(Principal principal) throws RepositoryException {
+        Result aceResult = searchAces(Collections.<Principal>singleton(principal));
+        if (aceResult.getSize() > 0) {
+            return new JackrabbitAccessControlPolicy[] {getPrincipalACL(principal, aceResult)};
+        } else {
+            return new JackrabbitAccessControlPolicy[0];
+        }
+    }
+
+    @Override
+    public AccessControlPolicy[] getEffectivePolicies(Set<Principal> principals) throws RepositoryException {
+        Result aceResult = searchAces(principals);
+        List<AccessControlPolicy> effective = new ArrayList<AccessControlPolicy>();
+        for (ResultRow row : aceResult.getRows()) {
+            Tree aclTree = root.getTree(row.getPath()).getParent();
+            Tree accessControlledTree = aclTree.getParent();
+
+            String path = (REP_REPO_POLICY.equals(aclTree.getName())) ? null : accessControlledTree.getPath();
+            AccessControlPolicy policy = readAccessControlPolicy(path, accessControlledTree);
+            if (policy != null) {
+                effective.add(policy);
+            }
+        }
+        return effective.toArray(new AccessControlPolicy[effective.size()]);
+    }
+
+    @Override
+    public boolean hasPrivileges(String absPath, Set<Principal> principals, Privilege[] privileges) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+
+        // TODO
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public Privilege[] getPrivileges(String absPath, Set<Principal> principals) throws RepositoryException {
+        Tree tree = getTree(absPath);
+        checkPermission(tree);
+
+        // TODO
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    //------------------------------------------------------------< private >---
+    @CheckForNull
+    private String getOakPath(String absJcrPath) throws RepositoryException {
+        if (absJcrPath == null) {
+            return null; // repository level
+        }
+        String oakPath = namePathMapper.getOakPath(absJcrPath);
+        if (oakPath == null) {
+            throw new RepositoryException("Failed to resolve JCR path " + absJcrPath);
+        }
+        return oakPath;
+    }
+
+    @CheckForNull
+    private Tree getTree(String jcrPath) throws RepositoryException {
+        Tree tree = (jcrPath == null) ? root.getTree("/") : root.getTree(getOakPath(jcrPath));
+        if (tree == null) {
+            throw new PathNotFoundException("No tree at " +jcrPath);
+        }
+        return tree;
+    }
+
+    private void checkValidPath(String jcrPath) throws RepositoryException {
+        getTree(getOakPath(jcrPath));
+    }
+
+    /**
+     * Check if the specified tree is itself defines access control related
+     * content.
+     *
+     * @param tree the target tree
+     * @throws AccessControlException If the tree represents a ACL or ACE item.
+     */
+    private static void checkIsAccessControlContent(Tree tree) throws AccessControlException {
+        String ntName = new NodeUtil(tree).getPrimaryNodeTypeName();
+        if (AC_NODE_TYPE_NAMES.contains(ntName)) {
+            throw new AccessControlException("Tree " + tree.getPath() + " defines access control content.");
+        }
+    }
+
+    private void checkPermission(Tree tree) throws AccessDeniedException {
+        // TODO
+    }
+
+    private void checkValidPolicy(String jcrPath, AccessControlPolicy policy) throws AccessControlException {
+        // TODO
+        // TODO: make sure policy is jackrabbit acl
+        // TODO: make sure path matches path of policy
+    }
+
+    private boolean isAccessControlled(Tree tree, String nodeTypeName) throws RepositoryException {
+        return tree != null && ntMgr.isNodeType(tree, nodeTypeName);
+    }
+
+    private boolean isACE(Tree tree) throws RepositoryException {
+        return ntMgr.isNodeType(tree, NT_REP_ACE);
+    }
+
+    @CheckForNull
+    private AccessControlPolicy readAccessControlPolicy(String jcrPath, Tree accessControlledTree) throws RepositoryException {
+        AccessControlPolicy acl = null;
+        String aclName = getAclName(jcrPath);
+        String mixinName = getMixinName(jcrPath);
+        if (isAccessControlled(accessControlledTree, mixinName) && accessControlledTree.hasChild(aclName)) {
+            Tree aclTree = accessControlledTree.getChild(aclName);
+            List<ACE> entries = new ArrayList<ACE>();
+            for (Tree child : aclTree.getChildren()) {
+                if (isACE(child)) {
+                    entries.add(readAccessControlEntry(jcrPath, child, restrictionProvider));
+                }
+            }
+            acl = new ACL(jcrPath, entries, restrictionProvider, namePathMapper);
+        }
+        return acl;
+    }
+
+    @Nonnull
+    private ACE readAccessControlEntry(String jcrPath, Tree aceTree,
+                                       RestrictionProvider restrictionProvider) throws RepositoryException {
+        NodeUtil aceNode = new NodeUtil(aceTree);
+        Principal principal = principalProvider.getPrincipal(aceNode.getString(REP_PRINCIPAL_NAME, null));
+        boolean isAllow = aceNode.hasPrimaryNodeTypeName(NT_REP_GRANT_ACE);
+        Set<Restriction> restrictions = restrictionProvider.readRestrictions(jcrPath, aceTree);
+        return new ACE(principal, getPrivileges(aceNode), isAllow, restrictions, namePathMapper);
+    }
+
+    @Nonnull
+    private ACL getPrincipalACL(Principal principal, Result aceResult) throws RepositoryException {
+        // TODO: specific path indicating the principal-based nature of the
+        // TODO: ACL... this could also be the path of the compiled permissions
+        // TODO: for this principal.
+        String principalBasedPath = null;
+        // TODO: specific principal based restriction provider specifying a
+        // TODO: mandatory 'path' restriction to enforce the location where
+        // TODO: the ACEs need to be stored in the content tree.
+        RestrictionProvider pbRestrictions = new PrincipalRestrictionProvider(namePathMapper);
+
+        List<ACE> entries = null;
+        if (aceResult != null) {
+            entries = new ArrayList();
+            for (ResultRow row : aceResult.getRows()) {
+                Tree aceTree = root.getTree(row.getPath());
+                if (isACE(aceTree)) {
+                    String aclPath = Text.getRelativeParent(aceTree.getPath(), 1);
+                    String jcrPath;
+                    if (aclPath.endsWith(REP_REPO_POLICY)) {
+                        jcrPath = null;
+                    } else {
+                        jcrPath = Text.getRelativeParent(aclPath, 1);
+                    }
+                    entries.add(readAccessControlEntry(jcrPath, aceTree, pbRestrictions));
+                }
+            }
+        }
+        return new ACL(principalBasedPath, entries, pbRestrictions, namePathMapper);
+    }
+
+    /**
+     *
+     * @param jcrPath the JCR path as specified with the ac mgr call.
+     * @param tree the access controlled node.
+     * @return the new acl tree.
+     * @throws RepositoryException if an error occurs
+     */
+    @Nonnull
+    private NodeUtil createAclTree(String jcrPath, Tree tree) throws RepositoryException {
+        NodeUtil node = new NodeUtil(tree);
+        String mixinName = getMixinName(jcrPath);
+        if (!isAccessControlled(tree, mixinName)) {
+            PropertyState mixins = tree.getProperty(JcrConstants.JCR_MIXINTYPES);
+            if (mixins == null) {
+                tree.setProperty(JcrConstants.JCR_MIXINTYPES, Collections.singleton(mixinName), Type.NAMES);
+            } else {
+                PropertyBuilder pb = MemoryPropertyBuilder.copy(Type.NAME, mixins);
+                pb.addValue(mixinName);
+                tree.setProperty(pb.getPropertyState());
+            }
+        }
+        return node.addChild(getAclName(jcrPath), NT_REP_ACL);
+    }
+
+    @Nonnull
+    private Result searchAces(Set<Principal> principals) throws RepositoryException {
+        // TODO: review if compiled permissions could be used instead of running a query.
+        // TODO: replace XPATH
+        // TODO: specify sort order
+        StringBuilder stmt = new StringBuilder("/jcr:root");
+        stmt.append("//element(*,");
+        stmt.append(NT_REP_ACE);
+        stmt.append(")[");
+        int i = 0;
+        for (Principal principal : principals) {
+            if (i > 0) {
+                stmt.append(" or ");
+            }
+            stmt.append('@');
+            stmt.append(ISO9075.encode(REP_PRINCIPAL_NAME));
+            stmt.append("='");
+            stmt.append(principal.getName().replaceAll("'", "''"));
+            stmt.append('\'');
+            i++;
+        }
+        stmt.append(']');
+
+        try {
+            QueryEngine queryEngine = root.getQueryEngine();
+            return queryEngine.executeQuery(stmt.toString(), Query.XPATH, Long.MAX_VALUE, 0, Collections.<String, PropertyValue>emptyMap(), NamePathMapper.DEFAULT);
+        } catch (ParseException e) {
+            String msg = "Error while collecting effective policies.";
+            log.error(msg, e.getMessage());
+            throw new RepositoryException(msg, e);
+        }
+    }
+
+    @Nonnull
+    private Set<Privilege> getPrivileges(NodeUtil aceNode) throws RepositoryException {
+        String[] privNames = aceNode.getNames(REP_PRIVILEGES);
+        Set<Privilege> privileges = new HashSet<Privilege>(privNames.length);
+        for (String name : privNames) {
+            privileges.add(privilegeManager.getPrivilege(name));
+        }
+        return privileges;
+    }
+
+    @CheckForNull
+    private static NodeUtil getAclNode(String jcrPath, Tree accessControlledTree) {
+        Tree policyTree = accessControlledTree.getChild(getAclName(jcrPath));
+        return (policyTree == null) ? null : new NodeUtil(policyTree);
+    }
+
+    @Nonnull
+    private static String getMixinName(String jcrPath) {
+        return (jcrPath == null) ? MIX_REP_REPO_ACCESS_CONTROLLABLE : MIX_REP_ACCESS_CONTROLLABLE;
+    }
+
+    @Nonnull
+    private static String getAclName(String jcrPath) {
+        return (jcrPath == null) ? REP_REPO_POLICY : REP_POLICY;
+    }
+
+    /**
+     * Create a unique valid name for the Permission nodes to be save.
+     *
+     * @param aclNode a name for the child is resolved
+     * @param isAllow If the ACE is allowing or denying.
+     * @return the name of the ACE node.
+     */
+    @Nonnull
+    public static String generateAceName(NodeUtil aclNode, boolean isAllow) {
+        int i = 0;
+        String hint = (isAllow) ? "allow" : "deny";
+        String aceName = hint;
+        while (aclNode.hasChild(aceName)) {
+            aceName = hint + i;
+            i++;
+        }
+        return aceName;
+    }
+
+    // TODO review again.
+    private static class PrincipalRestrictionProvider extends RestrictionProviderImpl {
+
+        private PrincipalRestrictionProvider(NamePathMapper namePathMapper) {
+            super(namePathMapper);
+        }
+
+        @Nonnull
+        @Override
+        public Set<RestrictionDefinition> getSupportedRestrictions(String jcrPath) {
+            Set<RestrictionDefinition> definitions = new HashSet<RestrictionDefinition>(super.getSupportedRestrictions(jcrPath));
+            definitions.add(new RestrictionDefinitionImpl(REP_NODE_PATH, PropertyType.PATH, true));
+            return definitions;
+        }
+
+        @Override
+        public Set<Restriction> readRestrictions(String jcrPath, Tree aceTree) throws AccessControlException {
+            Set<Restriction> restrictions = super.readRestrictions(jcrPath, aceTree);
+            String value = (jcrPath == null) ? "" : jcrPath;
+            PropertyState nodePathProp = PropertyStates.createProperty(REP_NODE_PATH, value, Type.PATH);
+            restrictions.add(new RestrictionImpl(nodePathProp, PropertyType.PATH, true));
+            return restrictions;
+        }
+
+        @Override
+        public void writeRestrictions(String jcrPath, Tree aceTree, Set<Restriction> restrictions) throws AccessControlException {
+            Iterator<Restriction> it = restrictions.iterator();
+            while (it.hasNext()) {
+                Restriction r = it.next();
+                if (REP_NODE_PATH.equals(r.getName())) {
+                    it.remove();
+                }
+            }
+            super.writeRestrictions(jcrPath, aceTree, restrictions);
+        }
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorProvider.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlValidatorProvider.java Thu Dec 13 19:56:44 2012
@@ -21,9 +21,11 @@ import javax.annotation.Nonnull;
 
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.core.ReadOnlyTree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.spi.commit.Validator;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AccessControlConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinitionReader;
@@ -54,7 +56,8 @@ class AccessControlValidatorProvider imp
 
         PrivilegeDefinitionReader reader = securityProvider.getPrivilegeConfiguration().getPrivilegeDefinitionReader(treeBefore);
         Map<String, PrivilegeDefinition> privilegeDefinitions = reader.readDefinitions();
-        RestrictionProvider restrictionProvider = null; // TODO
+        AccessControlConfiguration acConfig = securityProvider.getAccessControlConfiguration();
+        RestrictionProvider restrictionProvider = acConfig.getRestrictionProvider(NamePathMapper.DEFAULT);
         return new AccessControlValidator(rootBefore, rootAfter, privilegeDefinitions, restrictionProvider);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/PermissionValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/PermissionValidator.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/PermissionValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/PermissionValidator.java Thu Dec 13 19:56:44 2012
@@ -118,7 +118,7 @@ class PermissionValidator implements Val
         } else if (isVersionProperty(parent, property)) {
             permission = Permissions.VERSION_MANAGEMENT;
             // FIXME: path to check for permission must be adjusted to be
-            //        the one of the versionable node instead of the target parent.
+            // FIXME: the one of the versionable node instead of the target parent in case of version-store is affected.
         } else if (provider.getPrivilegeContext().definesProperty(parentTree, property)) {
             permission = Permissions.PRIVILEGE_MANAGEMENT;
         } else if (provider.getAccessControlContext().definesProperty(parentTree, property)) {
@@ -129,7 +129,7 @@ class PermissionValidator implements Val
             permission = defaultPermission;
         }
 
-        checkPermissions(parent.getTree(), property, permission);
+        checkPermissions(parentTree, property, permission);
     }
 
     private Validator checkPermissions(NodeUtil node, boolean isBefore, int defaultPermission) throws CommitFailedException {
@@ -144,7 +144,7 @@ class PermissionValidator implements Val
         } else if (isVersion(node)) {
             permission = Permissions.VERSION_MANAGEMENT;
             // FIXME: path to check for permission must be adjusted to be
-            // //     the one of the versionable node instead of the target node.
+            // FIXME: the one of the versionable node instead of the target parent in case of version-store is affected.
         } else if (provider.getPrivilegeContext().definesTree(tree)) {
             permission = Permissions.PRIVILEGE_MANAGEMENT;
         } else if (provider.getAccessControlContext().definesTree(tree)) {

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionImpl.java?rev=1421458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionImpl.java Thu Dec 13 19:56:44 2012
@@ -0,0 +1,42 @@
+/*
+ * 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.oak.security.authorization.restriction;
+
+/**
+ * {@code RestrictionImpl}
+ */
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
+
+public class RestrictionImpl extends RestrictionDefinitionImpl implements Restriction {
+
+    private final PropertyState property;
+
+    public RestrictionImpl(@Nonnull PropertyState property, int requiredType, boolean isMandatory) {
+        super(property.getName(), requiredType, isMandatory);
+        this.property = property;
+    }
+
+    @Nonnull
+    @Override
+    public PropertyState getProperty() {
+        return property;
+    }
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java Thu Dec 13 19:56:44 2012
@@ -37,6 +37,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
 import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.jackrabbit.util.Text;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
 
 /**
  * RestrictionProviderImpl... TODO
@@ -54,8 +55,8 @@ public class RestrictionProviderImpl imp
 
     @Nonnull
     @Override
-    public Set<RestrictionDefinition> getSupportedRestrictions(String path) {
-        if (path == null) {
+    public Set<RestrictionDefinition> getSupportedRestrictions(String jcrPath) {
+        if (jcrPath == null) {
             return Collections.emptySet();
         } else {
             return ImmutableSet.copyOf(supported.values());
@@ -63,9 +64,9 @@ public class RestrictionProviderImpl imp
     }
 
     @Override
-    public Restriction createRestriction(String path, String jcrName, Value value) throws RepositoryException {
+    public Restriction createRestriction(String jcrPath, String jcrName, Value value) throws RepositoryException {
         String oakName = namePathMapper.getOakName(jcrName);
-        RestrictionDefinition definition = (path == null) ? null : supported.get(oakName);
+        RestrictionDefinition definition = (jcrPath == null) ? null : supported.get(oakName);
         if (definition == null) {
             throw new AccessControlException("Unsupported restriction: " + jcrName);
         }
@@ -78,19 +79,19 @@ public class RestrictionProviderImpl imp
     }
 
     @Override
-    public Set<Restriction> readRestrictions(String path, Tree aceTre) throws javax.jcr.security.AccessControlException {
+    public Set<Restriction> readRestrictions(String jcrPath, Tree aceTree) throws javax.jcr.security.AccessControlException {
         // TODO
-        return null;
+        throw new NotImplementedException();
     }
 
     @Override
-    public void writeRestrictions(String path, Tree aceTree, Set<Restriction> restrictions) throws javax.jcr.security.AccessControlException {
+    public void writeRestrictions(String jcrPath, Tree aceTree, Set<Restriction> restrictions) throws javax.jcr.security.AccessControlException {
         // TODO
 
     }
 
     @Override
-    public void validateRestrictions(String path, Tree aceTree) throws javax.jcr.security.AccessControlException {
+    public void validateRestrictions(String jcrPath, Tree aceTree) throws javax.jcr.security.AccessControlException {
         Tree restrictions;
         if (aceTree.hasChild(AccessControlConstants.REP_RESTRICTIONS)) {
             restrictions = aceTree.getChild(AccessControlConstants.REP_RESTRICTIONS);
@@ -108,7 +109,7 @@ public class RestrictionProviderImpl imp
             }
         }
 
-        if (path == null && !restrictionProperties.isEmpty()) {
+        if (jcrPath == null && !restrictionProperties.isEmpty()) {
             throw new AccessControlException("Restrictions not supported with 'null' path.");
         }
         for (String restrName : restrictionProperties.keySet()) {
@@ -123,40 +124,4 @@ public class RestrictionProviderImpl imp
             }
         }
     }
-
-    private static class RestrictionImpl implements Restriction {
-
-        private final PropertyState property;
-        private final int requiredType;
-        private final boolean isMandatory;
-
-        private RestrictionImpl(PropertyState property, int requiredType, boolean isMandatory) {
-            this.property = property;
-            this.requiredType = requiredType;
-            this.isMandatory = isMandatory;
-        }
-
-        @Nonnull
-        @Override
-        public PropertyState getProperty() {
-            return property;
-        }
-
-        @Nonnull
-        @Override
-        public String getName() {
-            return property.getName();
-        }
-
-        @Nonnull
-        @Override
-        public int getRequiredType() {
-            return requiredType;
-        }
-
-        @Override
-        public boolean isMandatory() {
-            return isMandatory;
-        }
-    }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACE.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACE.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACE.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACE.java Thu Dec 13 19:56:44 2012
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.oak.spi.security.authorization;
 
 import java.security.Principal;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Set;
 import javax.jcr.RepositoryException;
@@ -58,8 +59,14 @@ public class ACE implements JackrabbitAc
         this.namePathMapper = namePathMapper;
     }
 
-    public Set<Privilege> getPrivilegeSet() {
-        return privileges;
+    public String[] getPrivilegeNames() {
+        Collection<String> privNames = Collections2.transform(privileges, new Function<Privilege, String>() {
+            @Override
+            public String apply(Privilege privilege) {
+                return privilege.getName();
+            }
+        });
+        return privNames.toArray(new String[privNames.size()]);
     }
 
     public Set<Restriction> getRestrictionSet() {
@@ -153,7 +160,7 @@ public class ACE implements JackrabbitAc
      */
     private int buildHashCode() {
         int h = 17;
-        h = 37 * h + principal.getName().hashCode();
+        h = 37 * h + principal.hashCode();
         h = 37 * h + privileges.hashCode();
         h = 37 * h + Boolean.valueOf(isAllow).hashCode();
         h = 37 * h + restrictions.hashCode();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACL.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACL.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACL.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/ACL.java Thu Dec 13 19:56:44 2012
@@ -48,14 +48,18 @@ public class ACL implements JackrabbitAc
 
     private static final Logger log = LoggerFactory.getLogger(ACL.class);
 
-    private final String path;
+    private final String jcrPath;
     private final List<ACE> entries;
     private final RestrictionProvider restrictionProvider;
     private final NamePathMapper namePathMapper;
 
-    public ACL(String path, List<ACE> entries, RestrictionProvider restrictionProvider,
+    public ACL(String jcrPath, RestrictionProvider restrictionProvider, NamePathMapper namePathMapper) {
+        this(jcrPath, null, restrictionProvider, namePathMapper);
+    }
+
+    public ACL(String jcrPath, List<ACE> entries, RestrictionProvider restrictionProvider,
                NamePathMapper namePathMapper) {
-        this.path = path;
+        this.jcrPath = jcrPath;
         this.entries = (entries == null) ? new ArrayList<ACE>() : entries;
         this.restrictionProvider = restrictionProvider;
         this.namePathMapper = namePathMapper;
@@ -87,13 +91,13 @@ public class ACL implements JackrabbitAc
     //--------------------------------------< JackrabbitAccessControlPolicy >---
     @Override
     public String getPath() {
-        return (path == null) ? null : namePathMapper.getJcrPath(path);
+        return jcrPath;
     }
 
     //----------------------------------------< JackrabbitAccessControlList >---
     @Override
     public String[] getRestrictionNames() throws RepositoryException {
-        Set<RestrictionDefinition> supported = restrictionProvider.getSupportedRestrictions(path);
+        Set<RestrictionDefinition> supported = restrictionProvider.getSupportedRestrictions(jcrPath);
         return Collections2.transform(supported, new Function<RestrictionDefinition, String>() {
             @Override
             public String apply(RestrictionDefinition definition) {
@@ -106,7 +110,7 @@ public class ACL implements JackrabbitAc
     @Override
     public int getRestrictionType(String restrictionName) throws RepositoryException {
         String oakName = namePathMapper.getOakName(restrictionName);
-        for (RestrictionDefinition definition : restrictionProvider.getSupportedRestrictions(path)) {
+        for (RestrictionDefinition definition : restrictionProvider.getSupportedRestrictions(jcrPath)) {
             if (definition.getName().equals(oakName)) {
                 return definition.getRequiredType();
             }
@@ -139,7 +143,7 @@ public class ACL implements JackrabbitAc
         } else {
             rs = new HashSet<Restriction>(restrictions.size());
             for (String name : restrictions.keySet()) {
-                rs.add(restrictionProvider.createRestriction(path, name, restrictions.get(name)));
+                rs.add(restrictionProvider.createRestriction(jcrPath, name, restrictions.get(name)));
             }
         }
         ACE entry = new ACE(principal, privileges, isAllow, rs, namePathMapper);
@@ -205,7 +209,8 @@ public class ACL implements JackrabbitAc
         }
         if (obj instanceof ACL) {
             ACL acl = (ACL) obj;
-            return path.equals(acl.path) && entries.equals(acl.entries);
+            return ((jcrPath == null) ? acl.jcrPath == null : jcrPath.equals(acl.jcrPath))
+                    && entries.equals(acl.entries);
         }
         return false;
     }
@@ -213,7 +218,7 @@ public class ACL implements JackrabbitAc
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("ACL: ").append(path).append("; ACEs: ");
+        sb.append("ACL: ").append(jcrPath).append("; ACEs: ");
         for (AccessControlEntry ace : entries) {
             sb.append(ace.toString()).append(';');
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionDefinition.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionDefinition.java Thu Dec 13 19:56:44 2012
@@ -23,10 +23,25 @@ import javax.annotation.Nonnull;
  */
 public interface RestrictionDefinition {
 
+    /**
+     * The internal oak name of this restriction definition.
+     *
+     * @return The oak name.
+     */
     @Nonnull
     String getName();
 
+    /**
+     * The required type as defined by this definition.
+     *
+     * @return The required type which must be a valid {@link javax.jcr.PropertyType}.
+     */
     int getRequiredType();
 
+    /**
+     * Indicates if this restriction is mandatory.
+     *
+     * @return {@code true} if this restriction is mandatory; {@code false} otherwise.
+     */
     boolean isMandatory();
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/RestrictionProvider.java Thu Dec 13 19:56:44 2012
@@ -30,13 +30,15 @@ import org.apache.jackrabbit.oak.api.Tre
 public interface RestrictionProvider {
 
     @Nonnull
-    Set<RestrictionDefinition> getSupportedRestrictions(String path);
+    Set<RestrictionDefinition> getSupportedRestrictions(String jcrPath);
 
+    @Nonnull
     Restriction createRestriction(String jcrPath, String jcrName, Value value) throws RepositoryException;
 
-    Set<Restriction> readRestrictions(String path, Tree aceTree) throws AccessControlException;
+    @Nonnull
+    Set<Restriction> readRestrictions(String jcrPath, Tree aceTree) throws AccessControlException;
 
-    void writeRestrictions(String path, Tree aceTree, Set<Restriction> restrictions) throws AccessControlException;
+    void writeRestrictions(String jcrPath, Tree aceTree, Set<Restriction> restrictions) throws AccessControlException;
 
-    void validateRestrictions(String path, Tree aceTree) throws AccessControlException;
+    void validateRestrictions(String jcrPath, Tree aceTree) throws AccessControlException;
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/PropInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/PropInfo.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/PropInfo.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/PropInfo.java Thu Dec 13 19:56:44 2012
@@ -21,7 +21,6 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.nodetype.PropertyDefinition;
 
-import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 
 /**
@@ -44,7 +43,7 @@ public class PropInfo {
     /**
      * Type of the property being imported.
      */
-    private final Type type;
+    private final int type;
 
     /**
      * Value(s) of the property being imported.
@@ -64,7 +63,7 @@ public class PropInfo {
      * @param type type of the property being imported
      * @param values value(s) of the property being imported
      */
-    public PropInfo(String name, Type type, TextValue[] values) {
+    public PropInfo(String name, int type, TextValue[] values) {
         this.name = name;
         this.type = type;
         this.values = values;
@@ -78,9 +77,8 @@ public class PropInfo {
      * @param type type of the property being imported
      * @param values value(s) of the property being imported
      * @param multipleStatus Hint indicating whether the property is
-     *                       multi- or single-value
      */
-    public PropInfo(String name, Type type, TextValue[] values,
+    public PropInfo(String name, int type, TextValue[] values,
                     MultipleStatus multipleStatus) {
         this.name = name;
         this.type = type;
@@ -97,14 +95,14 @@ public class PropInfo {
         }
     }
 
-    public Type getTargetType(PropertyDefinition def) {
+    public int getTargetType(PropertyDefinition def) {
         int target = def.getRequiredType();
         if (target != PropertyType.UNDEFINED) {
-            return Type.fromTag(target, def.isMultiple());
-        } else if (type.tag() != PropertyType.UNDEFINED) {
+            return type;
+        } else if (type != PropertyType.UNDEFINED) {
             return type;
         } else {
-            return Type.STRING;
+            return PropertyType.STRING;
         }
     }
 
@@ -112,7 +110,7 @@ public class PropInfo {
         return name;
     }
 
-    public Type getType() {
+    public int getType() {
         return type;
     }
 
@@ -127,14 +125,14 @@ public class PropInfo {
         return values;
     }
 
-    public Value getValue(Type targetType, NamePathMapper namePathMapper) throws RepositoryException {
+    public Value getValue(int targetType, NamePathMapper namePathMapper) throws RepositoryException {
         if (multipleStatus == MultipleStatus.MULTIPLE) {
             throw new RepositoryException("TODO");
         }
         return values[0].getValue(targetType, namePathMapper);
     }
 
-    public Value[] getValues(Type targetType, NamePathMapper namePathMapper) throws RepositoryException {
+    public Value[] getValues(int targetType, NamePathMapper namePathMapper) throws RepositoryException {
         Value[] va = new Value[values.length];
         for (int i = 0; i < values.length; i++) {
             va[i] = values[i].getValue(targetType, namePathMapper);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/TextValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/TextValue.java?rev=1421458&r1=1421457&r2=1421458&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/TextValue.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/xml/TextValue.java Thu Dec 13 19:56:44 2012
@@ -20,7 +20,6 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
 
-import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 
 /**
@@ -32,7 +31,7 @@ public interface TextValue {
     String getString();
 
     // TODO: review again
-    Value getValue(Type targetType, NamePathMapper namePathMapper) throws ValueFormatException, RepositoryException;
+    Value getValue(int targetType, NamePathMapper namePathMapper) throws ValueFormatException, RepositoryException;
 
     /**
      * Dispose this value, i.e. free all bound resources. Once a value has



Mime
View raw message