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

enorman pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git


The following commit(s) were added to refs/heads/master by this push:
     new 7587c9c  SLING-8118 Add support to set ACE restrictions from 
contentloader
7587c9c is described below

commit 7587c9c06b1378fbf42751d65d68e7c14cbd97b4
Author: Eric Norman <[email protected]>
AuthorDate: Sun Dec 16 13:58:58 2018 -0800

    SLING-8118 Add support to set ACE restrictions from contentloader
---
 pom.xml                                            |  12 +-
 .../sling/jcr/contentloader/ContentCreator.java    |  38 ++++
 .../internal/DefaultContentCreator.java            |  28 ++-
 .../contentloader/internal/readers/JsonReader.java | 151 +++++++++++++++-
 .../sling/jcr/contentloader/package-info.java      |   2 +-
 .../internal/readers/XmlReaderTest.java            |  11 ++
 .../contentloader/it/ContentloaderTestSupport.java |   3 +
 .../it/SLING8118InitialContentIT.java              | 193 +++++++++++++++++++++
 src/test/resources/initial-content/SLING-8118.json |  46 +++++
 9 files changed, 476 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index fd2cb52..290e80a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
     </parent>
 
     <artifactId>org.apache.sling.jcr.contentloader</artifactId>
-    <version>2.2.7-SNAPSHOT</version>
+    <version>2.3.0-SNAPSHOT</version>
 
     <name>Apache Sling Initial Content Loader</name>
     <description>This bundle provides initial content installation through 
bundles.</description>
@@ -158,10 +158,16 @@
       <!-- for security content loader (users/groups/acls) -->
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.jcr.base</artifactId>
-            <version>2.1.0</version>
+            <version>3.0.6</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>oak-security-spi</artifactId>
+            <version>1.8.0</version>
+            <optional>true</optional>
+        </dependency>        
+        <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.mime</artifactId>
             <version>2.1.2</version>
@@ -282,7 +288,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock-oak</artifactId>
-            <version>2.0.2</version>
+            <version>2.1.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git 
a/src/main/java/org/apache/sling/jcr/contentloader/ContentCreator.java 
b/src/main/java/org/apache/sling/jcr/contentloader/ContentCreator.java
index b53e71a..a663c51 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/ContentCreator.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/ContentCreator.java
@@ -20,8 +20,11 @@ package org.apache.sling.jcr.contentloader;
 
 import java.io.InputStream;
 import java.util.Map;
+import java.util.Set;
 
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.Value;
 
 import org.osgi.annotation.versioning.ProviderType;
 
@@ -165,4 +168,39 @@ public interface ContentCreator {
      */
     void createAce(String principal, String[] grantedPrivileges, String[] 
deniedPrivileges, String order) throws RepositoryException;
 
+    /**
+     * Creates an Access Control Entry for the current node for the specified
+     * principal and privileges.
+     *
+     * @param principal         the user or group id for the ACE
+     * @param grantedPrivileges the set of privileges to grant the principal
+     * @param deniedPrivileges  the set of privileges to deny the principal 
(for users only)
+     * @param order             specifies the position of the ACE in the 
containing ACL. (may be null)
+     *                          Value should be one of these:
+     *                          <table>
+     *                          <caption>Values</caption>
+     *                          <tr><td>first</td><td>Place the target ACE as 
the first amongst its siblings</td></tr>
+     *                          <tr><td>last</td><td>Place the target ACE as 
the last amongst its siblings</td></tr>
+     *                          <tr><td>before xyz</td><td>Place the target 
ACE immediately before the sibling whose name is xyz</td></tr>
+     *                          <tr><td>after xyz</td><td>Place the target ACE 
immediately after the sibling whose name is xyz</td></tr>
+     *                          <tr><td>numeric</td><td>Place the target ACE 
at the specified index</td></tr>
+     *                          </table>
+     * @param restrictions      specifies additional Map of single-value 
restrictions to apply. (optional)
+     * @param mvRestrictions    specifies additional Map of multi-value 
restrictions to apply. (optional)
+     * @param removedRestrictionNames optional set of restriction names that 
should be removed (if they already exist).
+     * @throws RepositoryException
+     */
+    default void createAce(String principal, String[] grantedPrivileges, 
String[] deniedPrivileges, String order, 
+               Map<String, Value> restrictions, Map<String, Value[]> 
mvRestrictions, Set<String> removedRestrictionNames) throws RepositoryException 
{
+       throw new UnsupportedOperationException();
+       }
+    
+    /**
+     * Gets the current parent Node
+     * @return the current parent node or null
+     */
+    default Node getParent() {
+       throw new UnsupportedOperationException();
+    }
+
 }
