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-jackrabbit-usermanager.git


The following commit(s) were added to refs/heads/master by this push:
     new 9e8abde  SLING-10437 Move integration tests (#5)
9e8abde is described below

commit 9e8abdef9a29c51f45b5d69339907f8127e91b46
Author: Eric Norman <[email protected]>
AuthorDate: Tue Jun 1 10:28:43 2021 -0700

    SLING-10437 Move integration tests (#5)
---
 pom.xml                                            |  42 ++
 .../it/AuthorizablePrivilegesInfoIT.java           |  18 +-
 .../sling/jcr/jackrabbit/usermanager/it/Retry.java |   2 +-
 .../usermanager/it/UserManagerTestSupport.java     | 220 ++++++++-
 .../usermanager/it/post/ChangeUserPasswordIT.java  |  12 +-
 .../usermanager/it/post/CreateGroupIT.java         | 185 ++++++++
 .../usermanager/it/post/CreateUserIT.java          | 280 +++++++++++
 .../it/post/CustomPostResponseCreatorImpl.java     |  55 +++
 .../usermanager/it/post/RemoveAuthorizablesIT.java | 263 +++++++++++
 .../usermanager/it/post/UpdateGroupIT.java         | 262 +++++++++++
 .../usermanager/it/post/UpdateUserIT.java          | 379 +++++++++++++++
 .../it/post/UserManagerClientTestSupport.java      | 509 ++++++++++++++++++++
 .../usermanager/it/post/UserPrivilegesInfoIT.java  | 518 +++++++++++++++++++++
 .../resource/AuthorizableResourceProviderIT.java   |  26 +-
 .../sling/servlet/default/privileges-info.json.esp |  33 ++
 15 files changed, 2745 insertions(+), 59 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6f893d3..2340281 100644
--- a/pom.xml
+++ b/pom.xml
@@ -268,11 +268,53 @@
           <version>3.0.6</version>
           <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.healthcheck.api</artifactId>
+            <version>2.0.4</version>
+            <scope>test</scope>
+        </dependency>
        <dependency>
             <groupId>org.awaitility</groupId>
             <artifactId>awaitility</artifactId>
             <version>4.0.0</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.4.13</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.13</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.0_spec</artifactId>
+            <version>1.0-alpha-1</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
+    <profiles>
+        <profile>
+            <id>jacoco-report</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.jacoco</groupId>
+                        <artifactId>jacoco-maven-plugin</artifactId>
+                        <configuration>
+                            <excludes>
+                                
<exclude>org/apache/sling/servlets/post/impl/helper/*</exclude>
+                            </excludes>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
index e0c2a07..b3759eb 100644
--- 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/AuthorizablePrivilegesInfoIT.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.ops4j.pax.exam.CoreOptions.options;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -62,8 +61,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
@@ -126,26 +123,19 @@ public class AuthorizablePrivilegesInfoIT extends 
UserManagerTestSupport {
     protected User user1;
     protected Session user1Session;
 
-    @Configuration
-    public Option[] configuration() {
-        return options(
-            baseConfiguration()
-        );
-    }
-
     @Before
     public void setup() throws RepositoryException {
         adminSession = repository.login(new SimpleCredentials("admin", 
"admin".toCharArray()));
         assertNotNull("Expected adminSession to not be null", adminSession);
 
-        user1 = createUser.createUser(adminSession, createUniqueName("user"), 
"testPwd", "testPwd", 
+        user1 = createUser.createUser(adminSession, createUniqueName("user"), 
"testPwd", "testPwd",
                 Collections.emptyMap(), new ArrayList<>());
         assertNotNull("Expected user1 to not be null", user1);
-        
+
         if (adminSession.hasPendingChanges()) {
             adminSession.save();
         }
-        
+
         user1Session = repository.login(new SimpleCredentials(user1.getID(), 
"testPwd".toCharArray()));
         assertNotNull("Expected user1Session to not be null", user1Session);
     }
@@ -210,7 +200,7 @@ public class AuthorizablePrivilegesInfoIT extends 
UserManagerTestSupport {
                 Map<String, String> propMap = new HashMap<>();
                 propMap.put("prop1", "value1");
                 propMap.put("nested/prop2", "value2");
-                user2 = createUser.createUser(user1Session, 
createUniqueName("user"), "testPwd", "testPwd", 
+                user2 = createUser.createUser(user1Session, 
createUniqueName("user"), "testPwd", "testPwd",
                         propMap, new ArrayList<>());
                 assertNotNull("Expected user2 to not be null", user2);
             } catch (RepositoryException e) {
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/Retry.java 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/Retry.java
index 5d1dcb3..01d2b15 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/Retry.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/Retry.java
@@ -44,7 +44,7 @@ public abstract class Retry {
         await().atMost(timeoutMsec, TimeUnit.MILLISECONDS)
                 .pollInterval(nextIterationDelay, TimeUnit.MILLISECONDS)
                 .ignoreExceptions()
-                .until(this::exec); 
+                .until(this::exec);
     }
 
     protected abstract boolean exec();
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/UserManagerTestSupport.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/UserManagerTestSupport.java
index 2740dfa..8991c27 100644
--- 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/UserManagerTestSupport.java
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/UserManagerTestSupport.java
@@ -18,34 +18,68 @@
  */
 package org.apache.sling.jcr.jackrabbit.usermanager.it;
 
+import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable;
 import static org.apache.sling.testing.paxexam.SlingOptions.awaitility;
 import static org.apache.sling.testing.paxexam.SlingOptions.sling;
+import static 
org.apache.sling.testing.paxexam.SlingOptions.slingCommonsCompiler;
 import static 
org.apache.sling.testing.paxexam.SlingOptions.slingQuickstartOakTar;
 import static org.apache.sling.testing.paxexam.SlingOptions.versionResolver;
+import static org.awaitility.Awaitility.await;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.streamBundle;
 import static org.ops4j.pax.exam.CoreOptions.vmOption;
+import static org.ops4j.pax.exam.CoreOptions.when;
 import static 
org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.withBnd;
 
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
-import org.apache.sling.testing.paxexam.SlingOptions;
+import javax.inject.Inject;
+
+import org.apache.felix.hc.api.Result;
+import org.apache.felix.hc.api.ResultLog;
+import org.apache.felix.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.felix.hc.api.execution.HealthCheckExecutor;
+import org.apache.felix.hc.api.execution.HealthCheckSelector;
 import org.apache.sling.testing.paxexam.TestSupport;
+import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.options.ModifiableCompositeOption;
 import org.ops4j.pax.exam.options.extra.VMOption;
+import org.ops4j.pax.tinybundles.core.TinyBundle;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Base class for UserManager related paxexam tests
  */
 public abstract class UserManagerTestSupport extends TestSupport {
+    private static final String BUNDLE_SYMBOLICNAME = "TEST-CONTENT-BUNDLE";
+    private static final String SLING_BUNDLE_RESOURCES_HEADER = 
"Sling-Bundle-Resources";
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Inject
+    private HealthCheckExecutor hcExecutor;
 
     /**
      * Use after using ConfigurationAdmin to change the configuration of
@@ -58,7 +92,7 @@ public abstract class UserManagerTestSupport extends 
TestSupport {
         private Object expectedValue;
         private Class<?> serviceClass;
 
-        public WaitForServiceUpdated(long timeoutMsec, long 
nextIterationDelay, BundleContext bundleContext, 
+        public WaitForServiceUpdated(long timeoutMsec, long 
nextIterationDelay, BundleContext bundleContext,
                 Class<?> serviceClass, String expectedKey, Object 
expectedValue) {
             super(timeoutMsec, nextIterationDelay, false);
             this.bundleContext = bundleContext;
@@ -77,21 +111,33 @@ public abstract class UserManagerTestSupport extends 
TestSupport {
         }
     }
 
+    @Configuration
+    public Option[] configuration() {
+        final String vmOpt = System.getProperty("pax.vm.options");
+        VMOption vmOption = null;
+        if (vmOpt != null && !vmOpt.isEmpty()) {
+            vmOption = new VMOption(vmOpt);
+        }
 
-    @Override
-    public ModifiableCompositeOption baseConfiguration() {
-        final Option usermanager = mavenBundle()
-                .groupId("org.apache.sling")
-                .artifactId("org.apache.sling.jcr.jackrabbit.usermanager")
-                
.version(SlingOptions.versionResolver.getVersion("org.apache.sling", 
"org.apache.sling.jcr.jackrabbit.usermanager"));
+        final String jacocoOpt = System.getProperty("jacoco.command");
+        VMOption jacocoCommand = null;
+        if (jacocoOpt != null && !jacocoOpt.isEmpty()) {
+            jacocoCommand = new VMOption(jacocoOpt);
+        }
+
+        // newer version of sling.api and dependencies for SLING-10034
+        //   may remove at a later date if the superclass includes these 
versions or later
         versionResolver.setVersionFromProject("org.apache.sling", 
"org.apache.sling.api");
         versionResolver.setVersion("org.apache.sling", 
"org.apache.sling.resourceresolver", "1.7.0"); // to be compatible with current 
o.a.sling.api
         versionResolver.setVersion("org.apache.sling", 
"org.apache.sling.scripting.core", "2.3.4"); // to be compatible with current 
o.a.sling.api
         versionResolver.setVersion("org.apache.sling", 
"org.apache.sling.scripting.api", "2.2.0"); // to be compatible with current 
o.a.sling.api
         versionResolver.setVersion("org.apache.sling", 
"org.apache.sling.servlets.resolver", "2.7.12"); // to be compatible with 
current o.a.sling.api
+        versionResolver.setVersion("org.apache.sling", 
"org.apache.sling.commons.compiler", "2.4.0"); // to be compatible with current 
o.a.sling.scripting.core
 
         return composite(
             super.baseConfiguration(),
+            when(vmOption != null).useOptions(vmOption),
+            when(jacocoCommand != null).useOptions(jacocoCommand),
             optionalRemoteDebug(),
             quickstart(),
             sling(),
@@ -107,17 +153,26 @@ public abstract class UserManagerTestSupport extends 
TestSupport {
             
factoryConfiguration("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended")
                 .put("user.mapping", new 
String[]{"org.apache.sling.jcr.jackrabbit.usermanager=sling-jcr-usermanager"})
                 .asOption(),
-            
+
             // Sling JCR UserManager
             testBundle("bundle.filename"),
             
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.jcr.jackrabbit.accessmanager").versionAsInProject(),
-            
mavenBundle().groupId("org.osgi").artifactId("org.osgi.util.converter").version("1.0.0"),
  //required by o.a.sling.api
-            
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.compiler").version("2.4.0"),
 //required by current o.a.sling.scripting.core
             junitBundles(),
             awaitility()
+        ).add(
+            // needed by latest version of org.apache.sling.api
+            
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.converter").version("1.0.14"),
+            // needed by latest version of org.apache.sling.scripting.core
+            slingCommonsCompiler()
+        ).add(
+            additionalOptions()
         ).remove(
-            usermanager
-        );
+            mavenBundle() 
.groupId("org.apache.sling").artifactId("org.apache.sling.jcr.jackrabbit.usermanager").version(versionResolver)
+        ).getOptions();
+    }
+
+    protected Option[] additionalOptions() {
+        return new Option[]{};
     }
 
     /**
@@ -150,8 +205,143 @@ public abstract class UserManagerTestSupport extends 
TestSupport {
         }
 
         newProps.put(newPropKey, newPropValue);
-        
+
         return newProps;
     }
-    
+
+    /**
+     * Wait for the health check to be ok
+     *
+     * @param timeoutMsec the max time to wait for the health check to be ok
+     * @param nextIterationDelay the sleep time between the check attempts
+     */
+    protected void waitForServerReady(long timeoutMsec, long 
nextIterationDelay) {
+        // retry until the exec call returns true and doesn't throw any 
exception
+        await().atMost(timeoutMsec, TimeUnit.MILLISECONDS)
+                .pollInterval(nextIterationDelay, TimeUnit.MILLISECONDS)
+                .until(this::doHealthCheck);
+    }
+
+    /**
+     * @return true if health checks are ok
+     */
+    protected boolean doHealthCheck() throws IOException {
+        boolean isOk = true;
+        logger.info("Performing health check");
+        HealthCheckSelector hcs = HealthCheckSelector.tags("systemalive");
+        List<HealthCheckExecutionResult> results = hcExecutor.execute(hcs);
+        logger.info("systemalive health check got {} results", results.size());
+        isOk &= !results.isEmpty();
+        for (final HealthCheckExecutionResult exR : results) {
+            final Result r = exR.getHealthCheckResult();
+            if (logger.isInfoEnabled()) {
+                logger.info("systemalive health check: {}", 
toHealthCheckResultInfo(exR, false));
+            }
+            isOk &= r.isOk();
+            if (!isOk) {
+                break; // found a failure so stop checking further
+            }
+        }
+
+        if (isOk) {
+            hcs = HealthCheckSelector.tags("bundles");
+            results = hcExecutor.execute(hcs);
+            logger.info("bundles health check got {} results", results.size());
+            isOk &= !results.isEmpty();
+            for (final HealthCheckExecutionResult exR : results) {
+                final Result r = exR.getHealthCheckResult();
+                if (logger.isInfoEnabled()) {
+                    logger.info("bundles health check: {}", 
toHealthCheckResultInfo(exR, false));
+                }
+                isOk &= r.isOk();
+                if (!isOk) {
+                    break; // found a failure so stop checking further
+                }
+            }
+        }
+        return isOk;
+    }
+
+    /**
+     * Produce a human readable report of the health check results that is 
suitable for
+     * debugging or writing to a log
+     */
+    protected String toHealthCheckResultInfo(final HealthCheckExecutionResult 
exResult, final boolean debug)  throws IOException {
+        String value = null;
+        try (StringWriter resultWriter = new StringWriter(); BufferedWriter 
writer = new BufferedWriter(resultWriter)) {
+            final Result result = exResult.getHealthCheckResult();
+
+            
writer.append('"').append(exResult.getHealthCheckMetadata().getTitle()).append('"');
+            writer.append(" result is: 
").append(result.getStatus().toString());
+            writer.newLine();
+            writer.append("   Finished: ").append(new 
SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(exResult.getFinishedAt()) + " 
after "
+                    + msHumanReadable(exResult.getElapsedTimeInMs()));
+
+            for (final ResultLog.Entry e : result) {
+                if (!debug && e.isDebug()) {
+                    continue;
+                }
+                writer.newLine();
+                writer.append("   ");
+                writer.append(e.getStatus().toString());
+                writer.append(' ');
+                writer.append(e.getMessage());
+                if (e.getException() != null) {
+                    writer.append(" ");
+                    writer.append(e.getException().toString());
+                }
+            }
+            writer.flush();
+            value = resultWriter.toString();
+        }
+        return value;
+    }
+
+    /**
+     * Add content to our test bundle
+     */
+    protected void addContent(final TinyBundle bundle, String resourcePath) 
throws IOException {
+        String pathInBundle = resourcePath;
+        resourcePath = "/content" + resourcePath;
+        try (final InputStream is = 
getClass().getResourceAsStream(resourcePath)) {
+            assertNotNull("Expecting resource to be found:" + resourcePath, 
is);
+            logger.info("Adding resource to bundle, path={}, resource={}", 
pathInBundle, resourcePath);
+            bundle.add(pathInBundle, is);
+        }
+    }
+
+    /**
+     * Override to provide the option for your test
+     *
+     * @return the tinybundle Option or null if none
+     */
+    protected Option buildBundleResourcesBundle() {
+        return null;
+    }
+
+    /**
+     * Build a test bundle containing the specified bundle resources
+     *
+     * @param header the value for the {@link #SLING_BUNDLE_RESOURCES_HEADER} 
header
+     * @param content the collection of files to embed in the tinybundle
+     * @return the tinybundle Option
+     */
+    protected Option buildBundleResourcesBundle(final String header, final 
Collection<String> content) {
+        final TinyBundle bundle = TinyBundles.bundle();
+        bundle.set(Constants.BUNDLE_SYMBOLICNAME, BUNDLE_SYMBOLICNAME);
+        bundle.set(SLING_BUNDLE_RESOURCES_HEADER, header);
+        bundle.set("Require-Capability", 
"osgi.extender;filter:=\"(&(osgi.extender=org.apache.sling.bundleresource)(version<=1.1.0)(!(version>=2.0.0)))\"");
+
+        for (final String entry : content) {
+            try {
+                addContent(bundle, entry);
+            } catch (IOException e) {
+                fail(String.format("Failed to add content to the bundle: %s.  
Reason: %s", entry, e.getMessage()));
+            }
+        }
+        return streamBundle(
+            bundle.build(withBnd())
+        ).start();
+    }
+
 }
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
index 15ce17c..f439fbc 100644
--- 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/ChangeUserPasswordIT.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-import static org.ops4j.pax.exam.CoreOptions.options;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -59,8 +58,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
@@ -115,13 +112,6 @@ public class ChangeUserPasswordIT extends 
UserManagerTestSupport {
     protected User user1;
     protected Session user1Session;
 
-    @Configuration
-    public Option[] configuration() {
-        return options(
-            baseConfiguration()
-        );
-    }
-
     @Before
     public void setup() throws RepositoryException {
         adminSession = repository.login(new SimpleCredentials("admin", 
"admin".toCharArray()));
@@ -211,7 +201,7 @@ public class ChangeUserPasswordIT extends 
UserManagerTestSupport {
                 // done with this.
                 bundleContext.ungetService(serviceReference);
             }
-            
+
             //put the original config back
             configuration.update(originalServiceProps);
             new WaitForServiceUpdated(5000, 100, bundleContext, 
ChangeUserPassword.class, "alwaysAllowSelfChangePassword",
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateGroupIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateGroupIT.java
new file mode 100644
index 0000000..84e40fd
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateGroupIT.java
@@ -0,0 +1,185 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+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;
+
+/**
+ * Tests for the 'createGroup' Sling Post Operation
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CreateGroupIT extends UserManagerClientTestSupport {
+
+    @Test
+    public void testCreateGroup() throws IOException, JsonException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        postParams.add(new BasicNameValuePair("marker", testGroupId));
+        assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, 
postParams, null);
+
+        //fetch the group profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals(testGroupId, jsonObj.getString("marker"));
+    }
+
+    @Test
+    public void testNotAuthorizedCreateGroup() throws IOException, 
JsonException {
+        testUserId = createTestUser();
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+
+        String testGroupId2 = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId2));
+        postParams.add(new BasicNameValuePair("marker", testGroupId2));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testAuthorizedCreateGroup() throws IOException, JsonException {
+        testUserId = createTestUser();
+        grantUserManagementRights(testUserId);
+
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        postParams.add(new BasicNameValuePair("marker", testGroupId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the group profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals(testGroupId, jsonObj.getString("marker"));
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testCreateGroupCustomPostResponse() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        postParams.add(new BasicNameValuePair("marker", testGroupId));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testCreateGroupMissingGroupId() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedAdminPostStatus(postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testCreateGroupAlreadyExists() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, 
postParams, null);
+
+        //post the same info again, should fail
+        assertAuthenticatedAdminPostStatus(postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testCreateGroupWithExtraProperties() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        postParams.add(new BasicNameValuePair("marker", testGroupId));
+        postParams.add(new BasicNameValuePair("displayName", "My Test Group"));
+        postParams.add(new BasicNameValuePair("url", "http://www.apache.org";));
+        assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, 
postParams, null);
+
+        //fetch the group profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals(testGroupId, jsonObj.getString("marker"));
+        assertEquals("My Test Group", jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org";, jsonObj.getString("url"));
+    }
+
+
+    /**
+     * Test for SLING-1677
+     */
+    @Test
+    public void testCreateGroupResponseAsJSON() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.json", baseServerUri);
+
+        testGroupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testGroupId));
+        postParams.add(new BasicNameValuePair("marker", testGroupId));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String json = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_JSON, postParams, HttpServletResponse.SC_OK);
+
+        //make sure the json response can be parsed as a JSON object
+        JsonObject jsonObj = parseJson(json);
+        assertNotNull(jsonObj);
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateUserIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateUserIT.java
new file mode 100644
index 0000000..cfe2e30
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CreateUserIT.java
@@ -0,0 +1,280 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+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;
+
+/**
+ * Tests for the 'createUser' Sling Post Operation
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CreateUserIT extends UserManagerClientTestSupport {
+
+    /*
+        <form action="/system/userManager/user.create.html" method="POST">
+           <div>Name: <input type="text" name=":name" value="testUser" /></div>
+           <div>Password: <input type="text" name="pwd" value="testUser" 
/></div>
+           <div>Password Confirm: <input type="text" name="pwdConfirm" 
value="testUser" /></div>
+           <input type="submit" value="Submit" />
+        </form>
+     */
+    @Test
+    public void testCreateUser() throws IOException, JsonException {
+        testUserId = "testUser" + getNextInt();
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+        final List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("marker", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        final Credentials creds = new UsernamePasswordCredentials("admin", 
"admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        // fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        final String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        final JsonObject jsonObj = parseJson(json);
+        assertEquals(testUserId, jsonObj.getString("marker"));
+        assertFalse(jsonObj.containsKey(":name"));
+        assertFalse(jsonObj.containsKey("pwd"));
+        assertFalse(jsonObj.containsKey("pwdConfirm"));
+
+        // fetch the session info to verify that the user can log in
+        final Credentials newUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+        final String getUrl2 = 
String.format("%s/system/sling/info.sessionInfo.json", baseServerUri);
+        final String json2 = getAuthenticatedContent(newUserCreds, getUrl2, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        final JsonObject jsonObj2 = parseJson(json2);
+        assertEquals(testUserId, jsonObj2.getString("userID"));
+    }
+
+    @Test
+    public void testNotAuthorizedCreateUser() throws IOException, 
JsonException {
+        testUserId2 = createTestUser();
+
+        String testUserId3 = "testUser" + getNextInt();
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+        final List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId3));
+        postParams.add(new BasicNameValuePair("marker", testUserId3));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        final Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testAuthorizedCreateUser() throws IOException, JsonException {
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        testUserId = "testUser" + getNextInt();
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+        final List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("marker", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        final Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        // fetch the user profile json to verify the settings
+        final String getUrl = 
String.format("%s/system/userManager/user/%s.json", baseServerUri, testUserId);
+        final String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        final JsonObject jsonObj = parseJson(json);
+        assertEquals(testUserId, jsonObj.getString("marker"));
+        assertFalse(jsonObj.containsKey(":name"));
+        assertFalse(jsonObj.containsKey("pwd"));
+        assertFalse(jsonObj.containsKey("pwdConfirm"));
+
+        // fetch the session info to verify that the user can log in
+        final Credentials newUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+        final String getUrl2 = 
String.format("%s/system/sling/info.sessionInfo.json", baseServerUri);
+        final String json2 = getAuthenticatedContent(newUserCreds, getUrl2, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        final JsonObject jsonObj2 = parseJson(json2);
+        assertEquals(testUserId, jsonObj2.getString("userID"));
+    }
+
+    @Test
+    public void testCreateUserMissingUserId() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testCreateUserMissingPwd() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        String userId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", userId));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testCreateUserWrongConfirmPwd() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        String userId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", userId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd2"));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testCreateUserUserAlreadyExists() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        testUserId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //post the same info again, should fail
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    /*
+    <form action="/system/userManager/user.create.html" method="POST">
+       <div>Name: <input type="text" name=":name" value="testUser" /></div>
+       <div>Password: <input type="text" name="pwd" value="testUser" /></div>
+       <div>Password Confirm: <input type="text" name="pwdConfirm" 
value="testUser" /></div>
+       <div>Extra Property #1: <input type="text" name="displayName" value="My 
Test User" /></div>
+       <div>Extra Property #2: <input type="text" name="url" 
value="http://www.apache.org"; /></div>
+       <input type="submit" value="Submit" />
+    </form>
+    */
+    @Test
+    public void testCreateUserWithExtraProperties() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        testUserId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("marker", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        postParams.add(new BasicNameValuePair("displayName", "My Test User"));
+        postParams.add(new BasicNameValuePair("url", "http://www.apache.org";));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals(testUserId, jsonObj.getString("marker"));
+        assertEquals("My Test User", jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org";, jsonObj.getString("url"));
+        assertFalse(jsonObj.containsKey(":name"));
+        assertFalse(jsonObj.containsKey("pwd"));
+        assertFalse(jsonObj.containsKey("pwdConfirm"));
+    }
+
+    /**
+     * Test for SLING-1642 to verify that user self-registration by the 
anonymous
+     * user is not allowed by default.
+     */
+    @Test
+    public void testAnonymousSelfRegistrationDisabled() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        String userId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", userId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        //user create without logging in as a privileged user should return a 
500 error
+        assertAuthenticatedPostStatus(null, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+
+    /**
+     * Test for SLING-1677
+     */
+    @Test
+    public void testCreateUserResponseAsJSON() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.json", baseServerUri);
+
+        testUserId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("marker", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String json = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_JSON, postParams, HttpServletResponse.SC_OK);
+
+        //make sure the json response can be parsed as a JSON object
+        JsonObject jsonObj = parseJson(json);
+        assertNotNull(jsonObj);
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testCreateUserCustomPostResponse() throws IOException, 
JsonException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        testUserId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+        postParams.add(new BasicNameValuePair(":name", testUserId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CustomPostResponseCreatorImpl.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CustomPostResponseCreatorImpl.java
new file mode 100644
index 0000000..160fa7f
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/CustomPostResponseCreatorImpl.java
@@ -0,0 +1,55 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.servlets.post.AbstractPostResponse;
+import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.PostResponseCreator;
+
+/**
+ * Sample implementation of the PostResponseCreator interface.
+ */
+public class CustomPostResponseCreatorImpl implements PostResponseCreator {
+
+    public PostResponse createPostResponse(SlingHttpServletRequest req) {
+        if ("custom".equals(req.getParameter(":responseType"))) {
+            return new AbstractPostResponse() {
+
+                public void onChange(String type, String... arguments) {
+                    // NO-OP
+                }
+
+                @Override
+                protected void doSend(HttpServletResponse response) throws 
IOException {
+                    response.setContentType("text/html");
+                    response.setCharacterEncoding("UTF-8");
+
+                    response.getWriter().write("Thanks!");
+                    response.getWriter().flush();
+                }
+
+            };
+        } else {
+            return null;
+        }
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/RemoveAuthorizablesIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/RemoveAuthorizablesIT.java
new file mode 100644
index 0000000..6b615c3
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/RemoveAuthorizablesIT.java
@@ -0,0 +1,263 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+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;
+
+/**
+ * Tests for the 'removeAuthorizable' Sling Post Operation
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class RemoveAuthorizablesIT extends UserManagerClientTestSupport {
+
+    @Test
+    public void testRemoveUser() throws IOException {
+        String userId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, userId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
userId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+    @Test
+    public void testNotAuthorizedRemoveUser() throws IOException {
+        //a user who is not authorized to do the action
+        testUserId2 = createTestUser();
+
+        String userId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, userId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        Credentials creds2 = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
userId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds2, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+    }
+
+    @Test
+    public void testAuthorizedRemoveUser() throws IOException {
+        //a user who is authorized to do the action
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        String userId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, userId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
userId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testRemoveUserCustomPostResponse() throws IOException {
+        String userId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
userId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testRemoveGroup() throws IOException {
+        String groupId = createTestGroup();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
groupId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+    @Test
+    public void testNotAuthorizedRemoveGroup() throws IOException {
+        //a user who is not authorized to do the action
+        testUserId2 = createTestUser();
+
+        String groupId = createTestGroup();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        Credentials creds2 = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
groupId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds2, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+    }
+
+    @Test
+    public void testAuthorizedRemoveGroup() throws IOException {
+        //a user who is authorized to do the action
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        String groupId = createTestGroup();
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
groupId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testRemoveGroupCustomPostResponse() throws IOException {
+        String groupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
groupId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testRemoveAuthorizables() throws IOException {
+        String userId = createTestUser();
+        String groupId = createTestGroup();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, userId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = String.format("%s/system/userManager.delete.html", 
baseServerUri);
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":applyTo", "group/" + groupId));
+        postParams.add(new BasicNameValuePair(":applyTo", "user/" + userId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, userId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+
+        getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+    /**
+     * Test the problem reported as SLING-1237
+     */
+    @Test
+    public void testRemoveGroupWithMembers() throws IOException {
+        String groupId = createTestGroup();
+        String userId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String addMemberPostUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
groupId);
+        List<NameValuePair> addMemberPostParams = new ArrayList<>();
+        addMemberPostParams.add(new BasicNameValuePair(":member", userId));
+        assertAuthenticatedPostStatus(creds, addMemberPostUrl, 
HttpServletResponse.SC_OK, addMemberPostParams, null);
+
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, groupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
groupId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request 
returns some data
+    }
+
+
+    /**
+     * Test for SLING-1677
+     */
+    @Test
+    public void testRemoveAuthorizablesResponseAsJSON() throws IOException, 
JsonException {
+        String userId = createTestUser();
+        String groupId = createTestGroup();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        String postUrl = String.format("%s/system/userManager.delete.json", 
baseServerUri);
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":applyTo", "group/" + groupId));
+        postParams.add(new BasicNameValuePair(":applyTo", "user/" + userId));
+        String json = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_JSON, postParams, HttpServletResponse.SC_OK);
+
+        //make sure the json response can be parsed as a JSON object
+        JsonObject jsonObj = parseJson(json);
+        assertNotNull(jsonObj);
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateGroupIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateGroupIT.java
new file mode 100644
index 0000000..0dcdab9
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateGroupIT.java
@@ -0,0 +1,262 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.JsonArray;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+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;
+
+/**
+ * Tests for the 'updateAuthorizable' Sling Post Operation on
+ * a group resource.
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class UpdateGroupIT extends UserManagerClientTestSupport {
+
+    @Test
+    public void testUpdateGroup() throws IOException, JsonException {
+        testGroupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
Group"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals("My Updated Test Group", 
jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org/updated";, 
jsonObj.getString("url"));
+    }
+
+    @Test
+    public void testNotAuthorizedUpdateGroup() throws IOException, 
JsonException {
+        //a user who is not authorized to do the action
+        testUserId2 = createTestUser();
+
+        testGroupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
Group"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testAuthorizedUpdateGroup() throws IOException, JsonException {
+        //a user who is authorized to do the action
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        testGroupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
Group"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals("My Updated Test Group", 
jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org/updated";, 
jsonObj.getString("url"));
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testUpdateGroupCustomPostResponse() throws IOException, 
JsonException {
+        testGroupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
Group"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testUpdateGroupMembers() throws IOException, JsonException {
+        testGroupId = createTestGroup();
+        testUserId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        // verify that the members array exists, but is empty
+        JsonArray members = getTestGroupMembers(creds);
+        assertEquals(0, members.size());
+
+        JsonArray memberships = getTestUserMemberships(creds);
+        assertEquals(0, memberships.size());
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        // add a group member
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":member", testUserId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        members = getTestGroupMembers(creds);
+        assertEquals(1, members.size());
+        assertEquals("/system/userManager/user/" + testUserId, 
members.getString(0));
+
+        memberships = getTestUserMemberships(creds);
+        assertEquals(1, memberships.size());
+        assertEquals("/system/userManager/group/" + testGroupId, 
memberships.getString(0));
+
+        // delete a group member
+        postParams.clear();
+        postParams.add(new BasicNameValuePair(":member@Delete", testUserId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        members = getTestGroupMembers(creds);
+        assertEquals(0, members.size());
+
+        memberships = getTestUserMemberships(creds);
+        assertEquals(0, memberships.size());
+
+    }
+
+    @Test
+    public void testAuthorizedUpdateGroupMembers() throws IOException, 
JsonException {
+        //a user who is authorized to do the action
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        testGroupId = createTestGroup();
+        testUserId = createTestUser();
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+
+        // verify that the members array exists, but is empty
+        JsonArray members = getTestGroupMembers(creds);
+        assertEquals(0, members.size());
+
+        JsonArray memberships = getTestUserMemberships(creds);
+        assertEquals(0, memberships.size());
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.html", baseServerUri, 
testGroupId);
+
+        // add a group member
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":member", testUserId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        members = getTestGroupMembers(creds);
+        assertEquals(1, members.size());
+        assertEquals("/system/userManager/user/" + testUserId, 
members.getString(0));
+
+        memberships = getTestUserMemberships(creds);
+        assertEquals(1, memberships.size());
+        assertEquals("/system/userManager/group/" + testGroupId, 
memberships.getString(0));
+
+        // delete a group member
+        postParams.clear();
+        postParams.add(new BasicNameValuePair(":member@Delete", testUserId));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        members = getTestGroupMembers(creds);
+        assertEquals(0, members.size());
+
+        memberships = getTestUserMemberships(creds);
+        assertEquals(0, memberships.size());
+
+    }
+
+    JsonArray getTestUserMemberships(Credentials creds) throws IOException, 
JsonException {
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        return jsonObj.getJsonArray("memberOf");
+    }
+
+    JsonArray getTestGroupMembers(Credentials creds) throws IOException, 
JsonException {
+        String getUrl = String.format("%s/system/userManager/group/%s.json", 
baseServerUri, testGroupId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        return jsonObj.getJsonArray("members");
+    }
+
+    /**
+     * Test for SLING-1677
+     */
+    @Test
+    public void testUpdateGroupResponseAsJSON() throws IOException, 
JsonException {
+        testGroupId = createTestGroup();
+
+        String postUrl = 
String.format("%s/system/userManager/group/%s.update.json", baseServerUri, 
testGroupId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
Group"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        String json = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_JSON, postParams, HttpServletResponse.SC_OK);
+
+        //make sure the json response can be parsed as a JSON object
+        JsonObject jsonObj = parseJson(json);
+        assertNotNull(jsonObj);
+    }
+
+}
+
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateUserIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateUserIT.java
new file mode 100644
index 0000000..f44271a
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UpdateUserIT.java
@@ -0,0 +1,379 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.apache.sling.testing.paxexam.SlingOptions.slingAuthForm;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+/**
+ * Tests for the 'updateAuthorizable' and 'changePassword' Sling Post
+ * Operations on a user resource.
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class UpdateUserIT extends UserManagerClientTestSupport {
+
+    @Override
+    protected Option[] additionalOptions() {
+        return composite(super.additionalOptions())
+                .add(slingAuthForm()) // needed for testDisableUser
+                .getOptions();
+    }
+
+    @Test
+    public void testUpdateUser() throws IOException, JsonException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.html", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
User"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+        // add nested param (SLING-6747)
+        postParams.add(new BasicNameValuePair("nested/param", "value"));
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals("My Updated Test User", jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org/updated";, 
jsonObj.getString("url"));
+        // get path (SLING-6753)
+        String path = jsonObj.getString("path");
+        assertNotNull(path);
+        // retrieve nested property via regular GET servlet
+        getUrl = String.format("%s%s/nested.json", baseServerUri, path);
+        json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, 
HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+        assertEquals("value", jsonObj.getString("param"));
+    }
+
+    /**
+     * SLING-7901 test to verify update user delete nested property 
functionality
+     */
+    @Test
+    public void testUpdateUserDeleteProperties() throws IOException, 
JsonException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.html", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+        // add nested param (SLING-6747)
+        postParams.add(new BasicNameValuePair("nested/param", "value"));
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals("http://www.apache.org/updated";, 
jsonObj.getString("url"));
+        // get path (SLING-6753)
+        String path = jsonObj.getString("path");
+        assertNotNull(path);
+        // retrieve nested property via regular GET servlet
+        getUrl = String.format("%s%s/nested.json", baseServerUri, path);
+        json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, 
HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+        assertEquals("value", jsonObj.getString("param"));
+
+        //now remove
+        postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("url@Delete", "true"));
+        // remove nested param
+        postParams.add(new BasicNameValuePair("nested/param@Delete", "true"));
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+
+        //and verify
+        getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, 
HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+        assertFalse(jsonObj.containsKey("url"));
+        // get path (SLING-6753)
+        path = jsonObj.getString("path");
+        assertNotNull(path);
+        // retrieve nested property via regular GET servlet
+        getUrl = String.format("%s%s/nested.json", baseServerUri, path);
+        json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, 
HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+        assertFalse("Nested property should not exist", 
jsonObj.containsKey("param"));
+    }
+
+    @Test
+    public void testNotAuthorizedUpdateUser() throws IOException, 
JsonException {
+        //a user who is not authorized to do the action
+        testUserId2 = createTestUser();
+
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.html", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
User"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+        // add nested param (SLING-6747)
+        postParams.add(new BasicNameValuePair("nested/param", "value"));
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_NOT_FOUND, null); //make sure the profile request is not 
there
+    }
+
+    @Test
+    public void testAuthorizedUpdateUser() throws IOException, JsonException {
+        //a user who is authorized to do the action
+        testUserId2 = createTestUser();
+        grantUserManagementRights(testUserId2);
+
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.html", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
User"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+        // add nested param (SLING-6747)
+        postParams.add(new BasicNameValuePair("nested/param", "value"));
+        Credentials creds = new UsernamePasswordCredentials(testUserId2, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+
+        //fetch the user profile json to verify the settings
+        String getUrl = String.format("%s/system/userManager/user/%s.json", 
baseServerUri, testUserId);
+        assertAuthenticatedHttpStatus(creds, getUrl, 
HttpServletResponse.SC_OK, null); //make sure the profile request returns some 
data
+        String json = getAuthenticatedContent(creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+        assertEquals("My Updated Test User", jsonObj.getString("displayName"));
+        assertEquals("http://www.apache.org/updated";, 
jsonObj.getString("url"));
+        // get path (SLING-6753)
+        String path = jsonObj.getString("path");
+        assertNotNull(path);
+        // retrieve nested property via regular GET servlet
+        getUrl = String.format("%s%s/nested.json", baseServerUri, path);
+        json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, 
HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+        assertEquals("value", jsonObj.getString("param"));
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testUpdateUserCustomPostResponse() throws IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.html", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
User"));
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testChangeUserPassword() throws IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.changePassword.html", 
baseServerUri, testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("oldPwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("newPwd", "testNewPwd"));
+        postParams.add(new BasicNameValuePair("newPwdConfirm", "testNewPwd"));
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+    }
+
+    /**
+     * Test for SLING-7831
+     */
+    @Test
+    public void testChangeUserPasswordCustomPostResponse() throws IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.changePassword.html", 
baseServerUri, testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":responseType", "custom"));
+        postParams.add(new BasicNameValuePair("oldPwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("newPwd", "testNewPwd"));
+        postParams.add(new BasicNameValuePair("newPwdConfirm", "testNewPwd"));
+
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        String content = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_HTML, postParams, HttpServletResponse.SC_OK);
+        assertEquals("Thanks!", content); //verify that the content matches 
the custom response
+    }
+
+    @Test
+    public void testChangeUserPasswordWrongOldPwd() throws IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.changePassword.html", 
baseServerUri, testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("oldPwd", "wrongTestPwd"));
+        postParams.add(new BasicNameValuePair("newPwd", "testNewPwd"));
+        postParams.add(new BasicNameValuePair("newPwdConfirm", "testNewPwd"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    @Test
+    public void testChangeUserPasswordWrongConfirmPwd() throws IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.changePassword.html", 
baseServerUri, testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("oldPwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("newPwd", "testNewPwd"));
+        postParams.add(new BasicNameValuePair("newPwdConfirm", 
"wrongTestNewPwd"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, postParams, null);
+    }
+
+    /**
+     * Test for SLING-1677
+     */
+    @Test
+    public void testUpdateUserResponseAsJSON() throws IOException, 
JsonException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.update.json", baseServerUri, 
testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("displayName", "My Updated Test 
User"));
+        postParams.add(new BasicNameValuePair("url", 
"http://www.apache.org/updated";));
+        Credentials creds = new UsernamePasswordCredentials(testUserId, 
"testPwd");
+        String json = getAuthenticatedPostContent(creds, postUrl, 
CONTENT_TYPE_JSON, postParams, HttpServletResponse.SC_OK);
+
+        //make sure the json response can be parsed as a JSON object
+        JsonObject jsonObj = parseJson(json);
+        assertNotNull(jsonObj);
+    }
+
+
+    /**
+     * Test for SLING-2069
+     * @throws IOException
+     */
+    @Test
+    public void testChangeUserPasswordAsAdministratorWithoutOldPwd() throws 
IOException {
+        testUserId = createTestUser();
+
+        String postUrl = 
String.format("%s/system/userManager/user/%s.changePassword.html", 
baseServerUri, testUserId);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("newPwd", "testNewPwd"));
+        postParams.add(new BasicNameValuePair("newPwdConfirm", "testNewPwd"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+    }
+
+    /**
+     * Test for SLING-2072
+     */
+    @Test
+    public void testDisableUser() throws IOException {
+        testUserId = createTestUser();
+
+        //login before the user is disabled, so login should work
+        List<NameValuePair> params = new ArrayList<>();
+        params.add(new BasicNameValuePair("j_username", testUserId));
+        params.add(new BasicNameValuePair("j_password", "testPwd"));
+        params.add(new BasicNameValuePair("j_validate", "true"));
+        String postUrl = String.format("%s/j_security_check", baseServerUri);
+        assertAuthenticatedPostStatus(null, postUrl, 
HttpServletResponse.SC_OK, params, null,
+                response -> assertNull(response.getFirstHeader("X-Reason")));
+        httpContext.getCredentialsProvider().clear();
+        httpContext.getCookieStore().clear();
+
+        //update the user to disable it
+        postUrl = String.format("%s/system/userManager/user/%s.update.html", 
baseServerUri, testUserId);
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":disabled", "true"));
+        postParams.add(new BasicNameValuePair(":disabledReason", "Just 
Testing"));
+        assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, 
postParams, null);
+
+        //the user is now disabled, so login should fail
+        postUrl = String.format("%s/j_security_check", baseServerUri);
+        assertAuthenticatedPostStatus(null, postUrl, 
HttpServletResponse.SC_FORBIDDEN, params, null,
+                response -> 
assertNotNull(response.getFirstHeader("X-Reason")));
+        httpContext.getCredentialsProvider().clear();
+        httpContext.getCookieStore().clear();
+
+        //enable the user again
+        postUrl = String.format("%s/system/userManager/user/%s.update.html", 
baseServerUri, testUserId);
+        postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":disabled", "false"));
+        assertAuthenticatedAdminPostStatus(postUrl, HttpServletResponse.SC_OK, 
postParams, null);
+
+        //login after the user is enabled, so login should work
+        postUrl = String.format("%s/j_security_check", baseServerUri);
+        assertAuthenticatedPostStatus(null, postUrl, 
HttpServletResponse.SC_OK, params, null,
+                response -> assertNull(response.getFirstHeader("X-Reason")));
+        httpContext.getCredentialsProvider().clear();
+        httpContext.getCookieStore().clear();
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserManagerClientTestSupport.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserManagerClientTestSupport.java
new file mode 100644
index 0000000..219b64f
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserManagerClientTestSupport.java
@@ -0,0 +1,509 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static 
org.apache.sling.testing.paxexam.SlingOptions.slingCommonsCompiler;
+import static 
org.apache.sling.testing.paxexam.SlingOptions.slingJcrJackrabbitSecurity;
+import static 
org.apache.sling.testing.paxexam.SlingOptions.slingScriptingJavascript;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static 
org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.apache.sling.jcr.jackrabbit.usermanager.it.UserManagerTestSupport;
+import org.apache.sling.servlets.post.PostResponseCreator;
+import org.junit.After;
+import org.junit.Before;
+import org.ops4j.pax.exam.Option;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * base class for tests doing http requests to verify calls to the usermanager
+ * servlets
+ */
+public abstract class UserManagerClientTestSupport extends 
UserManagerTestSupport {
+    protected static final String TEST_FOLDER_JSON = "{'jcr:primaryType': 
'nt:unstructured'}";
+
+    protected static final String CONTENT_TYPE_JSON = "application/json";
+    protected static final String CONTENT_TYPE_HTML = "text/html";
+
+    protected static long randomId = System.currentTimeMillis();
+
+    protected static synchronized long getNextInt() {
+        final long val = randomId;
+        randomId++;
+        return val;
+    }
+
+    @Inject
+    protected ConfigurationAdmin cm;
+
+    protected ServiceRegistration<PostResponseCreator> serviceReg;
+
+    protected static final String COOKIE_SLING_FORMAUTH = "sling.formauth";
+    protected static final String COOKIE_SLING_FORMAUTH_DOMAIN = 
"sling.formauth.cookie.domain";
+    protected static final String HEADER_SET_COOKIE = "Set-Cookie";
+
+    protected URI baseServerUri;
+    protected HttpClientContext httpContext;
+    protected CloseableHttpClient httpClient;
+
+    protected String testUserId = null;
+    protected String testUserId2 = null;
+    protected String testUserId3 = null;
+    protected String testGroupId = null;
+    protected String testFolderUrl = null;
+
+    @Override
+    protected Option[] additionalOptions() {
+        // optionally create a tinybundle that contains a test script
+        final Option bundle = buildBundleResourcesBundle();
+
+        return new Option[]{
+            // for usermanager support
+            slingJcrJackrabbitSecurity(),
+            // add javascript support for the test script
+            slingCommonsCompiler(),
+            when(bundle != null).useOptions(slingScriptingJavascript()),
+
+            // add the test script tinybundle
+            when(bundle != null).useOptions(bundle),
+
+            // enable the healthcheck configuration for checking when the 
server is ready to
+            //  receive http requests.  (adapted from the starter 
healthcheck.json configuration)
+            
factoryConfiguration("org.apache.felix.hc.generalchecks.FrameworkStartCheck")
+                .put("hc.tags", new String[] {"systemalive"})
+                .put("targetStartLevel", 5)
+                .asOption(),
+            
factoryConfiguration("org.apache.felix.hc.generalchecks.ServicesCheck")
+                .put("hc.tags", new String[] {"systemalive"})
+                .put("services.list", new String[] {
+                        "org.apache.sling.jcr.api.SlingRepository",
+                        "org.apache.sling.engine.auth.Authenticator",
+                        
"org.apache.sling.api.resource.ResourceResolverFactory",
+                        "org.apache.sling.api.servlets.ServletResolver",
+                        "javax.script.ScriptEngineManager"
+                })
+                .asOption(),
+            
factoryConfiguration("org.apache.felix.hc.generalchecks.BundlesStartedCheck")
+                .put("hc.tags", new String[] {"bundles"})
+                .asOption(),
+            
factoryConfiguration("org.apache.sling.jcr.contentloader.hc.BundleContentLoadedCheck")
+                .put("hc.tags", new String[] {"bundles"})
+                .asOption(),
+        };
+    }
+
+    @Before
+    public void before() throws IOException, URISyntaxException {
+        Bundle bundle = FrameworkUtil.getBundle(getClass());
+        Dictionary<String, Object> props = new Hashtable<>(); // NOSONAR
+        serviceReg = 
bundle.getBundleContext().registerService(PostResponseCreator.class,
+                new CustomPostResponseCreatorImpl(), props);
+
+        // wait for the health checks to be OK
+        waitForServerReady(Duration.ofMinutes(1).toMillis(), 500);
+
+        // calculate the address of the http server
+        baseServerUri = getBaseServerUri();
+        assertNotNull(baseServerUri);
+
+        HttpHost targetHost = new HttpHost(baseServerUri.getHost(), 
baseServerUri.getPort(), baseServerUri.getScheme());
+        AuthCache authCache = new BasicAuthCache();
+        authCache.put(targetHost, new BasicScheme());
+
+        // prepare the http client for the test user
+        httpContext = HttpClientContext.create();
+        httpContext.setCookieStore(new BasicCookieStore());
+        httpContext.setCredentialsProvider(new BasicCredentialsProvider());
+        httpContext.setAuthCache(authCache);
+        RequestConfig requestConfig = 
RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
+        httpContext.setRequestConfig(requestConfig);
+        httpClient = HttpClients.custom()
+                .disableRedirectHandling()
+                .build();
+    }
+
+    @After
+    public void after() throws IOException {
+        if (serviceReg != null) {
+            serviceReg.unregister();
+        }
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+        if (testFolderUrl != null) {
+            //remove the test user if it exists.
+            List<NameValuePair> postParams = new ArrayList<>();
+            postParams.add(new BasicNameValuePair(":operation", "delete"));
+            assertAuthenticatedPostStatus(creds, testFolderUrl, 
HttpServletResponse.SC_OK, postParams, null);
+        }
+        if (testGroupId != null) {
+            //remove the test user if it exists.
+            String postUrl = 
String.format("%s/system/userManager/group/%s.delete.html", baseServerUri, 
testGroupId);
+            assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, Collections.emptyList(), null);
+        }
+        if (testUserId != null) {
+            //remove the test user if it exists.
+            String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
testUserId);
+            assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, Collections.emptyList(), null);
+        }
+        if (testUserId2 != null) {
+            //remove the test user if it exists.
+            String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
testUserId2);
+            assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, Collections.emptyList(), null);
+        }
+        if (testUserId3 != null) {
+            //remove the test user if it exists.
+            String postUrl = 
String.format("%s/system/userManager/user/%s.delete.html", baseServerUri, 
testUserId3);
+            assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, Collections.emptyList(), null);
+        }
+
+        // close/cleanup the test user http client
+        if (httpClient != null) {
+            httpClient.close();
+            httpClient = null;
+        }
+
+        // clear out other state
+        httpContext = null;
+        baseServerUri = null;
+    }
+
+    /**
+     * Calculate the base server URI from the current configuration of the
+     * httpservice
+     */
+    protected URI getBaseServerUri() throws IOException, URISyntaxException {
+        assertNotNull(cm);
+        Configuration httpServiceConfiguration = 
cm.getConfiguration("org.apache.felix.http");
+        Dictionary<String, Object> properties = 
httpServiceConfiguration.getProperties();
+
+        String host;
+        Object hostObj = properties.get("org.apache.felix.http.host");
+        if (hostObj == null) {
+            host = "localhost";
+        } else {
+            assertTrue(hostObj instanceof String);
+            host = (String)hostObj;
+        }
+        assertNotNull(host);
+
+        String scheme = null;
+        Object portObj = null;
+        Object httpsEnableObj = 
properties.get("org.apache.felix.https.enable");
+        if ("true".equals(httpsEnableObj)) {
+            scheme = "https";
+            portObj = properties.get("org.osgi.service.http.port.secure");
+        } else {
+            Object httpEnableObj = 
properties.get("org.apache.felix.http.enable");
+            if (httpEnableObj == null || "true".equals(httpEnableObj)) {
+                scheme = "http";
+                portObj = properties.get("org.osgi.service.http.port");
+            } else {
+                fail("Expected either http or https to be enabled");
+            }
+        }
+        int port = -1;
+        if (portObj instanceof Number) {
+            port = ((Number)portObj).intValue();
+        }
+        assertTrue(port > 0);
+
+        return new URI(String.format("%s://%s:%d", scheme, host, port));
+    }
+
+    protected void assertPrivilege(Collection<String> privileges, boolean 
expected, String privilegeName) {
+        if(expected != privileges.contains(privilegeName)) {
+            fail("Expected privilege " + privilegeName + " to be "
+                    + (expected ? "included" : "NOT INCLUDED")
+                    + " in supplied list: " + privileges + ")");
+        }
+    }
+
+    protected Object doAuthenticatedWork(Credentials creds, 
AuthenticatedWorker worker) throws IOException {
+        Object result = null;
+        AuthScope authScope = new AuthScope(baseServerUri.getHost(), 
baseServerUri.getPort(), baseServerUri.getScheme());
+        CredentialsProvider oldCredentialsProvider = 
httpContext.getCredentialsProvider();
+        try {
+            BasicCredentialsProvider credentialsProvider = new 
BasicCredentialsProvider();
+            httpContext.setCredentialsProvider(credentialsProvider);
+            if (creds != null) {
+                credentialsProvider.setCredentials(authScope, creds);
+            }
+
+            result = worker.doWork();
+        } finally {
+            httpContext.setCredentialsProvider(oldCredentialsProvider);
+        }
+        return result;
+    }
+
+    protected void assertAuthenticatedAdminPostStatus(String url, int 
expectedStatusCode, List<NameValuePair> postParams, String assertMessage) 
throws IOException {
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, url, expectedStatusCode, 
postParams, assertMessage);
+    }
+    protected void assertAuthenticatedPostStatus(Credentials creds, String 
url, int expectedStatusCode, List<NameValuePair> postParams, String 
assertMessage) throws IOException {
+        assertAuthenticatedPostStatus(creds, url, expectedStatusCode, 
postParams, assertMessage, null);
+    }
+    protected void assertAuthenticatedPostStatus(Credentials creds, String 
url, int expectedStatusCode, List<NameValuePair> postParams, String 
assertMessage, ValidateResponse validate) throws IOException {
+        doAuthenticatedWork(creds, () -> {
+            HttpPost postRequest = new HttpPost(url);
+            postRequest.setEntity(new UrlEncodedFormEntity(postParams));
+            try (CloseableHttpResponse response = 
httpClient.execute(postRequest, httpContext)) {
+                assertEquals(assertMessage, expectedStatusCode, 
response.getStatusLine().getStatusCode());
+                if (validate != null) {
+                    validate.validate(response);
+                }
+            }
+            return null;
+        });
+    }
+
+    protected void assertAuthenticatedHttpStatus(Credentials creds, String 
urlString, int expectedStatusCode, String assertMessage) throws IOException {
+        doAuthenticatedWork(creds, () -> {
+            HttpGet getRequest = new HttpGet(urlString);
+            try (CloseableHttpResponse response = 
httpClient.execute(getRequest, httpContext)) {
+                assertEquals(assertMessage, expectedStatusCode, 
response.getStatusLine().getStatusCode());
+                return null;
+            }
+        });
+    }
+
+    protected String getAuthenticatedContent(Credentials creds, String url, 
String expectedContentType, int expectedStatusCode) throws IOException {
+        return (String)doAuthenticatedWork(creds, () -> {
+            HttpGet getRequest = new HttpGet(url);
+            try (CloseableHttpResponse response = 
httpClient.execute(getRequest, httpContext)) {
+                assertEquals(expectedStatusCode, 
response.getStatusLine().getStatusCode());
+                final Header h = response.getFirstHeader("Content-Type");
+                if (expectedContentType == null) {
+                    if (h != null) {
+                        fail("Expected null Content-Type, got " + 
h.getValue());
+                    }
+                } else if (h == null) {
+                    fail(
+                            "Expected Content-Type that starts with '" + 
expectedContentType
+                            +" but got no Content-Type header at " + url
+                    );
+                } else {
+                    assertTrue(
+                        "Expected Content-Type that starts with '" + 
expectedContentType
+                        + "' for " + url + ", got '" + h.getValue() + "'",
+                        h.getValue().startsWith(expectedContentType)
+                    );
+                }
+                return EntityUtils.toString(response.getEntity());
+            }
+        });
+    }
+
+    protected String getAuthenticatedPostContent(Credentials creds, String 
url, String expectedContentType, List<NameValuePair> postParams, int 
expectedStatusCode) throws IOException {
+        return (String)doAuthenticatedWork(creds, () -> {
+            HttpPost postRequest = new HttpPost(url);
+            postRequest.setEntity(new UrlEncodedFormEntity(postParams));
+            try (CloseableHttpResponse response = 
httpClient.execute(postRequest, httpContext)) {
+                assertEquals(expectedStatusCode, 
response.getStatusLine().getStatusCode());
+                final Header h = response.getFirstHeader("Content-Type");
+                if (expectedContentType == null) {
+                    if (h != null) {
+                        fail("Expected null Content-Type, got " + 
h.getValue());
+                    }
+                } else if (h == null) {
+                    fail(
+                            "Expected Content-Type that starts with '" + 
expectedContentType
+                            +" but got no Content-Type header at " + url
+                    );
+                } else {
+                    assertTrue(
+                        "Expected Content-Type that starts with '" + 
expectedContentType
+                        + "' for " + url + ", got '" + h.getValue() + "'",
+                        h.getValue().startsWith(expectedContentType)
+                    );
+                }
+                return EntityUtils.toString(response.getEntity());
+            }
+        });
+    }
+
+    protected String createTestUser() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/user.create.html", baseServerUri);
+
+        String userId = "testUser" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", userId));
+        postParams.add(new BasicNameValuePair("pwd", "testPwd"));
+        postParams.add(new BasicNameValuePair("pwdConfirm", "testPwd"));
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        final String msg = "Unexpected status while attempting to create test 
user at " + postUrl;
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, msg);
+
+        final String sessionInfoUrl = 
String.format("%s/system/sling/info.sessionInfo.json", baseServerUri);
+        assertAuthenticatedHttpStatus(creds, sessionInfoUrl, 
HttpServletResponse.SC_OK,
+                "session info failed for user " + userId);
+
+        return userId;
+    }
+
+    protected String createTestGroup() throws IOException {
+        String postUrl = 
String.format("%s/system/userManager/group.create.html", baseServerUri);
+
+        String groupId = "testGroup" + getNextInt();
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair(":name", groupId));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        final String msg = "Unexpected status while attempting to create test 
group at " + postUrl;
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, msg);
+
+        return groupId;
+    }
+
+    protected String createTestFolder() throws IOException {
+        return createTestFolder(null, "sling-tests");
+    }
+
+    protected String createTestFolder(String parentPath, String nameHint) 
throws IOException {
+        return createTestFolder(parentPath, nameHint, TEST_FOLDER_JSON);
+    }
+    protected String createTestFolder(String parentPath, String nameHint, 
String jsonImport) throws IOException {
+        JsonObject json = importJSON(parentPath, nameHint, jsonImport);
+        return String.format("%s%s", baseServerUri, json.getString("path"));
+    }
+
+    protected JsonObject importJSON(String nameHint, String jsonImport) throws 
IOException {
+        return importJSON(null, nameHint, jsonImport);
+    }
+
+    protected JsonObject importJSON(String parentPath, String nameHint, String 
jsonImport) throws IOException {
+        JsonObject result = null;
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        result = (JsonObject)doAuthenticatedWork(creds, () -> {
+            List<NameValuePair> parameters = new ArrayList<>();
+            parameters.add(new BasicNameValuePair(":operation", "import"));
+            if (nameHint != null) {
+                parameters.add(new BasicNameValuePair(":nameHint", nameHint));
+            }
+            parameters.add(new BasicNameValuePair(":content", jsonImport));
+            parameters.add(new BasicNameValuePair(":contentType", "json"));
+            parameters.add(new BasicNameValuePair(":replaceProperties", 
"true"));
+
+            String postUrl = String.format("%s%s", baseServerUri, parentPath 
!= null ? parentPath : "/content");
+            HttpPost postRequest = new HttpPost(postUrl);
+            postRequest.setEntity(new UrlEncodedFormEntity(parameters));
+            postRequest.addHeader(new BasicHeader("Accept", 
"application/json,*/*;q=0.9"));
+            JsonObject jsonObj = null;
+            try (CloseableHttpResponse response = 
httpClient.execute(postRequest, httpContext)) {
+                assertEquals(HttpServletResponse.SC_CREATED, 
response.getStatusLine().getStatusCode());
+                jsonObj = 
parseJson(EntityUtils.toString(response.getEntity()));
+            }
+            return jsonObj;
+        });
+        return result;
+    }
+
+    /**
+     * Grant the minimum privilges neede for oak User Management
+     *
+     * @param principalId the principal
+     */
+    protected void grantUserManagementRights(String principalId) throws 
IOException {
+        String postUrl = String.format("%s/home.modifyAce.html", 
baseServerUri);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("principalId", principalId));
+        postParams.add(new BasicNameValuePair("privilege@jcr:read", 
"granted"));
+        postParams.add(new BasicNameValuePair("privilege@rep:write", 
"granted"));
+        postParams.add(new 
BasicNameValuePair("privilege@jcr:readAccessControl", "granted"));
+        postParams.add(new 
BasicNameValuePair("privilege@jcr:modifyAccessControl", "granted"));
+        postParams.add(new BasicNameValuePair("privilege@rep:userManagement", 
"granted"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        final String info = "Granting principal " + principalId + " user 
management rights via " + postUrl;
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, info);
+    }
+
+    /**
+     * @param json the json string to parse
+     * @return the parsed JsonObject
+     */
+    protected JsonObject parseJson(String json) {
+        JsonObject jsonObj = null;
+        try (JsonReader reader = Json.createReader(new StringReader(json))) {
+            jsonObj = reader.readObject();
+        }
+        return jsonObj;
+    }
+
+    protected static interface AuthenticatedWorker {
+        public Object doWork() throws IOException;
+    }
+
+    protected static interface ValidateResponse {
+        public void validate(CloseableHttpResponse response) throws 
IOException;
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserPrivilegesInfoIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserPrivilegesInfoIT.java
new file mode 100644
index 0000000..4a7a13d
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/post/UserPrivilegesInfoIT.java
@@ -0,0 +1,518 @@
+/*
+ * 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.jackrabbit.usermanager.it.post;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.message.BasicNameValuePair;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class UserPrivilegesInfoIT extends UserManagerClientTestSupport {
+
+    @Override
+    protected Option buildBundleResourcesBundle() {
+        final List<String> resourcePaths = 
Arrays.asList("/apps/sling/servlet/default/privileges-info.json.esp");
+        final String bundleResourcesHeader = String.join(",", resourcePaths);
+        return buildBundleResourcesBundle(bundleResourcesHeader, 
resourcePaths);
+    }
+
+    private void grantUserManagerRights(String principalId) throws IOException 
{
+        String postUrl = String.format("%s/home.modifyAce.html", 
baseServerUri);
+
+        List<NameValuePair> postParams = new ArrayList<>();
+        postParams.add(new BasicNameValuePair("principalId", principalId));
+        postParams.add(new BasicNameValuePair("privilege@jcr:read", 
"granted"));
+        postParams.add(new BasicNameValuePair("privilege@rep:write", 
"granted"));
+        postParams.add(new 
BasicNameValuePair("privilege@jcr:readAccessControl", "granted"));
+        postParams.add(new 
BasicNameValuePair("privilege@jcr:modifyAccessControl", "granted"));
+        postParams.add(new BasicNameValuePair("privilege@rep:userManagement", 
"granted"));
+
+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+        assertAuthenticatedPostStatus(creds, postUrl, 
HttpServletResponse.SC_OK, postParams, null);
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to add a new user.
+     */
+    @Test
+    public void testCanAddUser() throws JsonException, IOException {
+        testUserId = createTestUser();
+
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        assertEquals(false, jsonObj.getBoolean("canAddUser"));
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canAddUser"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canAddUser"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to add a new group.
+     */
+    @Test
+    public void testCanAddGroup() throws IOException, JsonException {
+        testUserId = createTestUser();
+
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        assertEquals(false, jsonObj.getBoolean("canAddGroup"));
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canAddGroup"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canAddGroup"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to update the properties of the specified user.
+     */
+    @Test
+    public void testCanUpdateUserProperties() throws IOException, 
JsonException {
+        testUserId = createTestUser();
+
+        //1. verify user can update thier own properties
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //user can update their own properties
+        assertEquals(true, jsonObj.getBoolean("canUpdateProperties"));
+
+
+        //2. now try another user
+        testUserId2 = createTestUser();
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUser2Creds = new 
UsernamePasswordCredentials(testUserId2, "testPwd");
+
+        String json2 = getAuthenticatedContent(testUser2Creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        JsonObject jsonObj2 = parseJson(json2);
+
+        //user can not update other users properties
+        assertEquals(false, jsonObj2.getBoolean("canUpdateProperties"));
+
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateProperties"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateProperties"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to update the properties of the specified group.
+     */
+    @Test
+    public void testCanUpdateGroupProperties() throws IOException, 
JsonException {
+        testGroupId = createTestGroup();
+        testUserId = createTestUser();
+
+        //1. Verify non admin user can not update group properties
+        String getUrl = 
String.format("%s/system/userManager/group/%s.privileges-info.json", 
baseServerUri, testGroupId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //normal user can not update group properties
+        assertEquals(false, jsonObj.getBoolean("canUpdateProperties"));
+
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateProperties"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateProperties"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to remove the specified user.
+     */
+    @Test
+    public void testCanRemoveUser() throws IOException, JsonException {
+        testUserId = createTestUser();
+
+        //1. verify user can remove themselves as they have jcr:all 
permissions by default in the starter
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //user can remove themself
+        assertEquals(true, jsonObj.getBoolean("canRemove"));
+
+
+        //2. now try another user
+        testUserId2 = createTestUser();
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUser2Creds = new 
UsernamePasswordCredentials(testUserId2, "testPwd");
+
+        String json2 = getAuthenticatedContent(testUser2Creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        JsonObject jsonObj2 = parseJson(json2);
+
+        //user can not delete other users
+        assertEquals(false, jsonObj2.getBoolean("canRemove"));
+
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canRemove"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canRemove"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to remove the specified group.
+     */
+    @Test
+    public void testCanRemoveGroup() throws IOException, JsonException {
+        testGroupId = createTestGroup();
+        testUserId = createTestUser();
+
+        //1. Verify non admin user can not remove group
+        String getUrl = 
String.format("%s/system/userManager/group/%s.privileges-info.json", 
baseServerUri, testGroupId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //normal user can not remove group
+        assertEquals(false, jsonObj.getBoolean("canRemove"));
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canRemove"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canRemove"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to update the membership of the specified group.
+     */
+    @Test
+    public void testCanUpdateGroupMembers() throws IOException, JsonException {
+        testGroupId = createTestGroup();
+        testUserId = createTestUser();
+
+        //1. Verify non admin user can not update group membership
+        String getUrl = 
String.format("%s/system/userManager/group/%s.privileges-info.json", 
baseServerUri, testGroupId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //normal user can not remove group
+        assertEquals(false, jsonObj.getBoolean("canUpdateGroupMembers"));
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateGroupMembers"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canUpdateGroupMembers"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to change the password of the specified user.
+     */
+    @Test
+    public void testCanChangePassword() throws IOException, JsonException {
+        testUserId = createTestUser();
+
+        //1. verify user can update thier own password
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //user can update their own password
+        assertEquals(true, jsonObj.getBoolean("canChangePassword"));
+
+
+        //2. now try another user
+        testUserId2 = createTestUser();
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUser2Creds = new 
UsernamePasswordCredentials(testUserId2, "testPwd");
+
+        String json2 = getAuthenticatedContent(testUser2Creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        JsonObject jsonObj2 = parseJson(json2);
+
+        //user can not update other users password
+        assertEquals(false, jsonObj2.getBoolean("canChangePassword"));
+
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        assertEquals(true, jsonObj.getBoolean("canChangePassword"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        //user can update other users password
+        assertEquals(true, jsonObj.getBoolean("canChangePassword"));
+    }
+
+    /**
+     * Checks whether the current user has been granted privileges
+     * to disable the specified user.
+     */
+    @Test
+    public void testCanDisable() throws IOException, JsonException {
+        testUserId = createTestUser();
+
+        //1. verify user can disable themselves
+        String getUrl = 
String.format("%s/system/userManager/user/%s.privileges-info.json", 
baseServerUri, testUserId);
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUserCreds = new 
UsernamePasswordCredentials(testUserId, "testPwd");
+
+        String json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        JsonObject jsonObj = parseJson(json);
+
+        //user can can disable themselves
+        assertEquals(true, jsonObj.getBoolean("canDisable"));
+
+
+        //2. now try another user
+        testUserId2 = createTestUser();
+
+        //fetch the JSON for the test page to verify the settings.
+        Credentials testUser2Creds = new 
UsernamePasswordCredentials(testUserId2, "testPwd");
+
+        String json2 = getAuthenticatedContent(testUser2Creds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json2);
+        JsonObject jsonObj2 = parseJson(json2);
+
+        //user can not disable other user
+        assertEquals(false, jsonObj2.getBoolean("canDisable"));
+
+
+        //try admin user
+        testUserCreds = new UsernamePasswordCredentials("admin", "admin");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        //admin can disable other user
+        assertEquals(true, jsonObj.getBoolean("canDisable"));
+
+        //try non-admin with sufficient privileges
+        testUserId3 = createTestUser();
+        grantUserManagerRights(testUserId3);
+
+        testUserCreds = new UsernamePasswordCredentials(testUserId3, 
"testPwd");
+
+        json = getAuthenticatedContent(testUserCreds, getUrl, 
CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+        assertNotNull(json);
+        jsonObj = parseJson(json);
+
+        //user can disable other user
+        assertEquals(true, jsonObj.getBoolean("canDisable"));
+    }
+
+}
diff --git 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/resource/AuthorizableResourceProviderIT.java
 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/resource/AuthorizableResourceProviderIT.java
index 39c23b9..38d14ce 100644
--- 
a/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/resource/AuthorizableResourceProviderIT.java
+++ 
b/src/test/java/org/apache/sling/jcr/jackrabbit/usermanager/it/resource/AuthorizableResourceProviderIT.java
@@ -21,7 +21,6 @@ package 
org.apache.sling.jcr.jackrabbit.usermanager.it.resource;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-import static org.ops4j.pax.exam.CoreOptions.options;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -55,8 +54,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
@@ -78,7 +75,7 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
 
     @Inject
     protected BundleContext bundleContext;
-    
+
     @Inject
     protected SlingRepository repository;
 
@@ -87,7 +84,7 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
 
     @Inject
     protected ConfigurationAdmin configAdmin;
-    
+
     @Inject
     private CreateUser createUser;
 
@@ -102,18 +99,11 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
 
     @Rule
     public TestName testName = new TestName();
-    
+
     protected Session adminSession;
     protected User user1;
     protected Group group1;
 
-    @Configuration
-    public Option[] configuration() {
-        return options(
-            baseConfiguration()
-        );
-    }
-
     @Before
     public void setup() throws RepositoryException {
         adminSession = repository.login(new SimpleCredentials("admin", 
"admin".toCharArray()));
@@ -165,7 +155,7 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
     protected String createUniqueName(String prefix) {
         return String.format("%s_%s%d", prefix, testName.getMethodName(), 
counter.incrementAndGet());
     }
-    
+
     /**
      * Test changing the usermanager provider.root value
      */
@@ -181,9 +171,9 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
             // update the service configuration to ensure the option is enabled
             Dictionary<String, Object> newServiceProps = 
replaceConfigProp(originalServiceProps, "provider.root", PEOPLE_ROOT);
             configuration.update(newServiceProps);
-            new WaitForServiceUpdated(5000, 100, bundleContext, 
SystemUserManagerPaths.class, 
+            new WaitForServiceUpdated(5000, 100, bundleContext, 
SystemUserManagerPaths.class,
                     "provider.root", PEOPLE_ROOT);
-            
+
             serviceReference = 
bundleContext.getServiceReference(SystemUserManagerPaths.class);
             assertEquals(PEOPLE_ROOT, 
serviceReference.getProperty("provider.root"));
 
@@ -194,10 +184,10 @@ public class AuthorizableResourceProviderIT extends 
UserManagerTestSupport {
                 // done with this.
                 bundleContext.ungetService(serviceReference);
             }
-            
+
             //put the original config back
             configuration.update(originalServiceProps);
-            new WaitForServiceUpdated(5000, 100, bundleContext, 
SystemUserManagerPaths.class, "provider.root", 
+            new WaitForServiceUpdated(5000, 100, bundleContext, 
SystemUserManagerPaths.class, "provider.root",
                     originalServiceProps == null ? 
AuthorizableResourceProvider.DEFAULT_SYSTEM_USER_MANAGER_PATH : 
originalServiceProps.get("provider.root"));
         }
     }
diff --git 
a/src/test/resources/content/apps/sling/servlet/default/privileges-info.json.esp
 
b/src/test/resources/content/apps/sling/servlet/default/privileges-info.json.esp
new file mode 100644
index 0000000..800900e
--- /dev/null
+++ 
b/src/test/resources/content/apps/sling/servlet/default/privileges-info.json.esp
@@ -0,0 +1,33 @@
+<% 
+/*
+ * 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.
+ */
+
+var privilegesInfo = 
sling.getService(Packages.org.apache.sling.jackrabbit.usermanager.AuthorizablePrivilegesInfo);
+var authorizable = 
resource.adaptTo(Packages.org.apache.jackrabbit.api.security.user.Authorizable);
+var userID = authorizable ? authorizable.getID() : null;
+%>
+{
+  "canAddUser" : <%=privilegesInfo.canAddUser(currentSession)%>,
+  "canAddGroup" : <%=privilegesInfo.canAddGroup(currentSession)%>,
+  "canUpdateProperties" : 
<%=privilegesInfo.canUpdateProperties(currentSession, userID)%>,
+  "canRemove" : <%=privilegesInfo.canRemove(currentSession, userID)%>,
+  "canUpdateGroupMembers" : 
<%=privilegesInfo.canUpdateGroupMembers(currentSession, userID)%>,
+  "canDisable" : <%=privilegesInfo.canDisable(currentSession, userID)%>,
+  "canChangePassword" : <%=privilegesInfo.canChangePassword(currentSession, 
userID)%>
+}

Reply via email to