You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2014/07/30 17:45:21 UTC

svn commit: r1614692 - in /jackrabbit/oak/trunk: ./ oak-authorization-cug/ oak-authorization-cug/src/ oak-authorization-cug/src/main/ oak-authorization-cug/src/main/java/ oak-authorization-cug/src/main/java/org/ oak-authorization-cug/src/main/java/org/...

Author: angela
Date: Wed Jul 30 15:45:20 2014
New Revision: 1614692

URL: http://svn.apache.org/r1614692
Log:
OAK-2008 : authorization setup for closed user groups

Added:
    jackrabbit/oak/trunk/oak-authorization-cug/   (with props)
    jackrabbit/oak/trunk/oak-authorization-cug/pom.xml
    jackrabbit/oak/trunk/oak-authorization-cug/src/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugExclude.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugPolicy.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugAccessControlManager.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConfiguration.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConstants.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugContext.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugExcludeImpl.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugImporter.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPermissionProvider.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPolicyImpl.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugUtil.java
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/cug_nodetypes.cnd
    jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/impl/
    jackrabbit/oak/trunk/oak-authorization-cug/src/test/
    jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeRegistry.java
      - copied, changed from r1605068, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/BuiltInNodeTypes.java
Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/BuiltInNodeTypes.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/InitialContent.java
    jackrabbit/oak/trunk/pom.xml

Propchange: jackrabbit/oak/trunk/oak-authorization-cug/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Jul 30 15:45:20 2014
@@ -0,0 +1,5 @@
+target
+.*
+*.iml
+*.ipr
+*.iws