diff --git 
a/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
 
b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
index 03650d2..7ac6388 100644
--- 
a/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
+++ 
b/src/main/java/org/apache/sling/jcr/contentloader/internal/DefaultContentCreator.java
@@ -798,6 +798,16 @@ public class DefaultContentCreator implements 
ContentCreator {
      * @see 
org.apache.sling.jcr.contentloader.ContentCreator#createAce(java.lang.String, 
java.lang.String, java.lang.String[], java.lang.String[])
         */
     public void createAce(String principalId, String[] grantedPrivilegeNames, 
String[] deniedPrivilegeNames, String order) throws RepositoryException {
+       createAce(principalId, grantedPrivilegeNames, deniedPrivilegeNames, 
order, null, null, null);
+    }
+
+    /* (non-Javadoc)
+        * @see 
org.apache.sling.jcr.contentloader.ContentCreator#createAce(java.lang.String, 
java.lang.String[], java.lang.String[], java.lang.String, java.util.Map, 
java.util.Map, java.util.Set)
+        */
+       @Override
+       public void createAce(String principalId, String[] 
grantedPrivilegeNames, String[] deniedPrivilegeNames, String order,
+                       Map<String, Value> restrictions, Map<String, Value[]> 
mvRestrictions, Set<String> removedRestrictionNames)
+                       throws RepositoryException {
         final Node parentNode = this.parentNodeStack.peek();
         Session session = parentNode.getSession();
         
@@ -820,11 +830,23 @@ public class DefaultContentCreator implements 
ContentCreator {
         String resourcePath = parentNode.getPath();
 
         if ((grantedPrivilegeNames != null) || (deniedPrivilegeNames != null)) 
{
-            AccessControlUtil.replaceAccessControlEntry(session, resourcePath, 
principal, grantedPrivilegeNames, deniedPrivilegeNames, null, order);
+            AccessControlUtil.replaceAccessControlEntry(session, resourcePath, 
principal, grantedPrivilegeNames, deniedPrivilegeNames, null, order, 
+                       restrictions, mvRestrictions, removedRestrictionNames);
         }
-    }
+       }
 
-    /**
+       
+       /* (non-Javadoc)
+        * @see org.apache.sling.jcr.contentloader.ContentCreator#getParent()
+        */
+       @Override
+       public Node getParent() {
+        final Node parentNode = this.parentNodeStack.peek();
+        return parentNode;
+       }
+
+
+       /**
      * used for the md5
      */
     private static final char[] hexTable = "0123456789abcdef".toCharArray();
diff --git 
a/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
 
b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
index c14ba98..f004fcf 100644
--- 
a/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
+++ 
b/src/main/java/org/apache/sling/jcr/contentloader/internal/readers/JsonReader.java
@@ -32,8 +32,12 @@ import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
 
+import javax.jcr.Node;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
 import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonException;
@@ -41,10 +45,17 @@ import javax.json.JsonNumber;
 import javax.json.JsonObject;
 import javax.json.JsonString;
 import javax.json.JsonValue;
