You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:56:23 UTC

[sling-org-apache-sling-oak-restrictions] annotated tag org.apache.sling.oak.restrictions-1.0.0 created (now bb088b5)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.oak.restrictions-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-oak-restrictions.git.


      at bb088b5  (tag)
 tagging 3888ba37fb6263349edcde3707726419d4be16fc (commit)
      by Robert Munteanu
      on Tue Sep 27 20:27:51 2016 +0000

- Log -----------------------------------------------------------------
org.apache.sling.oak.restrictions-1.0.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new 49238f7  Rename sling-oak-restrictions folder to oak-restrictions
     new 01a4313  [maven-release-plugin] prepare release org.apache.sling.oak.restrictions-1.0.0
     new 3888ba3  [maven-release-plugin] copy for tag org.apache.sling.oak.restrictions-1.0.0

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-oak-restrictions] 01/03: Rename sling-oak-restrictions folder to oak-restrictions

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.oak.restrictions-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-oak-restrictions.git

commit 49238f735e5ab846627db7f327e5daf890a3aa31
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Sep 27 20:25:42 2016 +0000

    Rename sling-oak-restrictions folder to oak-restrictions
    
    The sling prefix is redundant.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions@1762555 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 114 +++++++++++
 .../oak/restrictions/impl/ResourceTypePattern.java | 199 ++++++++++++++++++++
 .../impl/SlingRestrictionProviderImpl.java         | 120 ++++++++++++
 .../restrictions/impl/ResourceTypePatternTest.java | 209 +++++++++++++++++++++
 .../impl/SlingRestrictionProviderImplTest.java     | 133 +++++++++++++
 5 files changed, 775 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..271c4e5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 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. -->