Added: jackrabbit/oak/trunk/oak-authorization-cug/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/pom.xml?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/pom.xml (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/pom.xml Wed Jul 30 15:45:20 2014
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>jackrabbit-oak</artifactId>
+    <groupId>org.apache.jackrabbit</groupId>
+    <version>1.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>oak-authorization-cug</artifactId>
+  <name>Oak CUG</name>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.apache.jackrabbit.oak.security.authorization.cug
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+            <configuration>
+              <excludes>
+                <exclude>logback-test.xml</exclude>
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <configuration>
+            <excludes />
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <!-- Dependencies to other Oak components -->
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- General utility libraries -->
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+
+    <!-- JCR and Jackrabbit dependencies -->
+    <dependency>
+      <groupId>javax.jcr</groupId>
+      <artifactId>jcr</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-api</artifactId>
+      <version>${jackrabbit.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>jackrabbit-jcr-commons</artifactId>
+      <version>${jackrabbit.version}</version>
+    </dependency>
+
+    <!-- Logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <!-- Optional OSGi dependencies, used only when running within OSGi -->
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr.annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <!-- Findbugs annotations -->
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+    </dependency>
+
+  </dependencies>
+
+</project>
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugExclude.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugExclude.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugExclude.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugExclude.java Wed Jul 30 15:45:20 2014
@@ -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.oak.security.authorization.cug;
+
+import java.security.Principal;
+import java.util.Set;
+import javax.annotation.Nonnull;
+
+/**
+ * CugExclude... TODO
+ */
+public interface CugExclude {
+
+    boolean isExcluded(@Nonnull Set<Principal> principals);
+
+    CugExclude DEFAULT = new Default();
+
+    class Default implements CugExclude {
+
+        @Override
+        public boolean isExcluded(@Nonnull Set<Principal> principals) {
+            return principals.isEmpty();
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugPolicy.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugPolicy.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugPolicy.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/CugPolicy.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,38 @@
+package org.apache.jackrabbit.oak.security.authorization.cug; /*************************************************************************
+ *
+ * ADOBE CONFIDENTIAL
+ * ___________________
+ *
+ *  Copyright 2011 Adobe Systems Incorporated
+ *  All Rights Reserved.
+ *
+ * NOTICE:  All information contained herein is, and remains
+ * the property of Adobe Systems Incorporated and its suppliers,
+ * if any.  The intellectual and technical concepts contained
+ * herein are proprietary to Adobe Systems Incorporated and its
+ * suppliers and are protected by trade secret or copyright law.
+ * Dissemination of this information or reproduction of this material
+ * is strictly forbidden unless prior written permission is obtained
+ * from Adobe Systems Incorporated.
+ **************************************************************************/
+
+import java.security.Principal;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.security.AccessControlException;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+
+/**
+ * Denies read access for all principals except for the specified principals.
+ */
+public interface CugPolicy extends JackrabbitAccessControlPolicy {
+
+    @Nonnull
+    Set<Principal> getPrincipals();
+
+    boolean addPrincipals(@Nonnull Principal... principals) throws AccessControlException;
+
+    boolean removePrincipals(@Nonnull Principal... principals);
+
+}

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugAccessControlManager.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugAccessControlManager.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugAccessControlManager.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,240 @@
+/*
+ * 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.cug.impl;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.commons.iterator.AccessControlPolicyIteratorAdapter;
+import org.apache.jackrabbit.oak.api.PropertyState;
+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.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.security.authorization.cug.CugPolicy;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AbstractAccessControlManager;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.apache.jackrabbit.util.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
+
+/**
+ * CugAccessControlManager... TODO
+ */
+class CugAccessControlManager extends AbstractAccessControlManager implements CugConstants {
+
+    private static final Logger log = LoggerFactory.getLogger(CugAccessControlManager.class);
+
+    private final ConfigurationParameters config;
+    private final PrincipalManager principalManager;
+
+    public CugAccessControlManager(@Nonnull Root root, @Nonnull NamePathMapper namePathMapper, @Nonnull SecurityProvider securityProvider) {
+        super(root, namePathMapper, securityProvider);
+
+        config = securityProvider.getConfiguration(AuthorizationConfiguration.class).getParameters();
+        principalManager = securityProvider.getConfiguration(PrincipalConfiguration.class).getPrincipalManager(root, namePathMapper);
+    }
+
+    //-----------------------------------------------< AccessControlManager >---
+
+    @Nonnull
+    @Override
+    public Privilege[] getSupportedPrivileges(@Nullable String absPath) throws RepositoryException {
+        if (isSupportedPath(getOakPath(absPath))) {
+            return new Privilege[] {privilegeFromName(Privilege.JCR_READ)};
+        } else {
+            return new Privilege[0];
+        }
+    }
+
+    public AccessControlPolicy[] getPolicies(String absPath) throws RepositoryException {
+        String oakPath = getOakPath(absPath);
+        if (isSupportedPath(oakPath)) {
+            CugPolicy cug = getCugPolicy(oakPath);
+            if (cug != null) {
+                return new AccessControlPolicy[]{cug};
+            }
+        }
+        return new AccessControlPolicy[0];
+    }
+
+    public AccessControlPolicy[] getEffectivePolicies(String absPath) throws RepositoryException {
+        String oakPath = getOakPath(absPath);
+        getTree(oakPath, Permissions.READ_ACCESS_CONTROL, true);
+
+        Root r = getRoot().getContentSession().getLatestRoot();
+        List<AccessControlPolicy> effective = new ArrayList<AccessControlPolicy>();
+        while (!oakPath.isEmpty()) {
+            if (isSupportedPath(oakPath)) {
+                CugPolicy cug = getCugPolicy(oakPath, r.getTree(oakPath));
+                if (cug != null) {
+                    effective.add(cug);
+                }
+            }
+            oakPath = Text.getRelativeParent(oakPath, 1);
+        }
+        return effective.toArray(new AccessControlPolicy[effective.size()]);
+    }
+
+    public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws RepositoryException {
+        String oakPath = getOakPath(absPath);
+        if (!isSupportedPath(oakPath)) {
+            return AccessControlPolicyIteratorAdapter.EMPTY;
+        } else {
+            CugPolicy cug = getCugPolicy(oakPath);
+            if (cug == null) {
+                return new AccessControlPolicyIteratorAdapter(ImmutableSet.of(new CugPolicyImpl(oakPath, getNamePathMapper(), principalManager, CugUtil.getImportBehavior(config))));
+            } else {
+                return AccessControlPolicyIteratorAdapter.EMPTY;
+            }
+        }
+    }
+
+    public void removePolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
+        String oakPath = getOakPath(absPath);
+        if (isSupportedPath(oakPath)) {
+            checkValidPolicy(absPath, policy);
+
+            Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL, true);
+            Tree cug = tree.getChild(REP_CUG_POLICY);
+            if (!CugUtil.definesCug(cug)) {
+                throw new AccessControlException("Unexpected primary type of node rep:cugPolicy.");
+            } else {
+                cug.remove();
+            }
+        } else {
+            throw new AccessControlException("Unsupported path: " + absPath);
+        }
+    }
+
+    public void setPolicy(String absPath, AccessControlPolicy policy) throws RepositoryException {
+        String oakPath = getOakPath(absPath);
+        if (isSupportedPath(oakPath)) {
+            checkValidPolicy(absPath, policy);
+
+            Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL, true);
+            Tree typeRoot = getRoot().getTree(NODE_TYPES_PATH);
+            if (!TreeUtil.isNodeType(tree, MIX_REP_CUG_MIXIN, typeRoot)) {
+                TreeUtil.addMixin(tree, MIX_REP_CUG_MIXIN, typeRoot, null);
+            }
+            Tree cug;
+            if (tree.hasChild(REP_CUG_POLICY)) {
+                cug = tree.getChild(REP_CUG_POLICY);
+                if (!CugUtil.definesCug(cug)) {
+                    throw new AccessControlException("Unexpected primary type of node rep:cugPolicy.");
+                }
+            } else {
+                cug = TreeUtil.addChild(tree, REP_CUG_POLICY, NT_REP_CUG_POLICY, typeRoot, null);
+            }
+            cug.setProperty(REP_PRINCIPAL_NAMES, ((CugPolicyImpl) policy).getPrincipalNames(), Type.STRINGS);
+        } else {
+            throw new AccessControlException("Unsupported path: " + absPath);
+        }
+    }
+
+    //-------------------------------------< JackrabbitAccessControlManager >---
+
+    public JackrabbitAccessControlPolicy[] getApplicablePolicies(Principal principal) throws RepositoryException {
+        // TODO
+        return new JackrabbitAccessControlPolicy[0];
+    }
+
+    public JackrabbitAccessControlPolicy[] getPolicies(Principal principal) throws RepositoryException {
+        // TODO
+        return new JackrabbitAccessControlPolicy[0];
+    }
+
+    public AccessControlPolicy[] getEffectivePolicies(Set<Principal> principals) throws RepositoryException {
+        // TODO
+        return new AccessControlPolicy[0];
+    }
+
+    //--------------------------------------------------------------------------
+
+    private boolean isSupportedPath(@Nullable String oakPath) {
+        return CugUtil.isSupportedPath(oakPath, config);
+    }
+
+    @CheckForNull
+    private CugPolicy getCugPolicy(@Nonnull String oakPath) throws RepositoryException {
+        return getCugPolicy(oakPath, getTree(oakPath, Permissions.READ_ACCESS_CONTROL, true));
+    }
+
+    @CheckForNull
+    private CugPolicy getCugPolicy(@Nonnull String oakPath, @Nonnull Tree tree) {
+        Tree cug = tree.getChild(REP_CUG_POLICY);
+        if (CugUtil.definesCug(cug)) {
+            return new CugPolicyImpl(oakPath, getNamePathMapper(), principalManager, CugUtil.getImportBehavior(config), getPrincipals(cug));
+        } else {
+            return null;
+        }
+    }
+
+    private Set<Principal> getPrincipals(@Nonnull Tree cugTree) {
+        PropertyState property = cugTree.getProperty(REP_PRINCIPAL_NAMES);
+        if (property == null) {
+            return Collections.emptySet();
+        } else {
+            return ImmutableSet.copyOf(Iterables.transform(property.getValue(Type.STRINGS), new Function<String, Principal>() {
+                @Override
+                public Principal apply(String principalName) {
+                    Principal principal = principalManager.getPrincipal(principalName);
+                    if (principal == null) {
+                        log.debug("Unknown principal " + principalName);
+                        principal = new PrincipalImpl(principalName);
+                    }
+                    return principal;
+                }
+            }));
+        }
+    }
+
+    private static void checkValidPolicy(@Nullable String absPath, @Nonnull AccessControlPolicy policy) throws AccessControlException {
+        if (!(policy instanceof CugPolicyImpl)) {
+            throw new AccessControlException("Unsupported policy implementation: " + policy);
+        }
+
+        CugPolicy cug = (CugPolicy) policy;
+        if (!cug.getPath().equals(absPath)) {
+            throw new AccessControlException("Path mismatch: Expected " + cug.getPath() + ", Found: " + absPath);
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConfiguration.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConfiguration.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConfiguration.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,245 @@
+/*
+ * 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.cug.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlManager;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyOption;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.SystemRoot;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
+import org.apache.jackrabbit.oak.security.authorization.cug.CugExclude;
+import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.security.CompositeConfiguration;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.SystemSubject;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.ControlFlag;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.EmptyPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.OpenPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.apache.jackrabbit.oak.spi.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.oak.spi.security.principal.SystemPrincipal;
+import org.apache.jackrabbit.oak.spi.state.ApplyDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.osgi.service.component.ComponentContext;
+
+@Component()
+@Service({AuthorizationConfiguration.class, SecurityConfiguration.class})
+@Properties({
+        @Property(name = CugConstants.PARAM_CUG_SUPPORTED_PATHS,
+                label = "Supported Paths",
+                description = "Paths under which CUGs can be created and will be evaluated.",
+                cardinality = Integer.MAX_VALUE),
+        @Property(name = CugConstants.PARAM_CUG_ENABLED,
+                label = "CUG Enabled",
+                description = "Flag to enable the evaluation of the configured CUG policies.",
+                boolValue = false),
+        @Property(name = CompositeConfiguration.PARAM_RANKING,
+                label = "Ranking",
+                description = "Ranking of this configuration in a setup with multiple authorization configurations.",
+                intValue = 200),
+        @Property(name = AggregatedPermissionProvider.PARAM_CONTROL_FLAG,
+                label = "Control Flag",
+                description = "Control flag defining if the permission provider is SUFFICIENT or REQUISITE.",
+                options = {
+                        @PropertyOption(name = ControlFlag.SUFFICIENT_NAME, value = ControlFlag.SUFFICIENT_NAME),
+                        @PropertyOption(name = ControlFlag.REQUISITE_NAME, value = ControlFlag.REQUISITE_NAME)
+                },
+                value = ControlFlag.REQUISITE_NAME)
+})
+public class CugConfiguration extends ConfigurationBase implements AuthorizationConfiguration, CugConstants {
+
+    @Reference
+    private ContentRepository repository;
+
+    @Reference
+    private CugExclude exclude = CugExclude.DEFAULT;
+
+    public CugConfiguration() {
+        super();
+    }
+
+    public CugConfiguration(@Nonnull SecurityProvider securityProvider, @Nonnull ConfigurationParameters config) {
+        super(securityProvider, config);
+    }
+
+    @Override
+    public AccessControlManager getAccessControlManager(Root root, NamePathMapper namePathMapper) {
+        return new CugAccessControlManager(root, namePathMapper, getSecurityProvider());
+    }
+
+    @Override
+    public RestrictionProvider getRestrictionProvider() {
+        return RestrictionProvider.EMPTY;
+    }
+
+    @Override
+    public PermissionProvider getPermissionProvider(Root root, String workspaceName, Set<Principal> principals) {
+        if (principals.contains(SystemPrincipal.INSTANCE) || isAdmin(principals)) {
+            return OpenPermissionProvider.getInstance();
+        }
+
+        ConfigurationParameters params = getParameters();
+        boolean enabled = params.getConfigValue(CugConstants.PARAM_CUG_ENABLED, false);
+
+        String[] supportedPaths = params.getConfigValue(CugConstants.PARAM_CUG_SUPPORTED_PATHS, new String[0]);
+        if (!enabled || supportedPaths.length == 0 || getExclude().isExcluded(principals)) {
+            return EmptyPermissionProvider.getInstance();
+        } else {
+            ControlFlag flag = ControlFlag.valueOf(params.getConfigValue(AggregatedPermissionProvider.PARAM_CONTROL_FLAG, ControlFlag.REQUISITE_NAME));
+            return new CugPermissionProvider(root, principals, supportedPaths, flag, getContext());
+        }
+    }
+
+    @Override
+    public String getName() {
+        return AuthorizationConfiguration.NAME;
+    }
+
+    @Nonnull
+    @Override
+    public RepositoryInitializer getRepositoryInitializer() {
+        return new RepositoryInitializer() {
+            @Override
+            public void initialize(NodeBuilder builder) {
+                NodeState base = builder.getNodeState();
+                NodeStore store = new MemoryNodeStore(base);
+
+                Root root = new SystemRoot(store,
+                        new EditorHook(new CompositeEditorProvider(
+                                new NamespaceEditorProvider(),
+                                new TypeEditorProvider())));
+                if (registerCugNodeTypes(root)) {
+                    NodeState target = store.getRoot();
+                    target.compareAgainstBaseState(base, new ApplyDiff(builder));
+                }
+            }
+        };
+    }
+
+    @Override
+    public List<ProtectedItemImporter> getProtectedItemImporters() {
+        return Collections.<ProtectedItemImporter>singletonList(new CugImporter());
+    }
+
+    @Override
+    public Context getContext() {
+        return CugContext.INSTANCE;
+    }
+
+    //----------------------------------------------------< SCR Integration >---
+
+    @Activate
+    private void activate(ComponentContext context) throws IOException, CommitFailedException, PrivilegedActionException, RepositoryException {
+        ContentSession systemSession = null;
+        try {
+            systemSession = Subject.doAs(SystemSubject.INSTANCE, new PrivilegedExceptionAction<ContentSession>() {
+                @Override
+                public ContentSession run() throws LoginException, RepositoryException {
+                    return repository.login(null, null);
+                }
+            });
+            final Root root = systemSession.getLatestRoot();
+            if (registerCugNodeTypes(root)) {
+                root.commit();
+            }
+        } finally {
+            if (systemSession != null) {
+                systemSession.close();
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    private CugExclude getExclude() {
+        return (exclude == null) ? CugExclude.DEFAULT : exclude;
+    }
+
+    private static boolean isAdmin(@Nonnull Set<Principal> principals) {
+        for (Principal p : principals) {
+            if (p instanceof AdminPrincipal) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean registerCugNodeTypes(@Nonnull final Root root) {
+        try {
+            ReadOnlyNodeTypeManager ntMgr = new ReadOnlyNodeTypeManager() {
+                @Override
+                protected Tree getTypes() {
+                    return root.getTree(NodeTypeConstants.NODE_TYPES_PATH);
+                }
+            };
+            if (!ntMgr.hasNodeType(NT_REP_CUG_POLICY)) {
+                InputStream stream = CugConfiguration.class.getResourceAsStream("cug_nodetypes.cnd");
+                try {
+                    NodeTypeRegistry.register(root, stream, "cug node types");
+                    return true;
+                } finally {
+                    stream.close();
+                }
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException("Unable to read cug node types", e);
+        } catch (RepositoryException e) {
+            throw new IllegalStateException("Unable to read cug node types", e);
+        }
+        return false;
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConstants.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConstants.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugConstants.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,41 @@
+/*
+ * 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.cug.impl;
+
+/**
+ * CugConstants... TODO
+ */
+interface CugConstants {
+
+    String MIX_REP_CUG_MIXIN = "rep:CugMixin";
+
+    String NT_REP_CUG_POLICY = "rep:CugPolicy";
+
+    String REP_CUG_POLICY = "rep:cugPolicy";
+
+    String REP_PRINCIPAL_NAMES = "rep:principalNames";
+
+    String PARAM_CUG_SUPPORTED_PATHS = "cugSupportedPaths";
+
+    String PARAM_CUG_ENABLED = "cugEnabled";
+
+    /**
+     *
+     */
+    String PARAM_CUG_EXCLUDE = "cugExclude";
+
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugContext.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugContext.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugContext.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,62 @@
+/*
+ * 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.cug.impl;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * CugContext... TODO
+ */
+final class CugContext implements Context, CugConstants {
+
+    private CugContext(){}
+
+    static final Context INSTANCE = new CugContext();
+
+    @Override
+    public boolean definesProperty(@Nonnull Tree parent, @Nonnull PropertyState property) {
+        return CugUtil.definesCug(parent, property);
+    }
+
+    @Override
+    public boolean definesContextRoot(@Nonnull Tree tree) {
+        return CugUtil.definesCug(tree);
+    }
+
+    @Override
+    public boolean definesTree(@Nonnull Tree tree) {
+        return CugUtil.definesCug(tree);
+    }
+
+    @Override
+    public boolean definesLocation(@Nonnull TreeLocation location) {
+        Tree tree = location.getTree();
+        if (tree != null && location.exists()) {
+            PropertyState p = location.getProperty();
+            return (p == null) ? definesTree(tree) : definesProperty(tree, p);
+        } else {
+            String name = Text.getName(location.getPath());
+            return REP_PRINCIPAL_NAMES.equals(name) || REP_CUG_POLICY.equals(name);
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugExcludeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugExcludeImpl.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugExcludeImpl.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugExcludeImpl.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,104 @@
+/*
+ * 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.cug.impl;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.RepositoryException;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.api.security.principal.ItemBasedPrincipal;
+import org.apache.jackrabbit.oak.commons.PropertiesUtil;
+import org.apache.jackrabbit.oak.security.authorization.cug.CugExclude;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+
+/**
+ * CugExcludeImpl... TODO
+ */
+@Component()
+@Service({CugExclude.class})
+@Properties({
+        @Property(name = "principalNames",
+                label = "Principal Names",
+                description = "Name of principals that are always excluded from CUG evaluation.",
+                cardinality = Integer.MAX_VALUE),
+        @Property(name = "principalPaths",
+                label = "Principal Paths",
+                description = "Path pattern for principals that are always excluded from CUG evaluation",
+                cardinality = Integer.MAX_VALUE)
+})
+public class CugExcludeImpl extends CugExclude.Default {
+
+    private String[] principalNames = new String[0];
+    private String[] principalPaths = new String[0];
+
+    @Override
+    public boolean isExcluded(@Nonnull Set<Principal> principals) {
+        if (super.isExcluded(principals)) {
+            return true;
+        }
+        for (String principalName : principalNames) {
+            if (principals.contains(new PrincipalImpl(principalName))) {
+                return true;
+            }
+        }
+        if (principalPaths.length > 0) {
+            for (String principalPath : getPrincipalPaths(principals)) {
+                for (String path : principalPaths) {
+                    if (principalPath.startsWith(path)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Activate
+    protected void activate(Map<String, Object> properties) {
+        principalNames = PropertiesUtil.toStringArray(properties.get("principalNames"), new String[0]);
+        principalPaths = PropertiesUtil.toStringArray(properties.get("principalPaths"), new String[0]);
+    }
+
+    private static Iterable<String> getPrincipalPaths(@Nonnull final Iterable<Principal> principals) {
+        return Iterables.filter(Iterables.transform(principals, new Function<Principal, String>() {
+            @Nullable
+            @Override
+            public String apply(@Nullable Principal input) {
+                if (input instanceof ItemBasedPrincipal) {
+                    try {
+                        return ((ItemBasedPrincipal) input).getPath();
+                    } catch (RepositoryException e) {
+                        return null;
+                    }
+                } else {
+                    return null;
+                }
+            }
+        }), Predicates.notNull());
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugImporter.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugImporter.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugImporter.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,128 @@
+/*
+ * 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.cug.impl;
+
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+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.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.PropInfo;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedPropertyImporter;
+import org.apache.jackrabbit.oak.spi.xml.ReferenceChangeTracker;
+import org.apache.jackrabbit.oak.spi.xml.TextValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CugImporter... TODO
+ */
+class CugImporter implements ProtectedPropertyImporter, CugConstants {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(CugImporter.class);
+
+    private boolean initialized;
+
+    private ConfigurationParameters config;
+    private int importBehavior;
+
+    private PrincipalManager principalManager;
+
+    //----------------------------------------------< ProtectedItemImporter >---
+    @Override
+    public boolean init(@Nonnull Session session, @Nonnull Root root, @Nonnull NamePathMapper namePathMapper, boolean isWorkspaceImport, int uuidBehavior, @Nonnull ReferenceChangeTracker referenceTracker, SecurityProvider securityProvider) {
+        if (initialized) {
+            throw new IllegalStateException("Already initialized");
+        }
+        try {
+            config = securityProvider.getConfiguration(AuthorizationConfiguration.class).getParameters();
+            importBehavior = CugUtil.getImportBehavior(config);
+
+            if (isWorkspaceImport) {
+                PrincipalConfiguration pConfig = securityProvider.getConfiguration(PrincipalConfiguration.class);
+                principalManager = pConfig.getPrincipalManager(root, namePathMapper);
+            } else {
+                principalManager = ((JackrabbitSession) session).getPrincipalManager();
+            }
+            initialized = true;
+        } catch (RepositoryException e) {
+            log.warn("Error while initializing cug importer", e);
+        }
+        return initialized;
+    }
+
+    @Override
+    public void processReferences() throws RepositoryException {
+        // nothing to do
+    }
+
+    //------------------------------------------< ProtectedPropertyImporter >---
+
+    @Override
+    public boolean handlePropInfo(@Nonnull Tree parent, @Nonnull PropInfo protectedPropInfo, @Nonnull PropertyDefinition def) throws RepositoryException {
+        if (CugUtil.definesCug(parent) && isValid(protectedPropInfo, def) && CugUtil.isSupportedPath(parent.getPath(), config)) {
+            Set<String> principalNames = new HashSet<String>();
+            for (TextValue txtValue : protectedPropInfo.getTextValues()) {
+                String principalName = txtValue.getString();
+                Principal principal = principalManager.getPrincipal(principalName);
+                if (principal == null) {
+                    switch (importBehavior) {
+                        case ImportBehavior.IGNORE:
+                            log.debug("Unknown principal " + principalName + " -> Ignoring this ACE.");
+                            break;
+                        case ImportBehavior.ABORT:
+                            throw new AccessControlException("Unknown principal " + principalName);
+                        case ImportBehavior.BESTEFFORT:
+                            principalNames.add(principalName);
+                    }
+                } else {
+                    principalNames.add(principalName);
+                }
+            }
+            parent.setProperty(REP_PRINCIPAL_NAMES, principalNames, Type.STRINGS);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    private boolean isValid(@Nonnull PropInfo propInfo, @Nonnull PropertyDefinition def) {
+        if (REP_PRINCIPAL_NAMES.equals(propInfo.getName())) {
+            return def.isMultiple() && NT_REP_CUG_POLICY.equals(def.getDeclaringNodeType().getName());
+        }
+        return false;
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPermissionProvider.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPermissionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPermissionProvider.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,396 @@
+/*
+ * 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.cug.impl;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.Session;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.apache.jackrabbit.oak.api.PropertyState;
+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.core.ImmutableRoot;
+import org.apache.jackrabbit.oak.plugins.tree.ImmutableTree;
+import org.apache.jackrabbit.oak.plugins.tree.TreeLocation;
+import org.apache.jackrabbit.oak.spi.security.Context;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.AggregatedPermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.ControlFlag;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.RepositoryPermission;
+import org.apache.jackrabbit.oak.spi.security.authorization.permission.TreePermission;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class CugPermissionProvider implements PermissionProvider, AggregatedPermissionProvider, CugConstants {
+
+    private static final Logger log = LoggerFactory.getLogger(CugPermissionProvider.class);
+
+    private static final Set<String> READ_NAMES = ImmutableSet.of(
+            Session.ACTION_READ,
+            Permissions.PERMISSION_NAMES.get(Permissions.READ),
+            Permissions.PERMISSION_NAMES.get(Permissions.READ_NODE),
+            Permissions.PERMISSION_NAMES.get(Permissions.READ_PROPERTY));
+
+    private static final Set<String> READ_PRIVILEGE_NAMES = ImmutableSet.of(
+            PrivilegeConstants.JCR_READ,
+            PrivilegeConstants.REP_READ_NODES,
+            PrivilegeConstants.REP_READ_PROPERTIES
+    );
+
+    private final Root root;
+    private final Set<String> principalNames;
+
+    private final ControlFlag flag;
+    private final Context ctx;
+
+    private final String[] supportedPaths;
+    private final String[] supportedAltPaths;
+
+    private ImmutableRoot immutableRoot;
+
+    CugPermissionProvider(@Nonnull Root root,
+                          @Nonnull Set<Principal> principals,
+                          @Nonnull String[] supportedPaths,
+                          @Nonnull ControlFlag flag,
+                          @Nonnull Context ctx) {
+        this.root = root;
+        this.immutableRoot = ImmutableRoot.getInstance(root);
+        principalNames = new HashSet<String>(principals.size());
+        for (Principal p : Iterables.filter(principals, Predicates.notNull())) {
+            principalNames.add(p.getName());
+        }
+
+        this.flag = flag;
+
+        this.supportedPaths = supportedPaths;
+        supportedAltPaths = new String[supportedPaths.length];
+        int i = 0;
+        for (String p : supportedPaths) {
+            supportedAltPaths[i++] = p + '/';
+        }
+
+        this.ctx = ctx;
+    }
+
+    //---------------------------------------< AggregatedPermissionProvider >---
+
+    public ControlFlag getFlag() {
+        return flag;
+    }
+
+    public boolean handles(String path, String jcrAction) {
+        return isReadAction(jcrAction) && includesCug(immutableRoot.getTree(path), path);
+    }
+
+    public boolean handles(Tree tree) {
+        return includesCug(tree, tree.getPath());
+    }
+
+    public boolean handles(Tree tree, long permission) {
+        return isRead(permission) && includesCug(tree, tree.getPath());
+    }
+
+    @Override
+    public boolean handles(@Nonnull TreePermission treePermission, long permission) {
+        if (isRead(permission)) {
+            return treePermission instanceof CugTreePermission;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean handlesRepositoryPermissions() {
+        return false;
+    }
+
+    //-------------------------------------------------< PermissionProvider >---
+    public void refresh() {
+        immutableRoot = ImmutableRoot.getInstance(root);
+    }
+
+    public Set<String> getPrivileges(Tree tree) {
+        if (canRead(tree)) {
+            return READ_PRIVILEGE_NAMES;
+        } else {
+            return Collections.emptySet();
+        }
+    }
+
+    public boolean hasPrivileges(Tree tree, String... privilegeNames) {
+        for (String privilegeName : privilegeNames) {
+            if (!READ_PRIVILEGE_NAMES.contains(privilegeName)) {
+                return false;
+            }
+        }
+        return canRead(tree);
+    }
+
+    public RepositoryPermission getRepositoryPermission() {
+        throw new UnsupportedOperationException("Not supported");
+    }
+
+    public TreePermission getTreePermission(Tree tree, TreePermission parentPermission) {
+        ImmutableTree immutableTree = getImmutableTree(tree);
+        if (ctx.definesContextRoot(immutableTree)) {
+            return TreePermission.EMPTY;
+        }
+        if (parentPermission instanceof CugTreePermission) {
+            if (hasCug(immutableTree)) {
+                return createCugPermission(immutableTree);
+            } else {
+                return new CugTreePermission(immutableTree, ((CugTreePermission) parentPermission).allow);
+            }
+        } else if (parentPermission == TreePermission.EMPTY && !immutableTree.isRoot()) {
+            return TreePermission.EMPTY;
+        } else {
+            String path = immutableTree.getPath();
+            if (includes(path)) {
+                return createCugPermission(immutableTree);
+            } else if (mayContainCug(path)) {
+                return new EmptyCugPermission(immutableTree);
+            } else {
+                return TreePermission.EMPTY;
+            }
+        }
+    }
+
+    public boolean isGranted(Tree tree, PropertyState property, long permissions) {
+        long diff = Permissions.diff(permissions, Permissions.READ);
+        if (diff != Permissions.NO_PERMISSION) {
+            return false;
+        } else {
+            return canRead(tree);
+        }
+    }
+
+    public boolean isGranted(String oakPath, String jcrActions) {
+        TreeLocation location = TreeLocation.create(immutableRoot, oakPath);
+        boolean isAcContent = ctx.definesLocation(location);
+        long permissions = Permissions.getPermissions(jcrActions, location, isAcContent);
+
+        PropertyState property = location.getProperty();
+        Tree tree = (property == null) ? location.getTree() : location.getParent().getTree();
+        while (tree == null && !PathUtils.denotesRoot(location.getPath())) {
+            location = location.getParent();
+            tree = location.getTree();
+        }
+        if (tree != null) {
+            return isGranted(tree, property, permissions);
+        } else {
+            return false;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    private static boolean isRead(long permission) {
+        return permission == Permissions.READ_NODE || permission == Permissions.READ_PROPERTY || permission == Permissions.READ;
+    }
+
+    private static boolean isReadAction(@Nonnull String jcrAction) {
+        return READ_NAMES.contains(jcrAction);
+    }
+
+    private static boolean hasCug(@Nonnull ImmutableTree tree) {
+        return tree.exists() && tree.hasChild(REP_CUG_POLICY);
+    }
+
+    private boolean includes(@Nonnull String path) {
+        for (String p : supportedAltPaths) {
+            if (p.startsWith(path)) {
+                return true;
+            }
+        }
+        for (String p : supportedPaths) {
+            if (p.equals(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean includesCug(@Nonnull Tree tree, @Nonnull String path) {
+        return getCugRoot(tree, path) != null;
+    }
+
+    @CheckForNull
+    private ImmutableTree getCugRoot(@Nonnull Tree tree, @Nonnull String path) {
+        if (!includes(path)) {
+            return null;
+        }
+        ImmutableTree immutableTree = getImmutableTree(tree);
+        if (hasCug(immutableTree)) {
+            return immutableTree;
+        }
+        while (!immutableTree.isRoot()) {
+            immutableTree = immutableTree.getParent();
+            if (hasCug(immutableTree)) {
+                return immutableTree;
+            }
+        }
+        return null;
+    }
+
+    private boolean mayContainCug(@Nonnull String path) {
+        String path2 = path + '/';
+        for (String sp : supportedPaths) {
+            if (path.equals(sp) || sp.startsWith(path2)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean canRead(@Nonnull Tree tree) {
+        ImmutableTree immutableTree = getImmutableTree(tree);
+        if (ctx.definesTree(immutableTree)) {
+            return false;
+        }
+        ImmutableTree cugRoot = getCugRoot(immutableTree, immutableTree.getPath());
+        return cugRoot != null && createCugPermission(cugRoot).canRead();
+    }
+
+    private ImmutableTree getImmutableTree(@Nonnull Tree tree) {
+        if (tree instanceof ImmutableTree) {
+            return (ImmutableTree) tree;
+        } else {
+            return immutableRoot.getTree(tree.getPath());
+        }
+    }
+
+    private TreePermission createCugPermission(@Nonnull ImmutableTree tree) {
+        Tree cugTree = tree.getChild(REP_CUG_POLICY);
+        if (CugUtil.definesCug(cugTree)) {
+            PropertyState pNameState = cugTree.getProperty(REP_PRINCIPAL_NAMES);
+            if (pNameState != null) {
+                boolean allow = false;
+                for (String pName : pNameState.getValue(Type.STRINGS)) {
+                    if (principalNames.contains(pName)) {
+                        allow = true;
+                        break;
+                    }
+                }
+                return new CugTreePermission(tree, allow);
+            } else {
+                log.warn("Tree at {0} doesn't represent a valid CUG.", cugTree.getPath());
+            }
+        }
+        return new EmptyCugPermission(tree);
+    }
+
+    //--------------------------------------------------------------------------
+    private final class EmptyCugPermission implements TreePermission {
+
+        private ImmutableTree tree;
+
+        private EmptyCugPermission(@Nonnull ImmutableTree tree) {
+            this.tree = tree;
+        }
+
+        @Override
+        public TreePermission getChildPermission(String childName, NodeState childState) {
+            return getTreePermission(tree.getChild(childName), this);
+        }
+
+        @Override
+        public boolean canRead() {
+            return false;
+        }
+
+        @Override
+        public boolean canRead(@Nonnull PropertyState property) {
+            return false;
+        }
+
+        @Override
+        public boolean canReadAll() {
+            return false;
+        }
+
+        @Override
+        public boolean canReadProperties() {
+            return false;
+        }
+
+        @Override
+        public boolean isGranted(long permissions) {
+            return false;
+        }
+
+        @Override
+        public boolean isGranted(long permissions, @Nonnull PropertyState property) {
+            return false;
+        }
+    }
+
+    private final class CugTreePermission implements TreePermission {
+
+        private final ImmutableTree tree;
+        private final boolean allow;
+
+        private CugTreePermission(@Nonnull ImmutableTree tree, boolean allow) {
+            this.tree = tree;
+            this.allow = allow;
+        }
+
+        @Override
+        public TreePermission getChildPermission(String childName, NodeState childState) {
+            return getTreePermission(tree.getChild(childName), this);
+        }
+
+        @Override
+        public boolean canRead() {
+            return allow;
+        }
+
+        @Override
+        public boolean canRead(@Nonnull PropertyState property) {
+            return allow;
+        }
+
+        @Override
+        public boolean canReadAll() {
+            return false;
+        }
+
+        @Override
+        public boolean canReadProperties() {
+            return false;
+        }
+
+        @Override
+        public boolean isGranted(long permissions) {
+            return allow && permissions == Permissions.READ_NODE;
+        }
+
+        @Override
+        public boolean isGranted(long permissions, @Nonnull PropertyState property) {
+            return allow && permissions == Permissions.READ_PROPERTY;
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPolicyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPolicyImpl.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPolicyImpl.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugPolicyImpl.java Wed Jul 30 15:45:20 2014
@@ -0,0 +1,129 @@
+/*
+ * 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.cug.impl;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.jcr.security.AccessControlException;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.security.authorization.cug.CugPolicy;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * CugPolicyImpl... TODO
+ */
+class CugPolicyImpl implements CugPolicy {
+
+    private static final Logger log = LoggerFactory.getLogger(CugPolicyImpl.class);
+
+    private final String oakPath;
+    private final NamePathMapper namePathMapper;
+    private final PrincipalManager principalManager;
+    private final int importBehavior;
+
+    private final Set<Principal> principals = new HashSet<Principal>();
+
+    CugPolicyImpl(@Nonnull String oakPath, @Nonnull NamePathMapper namePathMapper, PrincipalManager principalManager, int importBehavior) {
+        this(oakPath, namePathMapper, principalManager, importBehavior, Collections.<Principal>emptySet());
+    }
+
+    CugPolicyImpl(@Nonnull String oakPath, @Nonnull NamePathMapper namePathMapper, PrincipalManager principalManager, int importBehavior, @Nonnull Set<Principal> principals) {
+        this.oakPath = oakPath;
+        this.namePathMapper = namePathMapper;
+        this.principalManager = principalManager;
+        this.importBehavior = importBehavior;
+        this.principals.addAll(principals);
+    }
+
+    @Nonnull
+    @Override
+    public Set<Principal> getPrincipals() {
+        return Sets.newHashSet(principals);
+    }
+
+    @Override
+    public boolean addPrincipals(@Nonnull Principal... principals) throws AccessControlException {
+        boolean modified = false;
+        for (Principal principal : principals) {
+            if (principal != null) {
+                String name = principal.getName();
+                if (name == null || name.isEmpty()) {
+                    throw new AccessControlException("Invalid principal " + name);
+                }
+
+                Principal p = principal;
+                switch (importBehavior) {
+                    case ImportBehavior.ABORT:
+                        if (!principalManager.hasPrincipal(name)) {
+                            throw new AccessControlException("Unknown principal " + name);
+                        }
+                        break;
+                    case ImportBehavior.IGNORE:
+                        if (!principalManager.hasPrincipal(name)) {
+                            log.debug("Ignoring unknown principal " + name);
+                            p = null;
+                        }
+                        break;
+                }
+
+                if (p != null) {
+                    modified |= this.principals.add(p);
+                }
+            } else {
+                log.debug("Ignoring null principal.");
+            }
+        }
+        return modified;
+    }
+
+    @Override
+    public boolean removePrincipals(@Nonnull Principal... principals) {
+        boolean modified = false;
+        for (Principal principal : principals) {
+            if (principal != null) {
+                modified |= this.principals.remove(principal);
+            }
+        }
+        return modified;
+    }
+
+    //----------------------------------------< JackrabbitAccessControlList >---
+    @Override
+    public String getPath() {
+        return namePathMapper.getJcrPath(oakPath);
+    }
+
+    //--------------------------------------------------------------------------
+    Iterable<String> getPrincipalNames() {
+        return Iterables.transform(principals, new Function<Principal, String>() {
+            @Override
+            public String apply(Principal principal) {
+                return principal.getName();
+            }
+        });
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugUtil.java?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugUtil.java (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/java/org/apache/jackrabbit/oak/security/authorization/cug/impl/CugUtil.java Wed Jul 30 15:45:20 2014
@@ -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.oak.security.authorization.cug.impl;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * CugUtil... TODO
+ */
+public final class CugUtil {
+
+    private CugUtil(){}
+
+
+    public static boolean definesCug(@Nonnull Tree tree) {
+        return tree.exists() && CugConstants.NT_REP_CUG_POLICY.equals(TreeUtil.getPrimaryTypeName(tree));
+    }
+
+    public static boolean definesCug(@Nonnull Tree tree, @Nonnull PropertyState property) {
+        return CugConstants.REP_PRINCIPAL_NAMES.equals(property.getName()) && definesCug(tree);
+    }
+
+    public static boolean isSupportedPath(@Nullable String oakPath, @Nonnull ConfigurationParameters config) {
+        if (oakPath == null) {
+            return false;
+        } else {
+            for (String supportedPath : config.getConfigValue(CugConfiguration.PARAM_CUG_SUPPORTED_PATHS, new String[0])) {
+                if (Text.isDescendantOrEqual(supportedPath, oakPath)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static int getImportBehavior(ConfigurationParameters config) {
+        String importBehaviorStr = config.getConfigValue(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR, ImportBehavior.NAME_ABORT);
+        return ImportBehavior.valueFromString(importBehaviorStr);
+    }
+}
\ No newline at end of file

Added: jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/cug_nodetypes.cnd
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/cug_nodetypes.cnd?rev=1614692&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/cug_nodetypes.cnd (added)
+++ jackrabbit/oak/trunk/oak-authorization-cug/src/main/resources/org/apache/jackrabbit/oak.security.authorization.cug/cug_nodetypes.cnd Wed Jul 30 15:45:20 2014
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+<rep='internal'>
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+<oak='http://jackrabbit.apache.org/oak/ns/1.0'>
+
+// -----------------------------------------------------------------------------
+// Authorization: Closed User Group
+// -----------------------------------------------------------------------------
+/**
+ * @since oak 1.1
+ */
+[rep:CugMixin]
+  mixin
+  + rep:cugPolicy (rep:CugPolicy) protected IGNORE
+
+/**
+ * @since oak 1.1
+ */
+[rep:CugPolicy] > rep:Policy
+  - rep:principalNames (STRING) multiple protected mandatory IGNORE
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/InitialContent.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/InitialContent.java?rev=1614692&r1=1614691&r2=1614692&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/InitialContent.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/InitialContent.java Wed Jul 30 15:45:20 2014
@@ -86,10 +86,10 @@ public class InitialContent implements R
 
         NodeState base = builder.getNodeState();
         NodeStore store = new MemoryNodeStore(base);
-        BuiltInNodeTypes.register(new SystemRoot(
+        NodeTypeRegistry.registerBuiltIn(new SystemRoot(
                 store, new EditorHook(new CompositeEditorProvider(
-                        new NamespaceEditorProvider(),
-                        new TypeEditorProvider()))));
+                new NamespaceEditorProvider(),
+                new TypeEditorProvider()))));
         NodeState target = store.getRoot();
         target.compareAgainstBaseState(base, new ApplyDiff(builder));
     }

Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeRegistry.java (from r1605068, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/BuiltInNodeTypes.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeRegistry.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeRegistry.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/BuiltInNodeTypes.java&r1=1605068&r2=1614692&rev=1614692&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/BuiltInNodeTypes.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeRegistry.java Wed Jul 30 15:45:20 2014
@@ -16,18 +16,16 @@
  */
 package org.apache.jackrabbit.oak.plugins.nodetype.write;
 
-import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-
 import javax.annotation.Nonnull;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.RepositoryException;
 import javax.jcr.ValueFactory;
 import javax.jcr.nodetype.NodeTypeManager;
 
+import com.google.common.base.Charsets;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.commons.cnd.ParseException;
 import org.apache.jackrabbit.oak.api.Root;
@@ -37,13 +35,13 @@ import org.apache.jackrabbit.oak.namepat
 import org.apache.jackrabbit.oak.plugins.name.ReadWriteNamespaceRegistry;
 import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
 
-import com.google.common.base.Charsets;
+import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
 
 /**
  * {@code BuiltInNodeTypes} is a utility class that registers the built-in
  * node types required for a JCR repository running on Oak.
  */
-class BuiltInNodeTypes {
+public final class NodeTypeRegistry {
 
     private final NodeTypeManager ntMgr;
 
@@ -51,7 +49,7 @@ class BuiltInNodeTypes {
 
     private final ValueFactory vf;
 
-    private BuiltInNodeTypes(final Root root) {
+    private NodeTypeRegistry(final Root root) {
         this.ntMgr =  new ReadWriteNodeTypeManager() {
             @Override
             protected Tree getTypes() {
@@ -81,30 +79,42 @@ class BuiltInNodeTypes {
      *
      * @param root the {@link Root} instance.
      */
-    public static void register(final Root root) {
-        new BuiltInNodeTypes(root).registerBuiltinNodeTypes();
-    }
-
-    private void registerBuiltinNodeTypes() {
-        // FIXME: migrate custom node types as well.
+    static void registerBuiltIn(final Root root) {
         try {
-            InputStream stream = BuiltInNodeTypes.class.getResourceAsStream("builtin_nodetypes.cnd");
+            InputStream stream = NodeTypeRegistry.class.getResourceAsStream("builtin_nodetypes.cnd");
             try {
-                CndImporter.registerNodeTypes(
-                        new InputStreamReader(stream, Charsets.UTF_8),
-                        "built-in node types", ntMgr, nsReg, vf, false);
+                register(root, stream, "built-in node types");
             } finally {
                 stream.close();
             }
         } catch (IOException e) {
-            throw new IllegalStateException(
-                    "Unable to read built-in node types", e);
+            throw new IllegalStateException("Unable to read built-in node types", e);
+        }
+    }
+
+    /**
+     * Register the node type definitions contained in the specified {@code input}
+     * using the given {@link Root}.
+     *
+     * @param root The {@code Root} to register the node types.
+     * @param input The input stream containing the node type defintions to be registered.
+     * @param systemId An informative id of the given input.
+     */
+    public static void register(Root root, InputStream input, String systemId) {
+        new NodeTypeRegistry(root).registerNodeTypes(input, systemId);
+    }
+
+    private void registerNodeTypes(InputStream stream, String systemId) {
+        try {
+            CndImporter.registerNodeTypes(
+                    new InputStreamReader(stream, Charsets.UTF_8),
+                    systemId, ntMgr, nsReg, vf, false);
+        } catch (IOException e) {
+            throw new IllegalStateException("Unable to read " + systemId, e);
         } catch (ParseException e) {
-            throw new IllegalStateException(
-                    "Unable to parse built-in node types", e);
+            throw new IllegalStateException("Unable to parse " + systemId, e);
         } catch (RepositoryException e) {
-            throw new IllegalStateException(
-                    "Unable to register built-in node types", e);
+            throw new IllegalStateException("Unable to register " + systemId, e);
         }
     }
 

Modified: jackrabbit/oak/trunk/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/pom.xml?rev=1614692&r1=1614691&r2=1614692&view=diff
==============================================================================
--- jackrabbit/oak/trunk/pom.xml (original)
+++ jackrabbit/oak/trunk/pom.xml Wed Jul 30 15:45:20 2014
@@ -55,6 +55,7 @@
     <module>oak-it</module>
     <module>oak-pojosr</module>
     <module>oak-tarmk-failover</module>
+    <module>oak-authorization-cug</module>
   </modules>
 
   <scm>