+import javax.json.JsonValue.ValueType;
 
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionDefinition;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
 import org.apache.sling.jcr.contentloader.ContentCreator;
 import org.apache.sling.jcr.contentloader.ContentReader;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.annotations.Component;
 
 /**
@@ -464,8 +475,146 @@ public class JsonReader implements ContentReader {
                }
 
                String order = ace.getString("order", null);
+               
+               Map<String, Value> restrictionsMap = null;
+               Map<String, Value[]> mvRestrictionsMap = null;
+               Set<String> removedRestrictionNames = null;
+               JsonObject restrictions = (JsonObject) ace.get("restrictions");
+               if (restrictions != null) {
+                       //lazy initialized map for quick lookup when processing 
restrictions
+                       Map<String, RestrictionDefinition> 
supportedRestrictionsMap = new HashMap<>();
+
+                       Node parentNode = contentCreator.getParent();
+
+                       RestrictionProvider restrictionProvider = null;
+                       Bundle bundle = FrameworkUtil.getBundle(getClass());
+                       BundleContext bundleContext = bundle.getBundleContext();
+                       ServiceReference<RestrictionProvider> serviceReference 
= null;
+                       try {
+                               serviceReference = 
bundleContext.getServiceReference(RestrictionProvider.class);
+                               restrictionProvider = 
bundleContext.getService(serviceReference);
+                               
+                               if (restrictionProvider == null) {
+                                       throw new JsonException("No restriction 
provider is available so unable to process restriction values");
+                               }
+
+                               // populate the map
+                               Set<RestrictionDefinition> 
supportedRestrictions = 
restrictionProvider.getSupportedRestrictions(parentNode.getPath());
+                               for (RestrictionDefinition 
restrictionDefinition : supportedRestrictions) {
+                                       
supportedRestrictionsMap.put(restrictionDefinition.getName(), 
restrictionDefinition);
+                               }
+                       } finally {
+                               if (serviceReference != null) {
+                                       
bundleContext.ungetService(serviceReference);
+                               }
+                       }
+                       
+                       restrictionsMap = new HashMap<>();
+                       mvRestrictionsMap = new HashMap<>();
+                       removedRestrictionNames = new HashSet<>();
+
+                       ValueFactory factory = 
parentNode.getSession().getValueFactory();
+                       
+                       Set<String> keySet = restrictions.keySet();
+                       for (String rname : keySet) {
+                               if (rname.endsWith("@Delete")) {
+                                       //add the key to the 'remove' set.  the 
value doesn't matter and is ignored.
+                                       String rname2 = rname.substring(9, 
rname.length() - 7);
+                                       removedRestrictionNames.add(rname2);
+                               } else {
+                                       RestrictionDefinition rd = 
supportedRestrictionsMap.get(rname);
+                                       if (rd == null) {
+                                               //illegal restriction name?
+                                               throw new 
JsonException("Invalid or not supported restriction name was supplied: " + 
rname);
+                                       }
+                                       
+                                       boolean multival = 
rd.getRequiredType().isArray();
+                                       int restrictionType = 
rd.getRequiredType().tag();
+
+                                       //read the requested restriction value 
and apply it
+                                       JsonValue jsonValue = 
restrictions.get(rname);
+
+                                       if (multival) {
+                                               if (jsonValue.getValueType() == 
ValueType.ARRAY) {
+                                                       JsonArray jsonArray = 
(JsonArray)jsonValue;
+                                                       int size = 
jsonArray.size();
+                                                       Value [] values = new 
Value[size];
+                                                       for (int i = 0; i < 
size; i++) {
+                                                               values[i] = 
toValue(factory, jsonArray.get(i), restrictionType);
+                                                       }
+                                                       
mvRestrictionsMap.put(rname, values);
+                                               } else {
+                                                       Value v = 
toValue(factory, jsonValue, restrictionType);
+                                                       
mvRestrictionsMap.put(rname, new Value[] {v});
+                                               }
+                                       } else {
+                                               if (jsonValue.getValueType() == 
ValueType.ARRAY) {
+                                                       JsonArray jsonArray = 
(JsonArray)jsonValue;
+                                                       int size = 
jsonArray.size();
+                                                       if (size == 1) {
+                                                               Value v = 
toValue(factory, jsonArray.get(0), restrictionType);
+                                                               
restrictionsMap.put(rname, v);
+                                                       } else if (size > 1) {
+                                                       throw new 
JsonException("Unexpected multi value array data found for single-value 
restriction value for name: " + rname);
+                                                       }
+                                               } else {
+                                                       Value v = 
toValue(factory, jsonValue, restrictionType);
+                                                       
restrictionsMap.put(rname, v);
+                                               }
+                                       }
+                               }
+                       }
+               }
 
                //do the work.
-               contentCreator.createAce(principalID, grantedPrivileges, 
deniedPrivileges, order);
+               if (restrictionsMap == null && mvRestrictionsMap == null && 
removedRestrictionNames == null) {
+                       contentCreator.createAce(principalID, 
grantedPrivileges, deniedPrivileges, order);
+               } else {
+                       contentCreator.createAce(principalID, 
grantedPrivileges, deniedPrivileges, order, restrictionsMap, mvRestrictionsMap, 
+                                       removedRestrictionNames == null ? null 
: removedRestrictionNames);
+               }
+    }
+    
+    /**
+     * Attempt to convert the JsonValue to the equivalent JCR Value object
+     * 
+     * @param factory the JCR value factory
+     * @param jsonValue the JSON value to convert
+     * @param restrictionType a hint for the expected property type of the 
value
+     * @return the Value if converted or null otherwise
+     * @throws ValueFormatException 
+     */
+    private Value toValue(ValueFactory factory, JsonValue jsonValue, int 
restrictionType) throws ValueFormatException {
+       Value value = null;
+               ValueType valueType = jsonValue.getValueType();
+               switch (valueType) {
+               case TRUE:
+                       value = factory.createValue(false);
+                       break;
+               case FALSE:
+                       value = factory.createValue(false);
+                       break;
+               case NUMBER:
+                       JsonNumber jsonNumber = (JsonNumber)jsonValue;
+                       if (jsonNumber.isIntegral()) {
+                               value = 
factory.createValue(jsonNumber.longValue());
+                       } else {
+                               value = 
factory.createValue(jsonNumber.doubleValue());
+                       }
+                       break;
+               case STRING:
+                       value = 
factory.createValue(((JsonString)jsonValue).getString(), restrictionType);
+                       break;
+               case NULL:
+                       value = null;
+                       break;
+               case ARRAY:
+               case OBJECT:
+               default:
+                       //illegal JSON?
+                       break;
+               }
+       
+       return value;
     }
 }
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/package-info.java 
b/src/main/java/org/apache/sling/jcr/contentloader/package-info.java
index 64f75e4..155fe79 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/package-info.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/package-info.java
@@ -17,6 +17,6 @@
  * under the License.
  */
 
