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)%>
+}