+<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/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>26</version>
+        <relativePath/>
+    </parent>
+
+    <artifactId>org.apache.sling.oak.restrictions</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Oak Restrictions</name>
+    <description>
+        Supports additional restrictions for OAK (e.g. for resource type).      
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/oak-restrictions</url>
+    </scm>
+
+    <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>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <!--
+                            org.apache.jackrabbit.oak.api: Only the classes Tree, Type and PropertyState are used in a
+                            very basic version to traverse the tree
+                            org.apache.jackrabbit.oak.util: Has changed to "0.0.0" in newer versions (only TreeUtil is used)
+                        -->
+                        <Import-Package>
+                            org.apache.jackrabbit.oak.api;version="[1.0,4)",
+                            org.apache.jackrabbit.oak.util;version="0.0.0",
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>oak-core</artifactId>
+            <version>1.2.7</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.9.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/oak/restrictions/impl/ResourceTypePattern.java b/src/main/java/org/apache/sling/oak/restrictions/impl/ResourceTypePattern.java
new file mode 100644
index 0000000..1ab2ac2
--- /dev/null
+++ b/src/main/java/org/apache/sling/oak/restrictions/impl/ResourceTypePattern.java
@@ -0,0 +1,199 @@
+/*
+ * 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.sling.oak.restrictions.impl;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+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.authorization.restriction.RestrictionPattern;
+import org.apache.jackrabbit.oak.util.TreeUtil;
+import org.apache.sling.api.SlingConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Implementation of the {@link RestrictionPattern} interface that returns {@code true} if the resource type of the target tree (or the
+ * parent of a target property) is contained in the configured resource type. */
+public class ResourceTypePattern implements RestrictionPattern {
+    private static final Logger LOG = LoggerFactory.getLogger(ResourceTypePattern.class);
+
+    static final String DEFAULT_PATH = ".";
+    static final String PATH_MARKER = "@";
+    
+    static final String SLING_RESOURCE_TYPE = SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE;
+
+
+    private final String limitedToPath;
+    private final boolean matchChildren;
+    
+    private final Map<String,Set<String>> resourceTypesByPath;
+    
+  
+    ResourceTypePattern(@Nonnull Iterable<String> resourceTypesRaw, String limitedToPath, boolean matchChildren) {
+        
+        this.limitedToPath = limitedToPath;
+        this.matchChildren = matchChildren;
+        
+        Map<String,Set<String>> resourceTypesByPath = new LinkedHashMap<String,Set<String>>();
+        for (String resourceTypeRaw : resourceTypesRaw) {
+            String path;
+            String resourceType;
+            if(resourceTypeRaw.contains(PATH_MARKER)) {
+                String[] bits = resourceTypeRaw.trim().split(PATH_MARKER, 2);
+                path = bits[1];
+                resourceType = bits[0];
+            } else {
+                path = DEFAULT_PATH;
+                resourceType = resourceTypeRaw;
+            }
+                
+            Set<String> resourceTypesForPath = resourceTypesByPath.get(path);
+            if(resourceTypesForPath==null) {
+                resourceTypesForPath = new HashSet<String>();
+                resourceTypesByPath.put(path, resourceTypesForPath);
+            }
+            resourceTypesForPath.add(resourceType);
+        }
+        
+        this.resourceTypesByPath = Collections.unmodifiableMap(resourceTypesByPath);
+        LOG.trace("pattern setup with resourceTypesByPath={}",  this.resourceTypesByPath);
+    }
+    
+    String getLimitedToPath() {
+        return limitedToPath;
+    }
+
+    boolean isMatchChildren() {
+        return matchChildren;
+    }
+
+    @Override
+    public boolean matches(@Nonnull Tree tree, @Nullable PropertyState property) {
+        boolean isMatch = matchesAtTree(tree);
+        if(!isMatch && matchChildren) { // try parent hierarchy
+            Tree treeCursor = tree;
+            while(!isMatch && !treeCursor.isRoot()) {
+                treeCursor = treeCursor.getParent();
+                if(!treeCursor.getPath().startsWith(limitedToPath)) {
+                    if(LOG.isTraceEnabled()) {
+                        LOG.trace("Breaking parent traversal loop: tree={}, limitedToPath={}", treeCursor.getPath(), limitedToPath);
+                    }
+                    break; 
+                }
+                isMatch = matchesAtTree(treeCursor);
+            }
+        }
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("Match for "+tree.getPath()+": "+ (isMatch ? "YES":"NO") + " ("+this+")");
+        }
+        return isMatch;
+    }
+
+    private boolean matchesAtTree(Tree tree) {
+        boolean isResourceTypeMatch = false;
+        for (String path : resourceTypesByPath.keySet()) {
+
+                Tree treeToCheck = tree; // the default if e.g. just the resource type without @path is given
+                if(!DEFAULT_PATH.equals(path)) {
+                    try {
+                        String[] segments = path.split("/");
+                        for (String string : segments) {
+                            treeToCheck = treeToCheck.getChild(string);
+                        }
+                    } catch (IllegalArgumentException e) {
+                        continue; // continue and ignore if path is not found
+                    } 
+                }
+                
+                Set<String> resourceTypesForPath = resourceTypesByPath.get(path);
+                String actualResourceType = TreeUtil.getString(treeToCheck, SLING_RESOURCE_TYPE);
+                isResourceTypeMatch = resourceTypesForPath.contains(actualResourceType);
+                
+                if(LOG.isTraceEnabled()) {
+                    LOG.trace("isResourceTypeMatch={} (checked at path {} at sub path {})", new Object[]{isResourceTypeMatch, tree.getPath(), path});
+                }
+                if(isResourceTypeMatch) {
+                    break; // return as quickly as possible
+                }
+
+        }
+        return isResourceTypeMatch;
+    }
+
+
+    @Override
+    public boolean matches(@Nonnull String path) {
+        return false;
+    }
+
+    @Override
+    public boolean matches() {
+        // node type pattern never matches for repository level permissions
+        return false;
+    }
+
+    // -------------------------------------------------------------< Object >---
+
+    @Override
+    public String toString() {
+        return "ResourceTypePattern [limitedToPath=" + limitedToPath + ", matchChildren=" + matchChildren + ", resourceTypesByPath="
+                + resourceTypesByPath + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((limitedToPath == null) ? 0 : limitedToPath.hashCode());
+        result = prime * result + (matchChildren ? 1231 : 1237);
+        result = prime * result + ((resourceTypesByPath == null) ? 0 : resourceTypesByPath.hashCode());
+        return result;
+    }
+
+
+    @Override
+    public boolean equals(Object obj) {
+        if(this == obj)
+            return true;
+        if(obj == null)
+            return false;
+        if(getClass() != obj.getClass())
+            return false;
+        ResourceTypePattern other = (ResourceTypePattern) obj;
+        if(limitedToPath == null) {
+            if(other.limitedToPath != null)
+                return false;
+        } else if(!limitedToPath.equals(other.limitedToPath))
+            return false;
+        if(matchChildren != other.matchChildren)
+            return false;
+        if(resourceTypesByPath == null) {
+            if(other.resourceTypesByPath != null)
+                return false;
+        } else if(!resourceTypesByPath.equals(other.resourceTypesByPath))
+            return false;
+        return true;
+    }
+    
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImpl.java b/src/main/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImpl.java
new file mode 100644
index 0000000..b2867c9
--- /dev/null
+++ b/src/main/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImpl.java
@@ -0,0 +1,120 @@
+/*
+ * 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.sling.oak.restrictions.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.AbstractRestrictionProvider;
+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.RestrictionDefinitionImpl;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
+import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Sling restriction provider implementation that supports the following restrictions:
+ *
+ * <ul>
+ * <li>{@link #SLING_RESOURCE_TYPES}: A restriction that allows to match against resource types (matches are exact and do not include children).</li>
+ * <li>{@link #SLING_RESOURCE_TYPES_WITH_DESCENDANTS}: A restriction that allows to match against resource types and all sub nodes of matching resource types.</li>
+ * </ul>
+ * 
+ * Further sling restriction can be added here in future.
+*/
+@Component
+@Service(RestrictionProvider.class)
+public class SlingRestrictionProviderImpl extends AbstractRestrictionProvider {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SlingRestrictionProviderImpl.class);
+
+    public static final String SLING_RESOURCE_TYPES = "sling:resourceTypes";
+    public static final String SLING_RESOURCE_TYPES_WITH_DESCENDANTS = "sling:resourceTypesWithDescendants";
+
+    public SlingRestrictionProviderImpl() {
+        super(supportedRestrictions());
+    }
+
+    private static Map<String, RestrictionDefinition> supportedRestrictions() {
+        RestrictionDefinition slingResourceTypes = new RestrictionDefinitionImpl(SLING_RESOURCE_TYPES, Type.STRINGS, false);
+        RestrictionDefinition slingResourceTypesWithChildren = new RestrictionDefinitionImpl(SLING_RESOURCE_TYPES_WITH_DESCENDANTS, Type.STRINGS, false);
+        Map<String, RestrictionDefinition> supportedRestrictions = new HashMap<String, RestrictionDefinition>();
+        supportedRestrictions.put(slingResourceTypes.getName(), slingResourceTypes);
+        supportedRestrictions.put(slingResourceTypesWithChildren.getName(), slingResourceTypesWithChildren);
+        return Collections.unmodifiableMap(supportedRestrictions);
+    }
+
+    // ------------------------------------------------< RestrictionProvider >---
+
+    @Nonnull
+    @Override
+    public RestrictionPattern getPattern(String oakPath, @Nonnull Tree tree) {
+        if (oakPath != null) {
+            PropertyState resourceTypes = tree.getProperty(SLING_RESOURCE_TYPES);
+            if (resourceTypes != null) {
+                ResourceTypePattern resourceTypePattern = new ResourceTypePattern(resourceTypes.getValue(Type.STRINGS), oakPath, false);
+                LOG.trace("Returning resourceTypePattern={} for rep:slingResourceTypes in getPattern(String,Tree)", resourceTypePattern);
+                return resourceTypePattern;
+            }
+            PropertyState resourceTypesWithChildren = tree.getProperty(SLING_RESOURCE_TYPES_WITH_DESCENDANTS);
+            if (resourceTypesWithChildren != null) {
+                ResourceTypePattern resourceTypePattern = new ResourceTypePattern(resourceTypesWithChildren.getValue(Type.STRINGS), oakPath, true);
+                LOG.trace("Returning resourceTypePattern={} for rep:slingResourceTypesWithChildren in getPattern(String,Tree)", resourceTypePattern);
+                return resourceTypePattern;
+            }            
+        }
+        return RestrictionPattern.EMPTY;
+    }
+
+    @Nonnull
+    @Override
+    public RestrictionPattern getPattern(@Nullable String oakPath, @Nonnull Set<Restriction> restrictions) {
+
+        if (oakPath != null && !restrictions.isEmpty()) {
+            for (Restriction r : restrictions) {
+                String name = r.getDefinition().getName();
+                if (SLING_RESOURCE_TYPES.equals(name)) {
+                    ResourceTypePattern resourceTypePattern = new ResourceTypePattern(r.getProperty().getValue(Type.STRINGS), oakPath, false);
+                    LOG.trace(
+                            "Returning resourceTypePattern={} for rep:slingResourceTypes in getPattern(String,Set<Restriction>)",
+                            resourceTypePattern);
+                    return resourceTypePattern;
+                } else if(SLING_RESOURCE_TYPES_WITH_DESCENDANTS.equals(name)) {
+                    ResourceTypePattern resourceTypePattern = new ResourceTypePattern(r.getProperty().getValue(Type.STRINGS), oakPath, true);
+                    LOG.trace(
+                            "Returning resourceTypePattern={} for rep:slingResourceTypesWithChildren in getPattern(String,Set<Restriction>)",
+                            resourceTypePattern);
+                    return resourceTypePattern;
+                }
+            }
+        }
+
+        return RestrictionPattern.EMPTY;
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/oak/restrictions/impl/ResourceTypePatternTest.java b/src/test/java/org/apache/sling/oak/restrictions/impl/ResourceTypePatternTest.java
new file mode 100644
index 0000000..eaffda2
--- /dev/null
+++ b/src/test/java/org/apache/sling/oak/restrictions/impl/ResourceTypePatternTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.sling.oak.restrictions.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import java.util.Arrays;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+public class ResourceTypePatternTest {
+    
+    private static final String TEST_PATH = "/content/path/to/test";
+    
+    private static final String RESOURCE_TYPE_TEST_PATH = "myproj/comp1";
+    private static final String RESOURCE_TYPE_SUB1 = "myproj/comp2";
+    private static final String RESOURCE_TYPE_SUB2 = "myproj/comp3";
+    private static final String RESOURCE_TYPE_SUB3 = "myproj/comp4";
+    private static final String RESOURCE_TYPE_SUBSUB1 = "myproj/comp5";
+    
+    private static final String RESOURCE_TYPE_OUTSIDE_SCOPE = "myproj/outsidescope";
+    
+    private static final String TEST_NODE_SUB1 = "subfolder1";        
+    private static final String TEST_NODE_SUB2 = "subfolder2";
+    private static final String TEST_NODE_SUB3 = "subfolder3";
+    private static final String TEST_NODE_SUBSUB1 = "subsubfolder1";
+    private static final String TEST_NODE_SUBSUB2 = "subsubfolder2";
+
+    @Mock
+    private Tree testTree;
+    
+    @Mock
+    private Tree testTreeSub1;    
+   
+    @Mock
+    private Tree testTreeSub2;
+
+    @Mock
+    private Tree testTreeSub3;
+    
+    @Mock
+    private Tree testTreeSub3Sub1;
+    
+    @Mock
+    private Tree testTreeSub3Sub2;
+    
+    @Mock
+    private Tree testTreeParentOutsideScope;
+    
+    
+    private ResourceTypePattern resourceTypePattern;
+    
+
+    @Before
+    public void setup() {
+        initMocks(this);
+        
+        setupTreeMock(testTreeParentOutsideScope, StringUtils.substringBeforeLast(TEST_PATH, "/"), null, RESOURCE_TYPE_OUTSIDE_SCOPE);
+        setupTreeMock(testTree, StringUtils.substringAfterLast(TEST_PATH, "/"), testTreeParentOutsideScope, RESOURCE_TYPE_TEST_PATH);
+
+        setupTreeMock(testTreeSub1, TEST_NODE_SUB1, testTree, RESOURCE_TYPE_SUB1);
+        setupTreeMock(testTreeSub2, TEST_NODE_SUB2, testTree, RESOURCE_TYPE_SUB2);
+        setupTreeMock(testTreeSub3, TEST_NODE_SUB3, testTree, RESOURCE_TYPE_SUB3);
+
+        setupTreeMock(testTreeSub3Sub1, TEST_NODE_SUBSUB1, testTreeSub3, RESOURCE_TYPE_SUBSUB1);
+        setupTreeMock(testTreeSub3Sub2, TEST_NODE_SUBSUB2, testTreeSub3, RESOURCE_TYPE_SUBSUB1);
+        
+    }
+
+
+
+    @Test
+    public void testBasicMatchWithoutChildren() {
+        
+        resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_TEST_PATH, RESOURCE_TYPE_SUB1, RESOURCE_TYPE_SUB3), TEST_PATH, false);
+        
+        assertNonTreeFunctionsReturnFalse();
+        
+        assertTrue(resourceTypePattern.matches(testTree, null));
+        assertTrue(resourceTypePattern.matches(testTreeSub1, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub2, null));
+        assertTrue(resourceTypePattern.matches(testTreeSub3, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
+
+    }
+    
+    @Test
+    public void testMatchWithoutChildren() {
+        
+        String restrictionWithPath = RESOURCE_TYPE_SUB2+"@"+TEST_NODE_SUB2;
+        resourceTypePattern = new ResourceTypePattern(Arrays.asList(restrictionWithPath, RESOURCE_TYPE_SUB3), TEST_PATH, false);
+        
+        assertNonTreeFunctionsReturnFalse();
+        
+        assertTrue("Has to match because of @path usage "+restrictionWithPath, resourceTypePattern.matches(testTree, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub1, null));
+        assertFalse("Must not match (although it has "+RESOURCE_TYPE_SUB2+", it does not have a child '"+TEST_NODE_SUB2+"' with this resource type)", resourceTypePattern.matches(testTreeSub2, null));
+        assertTrue("Has to match because of "+RESOURCE_TYPE_SUB3+" in list", resourceTypePattern.matches(testTreeSub3, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
+    }
+    
+    @Test
+    public void testMatchWithChildren() {
+        
+        resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_SUB3), TEST_PATH, true);
+        
+        assertNonTreeFunctionsReturnFalse();
+        
+        assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTree, null));
+        assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub1, null));
+        assertFalse("Not a node at or below "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub2, null));
+        assertTrue("The node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3, null));
+        assertTrue("A node below a node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3Sub1, null));
+        assertTrue("A node below a node with "+RESOURCE_TYPE_SUB3, resourceTypePattern.matches(testTreeSub3Sub2, null));
+    }
+    
+    @Test
+    public void testMatchWithChildrenDoesNotLeaveBasePath() {
+        
+        resourceTypePattern = new ResourceTypePattern(Arrays.asList(RESOURCE_TYPE_OUTSIDE_SCOPE), TEST_PATH, true);
+        
+        assertNonTreeFunctionsReturnFalse();
+        
+        // all false as RESOURCE_TYPE_OUTSIDE_SCOPE is only found above TEST_PATH
+        assertFalse(resourceTypePattern.matches(testTree, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub1, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub2, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub1, null));
+        assertFalse(resourceTypePattern.matches(testTreeSub3Sub2, null));
+    }
+    
+    @Test
+    public void testMatchWithChildrenAndPathUsage() {
+        
+        String restrictionWithPath = RESOURCE_TYPE_SUBSUB1+"@"+TEST_NODE_SUBSUB1;
+        resourceTypePattern = new ResourceTypePattern(Arrays.asList(restrictionWithPath), TEST_PATH, true);
+        
+        assertNonTreeFunctionsReturnFalse();
+        
+        assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTree, null));
+        assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub1, null));
+        assertFalse("This node or any of its parents do not have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1,resourceTypePattern.matches(testTreeSub2, null));
+        assertTrue("This node does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3, null));
+        assertTrue("A node in parent hierarchy does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3Sub1, null));
+        assertTrue("A node in parent hierarchy does have a sub node '"+TEST_NODE_SUBSUB1+"' with "+RESOURCE_TYPE_SUBSUB1, resourceTypePattern.matches(testTreeSub3Sub2, null));
+    }
+    
+
+    private void assertNonTreeFunctionsReturnFalse() {
+        assertFalse(resourceTypePattern.matches(TEST_PATH));
+        assertFalse(resourceTypePattern.matches());
+    }
+
+    private void setupTreeMock(Tree tree, String path, Tree parentTree, String resourceType) {
+
+        doReturn(parentTree==null).when(tree).isRoot();
+        doReturn(parentTree).when(tree).getParent();
+        
+        mockGetStringProperty(tree, ResourceTypePattern.SLING_RESOURCE_TYPE, resourceType);
+        
+        String effectivePath = path;
+        if(parentTree!=null) {
+            effectivePath = parentTree.getPath() + "/" + path;
+            String childNodeName = StringUtils.substringAfterLast(effectivePath, "/");
+            doReturn(tree).when(parentTree).getChild(childNodeName);
+        }
+        doReturn(effectivePath).when(tree).getPath();
+        
+        // default for getChild
+        doThrow(new IllegalArgumentException()).when(tree).getChild(Mockito.anyString());
+        
+    }
+    
+    private void mockGetStringProperty(Tree tree, String propertyName, String value) {
+        PropertyState propertyState = mock(PropertyState.class);
+        doReturn(propertyState).when(tree).getProperty(propertyName);
+        doReturn(false).when(propertyState).isArray();
+        doReturn(value).when(propertyState).getValue(Type.STRING);
+    }
+}
diff --git a/src/test/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImplTest.java b/src/test/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImplTest.java
new file mode 100644
index 0000000..d1d58b5
--- /dev/null
+++ b/src/test/java/org/apache/sling/oak/restrictions/impl/SlingRestrictionProviderImplTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.sling.oak.restrictions.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+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.RestrictionPattern;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class SlingRestrictionProviderImplTest {
+    
+    private static final String TEST_PATH = "/content/path/to/test";
+
+    private static final String RESOURCE_TYPE1 = "myproj/comp1";
+    private static final String RESOURCE_TYPE2 = "myproj/comp2";
+    
+    @Mock
+    private Tree restrictionNodeTree;
+
+    @Mock
+    private PropertyState restrictionProperty;
+    
+    @Mock
+    private Restriction restriction;
+    
+    @Mock
+    private RestrictionDefinition definition;
+    
+    private SlingRestrictionProviderImpl slingRestrictionProviderImpl;
+
+    @Before
+    public void setup() {
+        initMocks(this);
+        
+        doReturn(definition).when(restriction).getDefinition();
+        doReturn(restrictionProperty).when(restriction).getProperty();
+    }
+    
+    @Test
+    public void testGetPatternFromTreeResourceTypes() {
+        
+        doReturn(restrictionProperty).when(restrictionNodeTree).getProperty(SlingRestrictionProviderImpl.SLING_RESOURCE_TYPES);
+        doReturn(Arrays.asList(RESOURCE_TYPE1, RESOURCE_TYPE2)).when(restrictionProperty).getValue(Type.STRINGS);
+        
+        slingRestrictionProviderImpl = new SlingRestrictionProviderImpl();
+        
+        RestrictionPattern pattern = slingRestrictionProviderImpl.getPattern(TEST_PATH, restrictionNodeTree);
+        assertTrue(pattern instanceof ResourceTypePattern);
+        ResourceTypePattern resourceTypePattern = (ResourceTypePattern) pattern;
+        
+        assertFalse(resourceTypePattern.isMatchChildren());
+        assertEquals(TEST_PATH, resourceTypePattern.getLimitedToPath());
+    }
+
+    @Test
+    public void testGetPatternFromTreeResourceTypesWithDescendants() {
+        
+        doReturn(restrictionProperty).when(restrictionNodeTree).getProperty(SlingRestrictionProviderImpl.SLING_RESOURCE_TYPES_WITH_DESCENDANTS);
+        doReturn(Arrays.asList(RESOURCE_TYPE1, RESOURCE_TYPE2)).when(restrictionProperty).getValue(Type.STRINGS);
+        
+        slingRestrictionProviderImpl = new SlingRestrictionProviderImpl();
+        
+        RestrictionPattern pattern = slingRestrictionProviderImpl.getPattern(TEST_PATH, restrictionNodeTree);
+        assertTrue(pattern instanceof ResourceTypePattern);
+        ResourceTypePattern resourceTypePattern = (ResourceTypePattern) pattern;
+        
+        assertTrue(resourceTypePattern.isMatchChildren());
+        assertEquals(TEST_PATH, resourceTypePattern.getLimitedToPath());
+    }
+    
+    @Test
+    public void testGetPatternFromRestrictionsResourceTypes() {
+        
+        doReturn(SlingRestrictionProviderImpl.SLING_RESOURCE_TYPES).when(definition).getName();
+        doReturn(Arrays.asList(RESOURCE_TYPE1, RESOURCE_TYPE2)).when(restrictionProperty).getValue(Type.STRINGS);
+        
+        slingRestrictionProviderImpl = new SlingRestrictionProviderImpl();
+        
+        RestrictionPattern pattern = slingRestrictionProviderImpl.getPattern(TEST_PATH, new HashSet<Restriction>(Arrays.asList(restriction)));
+        assertTrue(pattern instanceof ResourceTypePattern);
+        ResourceTypePattern resourceTypePattern = (ResourceTypePattern) pattern;
+        
+        assertFalse(resourceTypePattern.isMatchChildren());
+        assertEquals(TEST_PATH, resourceTypePattern.getLimitedToPath());
+
+    }
+
+    @Test
+    public void testGetPatternFromRestrictionsResourceTypesWithDescendants() {
+        
+        doReturn(SlingRestrictionProviderImpl.SLING_RESOURCE_TYPES_WITH_DESCENDANTS).when(definition).getName();
+        doReturn(Arrays.asList(RESOURCE_TYPE1, RESOURCE_TYPE2)).when(restrictionProperty).getValue(Type.STRINGS);
+        
+        slingRestrictionProviderImpl = new SlingRestrictionProviderImpl();
+        
+        RestrictionPattern pattern = slingRestrictionProviderImpl.getPattern(TEST_PATH, new HashSet<Restriction>(Arrays.asList(restriction)));
+        assertTrue(pattern instanceof ResourceTypePattern);
+        ResourceTypePattern resourceTypePattern = (ResourceTypePattern) pattern;
+        
+        assertTrue(resourceTypePattern.isMatchChildren());
+        assertEquals(TEST_PATH, resourceTypePattern.getLimitedToPath());
+
+    }
+    
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-oak-restrictions] 03/03: [maven-release-plugin] copy for tag org.apache.sling.oak.restrictions-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.oak.restrictions-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-oak-restrictions.git

commit 3888ba37fb6263349edcde3707726419d4be16fc
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Sep 27 20:27:51 2016 +0000

    [maven-release-plugin] copy for tag org.apache.sling.oak.restrictions-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.oak.restrictions-1.0.0@1762557 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-oak-restrictions] 02/03: [maven-release-plugin] prepare release org.apache.sling.oak.restrictions-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.oak.restrictions-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-oak-restrictions.git

commit 01a4313837ceb985d1d670068063d19fc26bf8e1
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Sep 27 20:27:38 2016 +0000

    [maven-release-plugin] prepare release org.apache.sling.oak.restrictions-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions@1762556 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 271c4e5..dcf6a9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,19 +9,18 @@
     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. -->
-<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/maven-v4_0_0.xsd">
+<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/maven-v4_0_0.xsd">
 
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
         <version>26</version>
-        <relativePath/>
+        <relativePath />
     </parent>
 
     <artifactId>org.apache.sling.oak.restrictions</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Oak Restrictions</name>
@@ -30,9 +29,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/oak-restrictions</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/oak-restrictions</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.oak.restrictions-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.oak.restrictions-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.oak.restrictions-1.0.0</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.