[email protected]("0.2.2")
[email protected]("0.3.0")
 package org.apache.sling.jcr.contentloader;
 
diff --git 
a/src/test/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReaderTest.java
 
b/src/test/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReaderTest.java
index 77b1755..e4d9439 100644
--- 
a/src/test/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReaderTest.java
+++ 
b/src/test/java/org/apache/sling/jcr/contentloader/internal/readers/XmlReaderTest.java
@@ -29,8 +29,10 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.jcr.RepositoryException;
+import javax.jcr.Value;
 
 import org.apache.sling.jcr.contentloader.ContentCreator;
 
@@ -163,6 +165,15 @@ public class XmlReaderTest extends TestCase {
                                throws RepositoryException {
                }
 
+               /* (non-Javadoc)
+                * @see 
org.apache.sling.jcr.contentloader.ContentCreator#createAce(java.lang.String, 
java.lang.String[], java.lang.String[], java.lang.String, java.util.Map, 
java.util.Map, java.util.Set)
+                */
+               @Override
+               public void createAce(String principal, String[] 
grantedPrivileges, String[] deniedPrivileges, String order,
+                               Map<String, Value> restrictions, Map<String, 
Value[]> mvRestrictions,
+                               Set<String> removedRestrictionNames) throws 
RepositoryException {
+               }
+
                public void createGroup(String name, String[] members,
                                Map<String, Object> extraProperties) throws 
RepositoryException {
                }
diff --git 
a/src/test/java/org/apache/sling/jcr/contentloader/it/ContentloaderTestSupport.java
 
b/src/test/java/org/apache/sling/jcr/contentloader/it/ContentloaderTestSupport.java
index 7e71609..5bc7617 100644
--- 
a/src/test/java/org/apache/sling/jcr/contentloader/it/ContentloaderTestSupport.java
+++ 
b/src/test/java/org/apache/sling/jcr/contentloader/it/ContentloaderTestSupport.java
@@ -97,6 +97,9 @@ public abstract class ContentloaderTestSupport extends 
TestSupport {
 
     @Configuration
     public Option[] configuration() {
+       //workaround to get the required jcr.base bundle into the runtime
+       SlingOptions.versionResolver.setVersionFromProject("org.apache.sling", 
"org.apache.sling.jcr.base");
+       
         CompositeOption quickstart = (CompositeOption) quickstart();
         final Option[] options = 
Arrays.stream(quickstart.getOptions()).filter(e -> !Objects.deepEquals(e,
             
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.jcr.contentloader").version(SlingOptions.versionResolver.getVersion("org.apache.sling",
 "org.apache.sling.jcr.contentloader"))
diff --git 
a/src/test/java/org/apache/sling/jcr/contentloader/it/SLING8118InitialContentIT.java
 
b/src/test/java/org/apache/sling/jcr/contentloader/it/SLING8118InitialContentIT.java
new file mode 100644
index 0000000..dd08ec4
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/contentloader/it/SLING8118InitialContentIT.java
@@ -0,0 +1,193 @@
+/*
+ * 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.jcr.contentloader.it;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.sling.jcr.base.util.AccessControlUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.osgi.framework.Bundle;
+
+/** 
+ * test of a bundle that provides initial content that defines an ace with 
restrictions
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class SLING8118InitialContentIT extends ContentloaderTestSupport {
+
+       protected TinyBundle setupTestBundle(TinyBundle b) throws IOException {
+               b.set(SLING_INITIAL_CONTENT_HEADER, DEFAULT_PATH_IN_BUNDLE + 
";path:=" + contentRootPath);
+               addContent(b, DEFAULT_PATH_IN_BUNDLE, "SLING-8118.json");
+               return b;
+       }
+
+       @Test
+       public void bundleStarted() {
+               final Bundle b = findBundle(bundleSymbolicName);
+               assertNotNull("Expecting bundle to be found:" + 
bundleSymbolicName, b);
+               assertEquals("Expecting bundle to be active:" + 
bundleSymbolicName, Bundle.ACTIVE, b.getState());
+       }
+
+       @Test
+       public void initialContentInstalled() throws RepositoryException {
+               final String folderPath = contentRootPath + "/SLING-8118"; 
+               assertTrue("Expecting initial content to be installed", 
session.itemExists(folderPath)); 
+               assertEquals("folder has node type 'sling:Folder'", 
"sling:Folder", session.getNode(folderPath).getPrimaryNodeType().getName()); 
+       }
+
+       @Test
+       public void userCreated() throws RepositoryException {
+               UserManager userManager = 
AccessControlUtil.getUserManager(session);
+               Authorizable authorizable = 
userManager.getAuthorizable("sling8118_user");
+               assertNotNull("Expecting test user to exist", authorizable);
+       }
+
+       @Test
+       public void groupCreated() throws RepositoryException {
+               UserManager userManager = 
AccessControlUtil.getUserManager(session);
+               Authorizable authorizable = 
userManager.getAuthorizable("sling8118_group");
+               assertNotNull("Expecting test group to exist", authorizable);
+               assertTrue(authorizable instanceof Group);
+               Iterator<Authorizable> members = 
((Group)authorizable).getMembers();
+               assertTrue(members.hasNext());
+               Authorizable firstMember = members.next();
+               assertEquals("sling8118_user", firstMember.getID());
+       }
+
+       @Test
+       public void aceWithRestrictionsCreated() throws RepositoryException {
+               final String folderPath = contentRootPath + "/SLING-8118"; 
+               assertTrue("Expecting test folder to exist", 
session.itemExists(folderPath)); 
+
+               AccessControlManager accessControlManager = 
AccessControlUtil.getAccessControlManager(session);
+               AccessControlPolicy[] policies = 
accessControlManager.getPolicies(folderPath);
+               List<AccessControlEntry> allEntries = new 
ArrayList<AccessControlEntry>(); 
+               for (AccessControlPolicy accessControlPolicy : policies) {
+                       if (accessControlPolicy instanceof AccessControlList) {
+                               AccessControlEntry[] accessControlEntries = 
((AccessControlList)accessControlPolicy).getAccessControlEntries();
+                               for (AccessControlEntry accessControlEntry : 
accessControlEntries) {
+                                       allEntries.add(accessControlEntry);
+                               }
+                       }
+               }
+               assertEquals(3, allEntries.size());
+               Map<String, AccessControlEntry> aceMap = new HashMap<>();
+               for (AccessControlEntry accessControlEntry : allEntries) {
+                       aceMap.put(accessControlEntry.getPrincipal().getName(), 
accessControlEntry);
+               }
+
+               //check ACE for sling8118_user
+               AccessControlEntry testUserAce = aceMap.get("sling8118_user");
+               assertNotNull("Expected ACE for test user", testUserAce);
+               assertEquals("sling8118_user", 
testUserAce.getPrincipal().getName());
+               Privilege[] privileges = testUserAce.getPrivileges();
+               assertNotNull(privileges);
+               assertEquals(2, privileges.length);
+               Set<String> privilegeNames = new HashSet<>();
+               for (Privilege privilege : privileges) {
+                       privilegeNames.add(privilege.getName());
+               }
+               assertTrue("Expecting granted read privilege", 
privilegeNames.contains("jcr:read"));
+               assertTrue("Expecting granted write privilege", 
privilegeNames.contains("jcr:write"));
+
+               //check restrictions
+               assertTrue(testUserAce instanceof JackrabbitAccessControlEntry);
+               JackrabbitAccessControlEntry testUserJAce = 
(JackrabbitAccessControlEntry)testUserAce;
+               String[] testUserRestrictionNames = 
testUserJAce.getRestrictionNames();
+               assertNotNull(testUserRestrictionNames);
+               assertEquals(1, testUserRestrictionNames.length);
+               assertEquals("rep:glob", testUserRestrictionNames[0]);
+               Value globRestriction = testUserJAce.getRestriction("rep:glob");
+               assertNotNull(globRestriction);
+               assertEquals("glob1", globRestriction.getString());
+               
+               //check ACE for sling8118_group
+               AccessControlEntry testGroupAce = aceMap.get("sling8118_group");
+               assertNotNull("Expected ACE for test user", testGroupAce);
+               assertEquals("sling8118_group", 
testGroupAce.getPrincipal().getName());
+               privileges = testGroupAce.getPrivileges();
+               assertNotNull(privileges);
+               assertEquals(1, privileges.length);
+               privilegeNames = new HashSet<>();
+               for (Privilege privilege : privileges) {
+                       privilegeNames.add(privilege.getName());
+               }
+               assertTrue("Expecting granted modifyAccessControl privilege", 
privilegeNames.contains("jcr:modifyAccessControl"));
+
+               //check restrictions
+               assertTrue(testGroupAce instanceof 
JackrabbitAccessControlEntry);
+               JackrabbitAccessControlEntry testGroupJAce = 
(JackrabbitAccessControlEntry)testGroupAce;
+               String[] testGroupRestrictionNames = 
testGroupJAce.getRestrictionNames();
+               assertNotNull(testGroupRestrictionNames);
+               assertEquals(1, testGroupRestrictionNames.length);
+               assertEquals("rep:itemNames", testGroupRestrictionNames[0]);
+               Value[] restrictions = 
testGroupJAce.getRestrictions("rep:itemNames");
+               assertNotNull(restrictions);
+               assertEquals(2, restrictions.length);
+               assertEquals("name1", restrictions[0].getString());
+               assertEquals("name2", restrictions[1].getString());
+               
+               
+               
+               //check ACE for everyone group
+               AccessControlEntry everyoneAce = aceMap.get("everyone");
+               assertNotNull("Expected ACE for everyone", everyoneAce);
+               assertEquals("everyone", everyoneAce.getPrincipal().getName());
+               privileges = everyoneAce.getPrivileges();
+               assertNotNull(privileges);
+               assertEquals(1, privileges.length);
+
+               assertEquals("Expecting granted read privilege", "jcr:read", 
privileges[0].getName());
+
+               //check restrictions
+               assertTrue(everyoneAce instanceof JackrabbitAccessControlEntry);
+               JackrabbitAccessControlEntry everyoneJAce = 
(JackrabbitAccessControlEntry)everyoneAce;
+               String[] everyoneRestrictionNames = 
everyoneJAce.getRestrictionNames();
+               assertNotNull(everyoneRestrictionNames);
+               assertEquals(0, everyoneRestrictionNames.length);
+       }
+}
diff --git a/src/test/resources/initial-content/SLING-8118.json 
b/src/test/resources/initial-content/SLING-8118.json
new file mode 100644
index 0000000..8c84672
--- /dev/null
+++ b/src/test/resources/initial-content/SLING-8118.json
@@ -0,0 +1,46 @@
+{
+    "jcr:primaryType" : "sling:Folder",
+    "security:principals": [
+        { 
+            "name": "sling8118_user", 
+            "password": "mypassword"
+        },
+        { 
+            "name": "sling8118_group", 
+            "isgroup": true,
+            "members":[
+               "sling8118_user"
+            ]
+        }
+    ],
+    "security:acl": [
+        { 
+            "principal": "everyone", 
+            "granted": [
+                "jcr:read"
+            ]
+        },
+        { 
+            "principal": "sling8118_user", 
+            "granted": [
+                "jcr:read",
+                "jcr:write"
+            ],
+            "restrictions": {
+                               "rep:glob": "glob1"
+            }
+        },
+        { 
+            "principal": "sling8118_group", 
+            "granted": [
+                "jcr:modifyAccessControl"
+            ],
+            "restrictions": {
+               "rep:itemNames": [
+                       "name1",
+                       "name2"
+               ]
+            }
+        }
+    ]
+}

Reply via email to