blob: 2aab271d64a9ab27df0e32b741bd8df465d4c159 [file] [log] [blame]
/*
* 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.accessmanager.it;
import static org.apache.sling.testing.paxexam.SlingOptions.slingBundleresource;
import static org.apache.sling.testing.paxexam.SlingOptions.slingCommonsCompiler;
import static org.apache.sling.testing.paxexam.SlingOptions.slingJcrJackrabbitAccessmanager;
import static org.apache.sling.testing.paxexam.SlingOptions.slingJcrJackrabbitUsermanager;
import static org.apache.sling.testing.paxexam.SlingOptions.slingScriptingJavascript;
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.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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
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.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Before;
import org.ops4j.pax.exam.Option;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import jakarta.json.Json;
import jakarta.json.JsonException;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
/**
* base class for tests doing http requests to verify calls to the accessmanager
* servlets
*/
public abstract class AccessManagerClientTestSupport extends AccessManagerTestSupport {
protected static final int SC_UNPROCESSABLE_ENTITY = 422; // http status code for 422 Unprocessable Entity
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;
@Inject
protected ResourceResolverFactory resourceResolverFactory;
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 testGroupId = null;
protected String testFolderUrl = null;
@Override
protected Option[] additionalOptions() throws IOException {
// optionally create a tinybundle that contains a test script
final Option bundle = buildBundleResourcesBundle();
return new Option[]{
slingBundleresource(),
// for usermanager support
slingJcrJackrabbitAccessmanager(),
slingJcrJackrabbitUsermanager(),
// 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 Exception {
// 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();
// SLING-12081 - wait for the "users" resource to be available to try to avoid flaky
// failures while creating test users
Awaitility.await("users resource available")
.atMost(10000, TimeUnit.MILLISECONDS)
.pollInterval(1000, TimeUnit.MILLISECONDS)
.ignoreException(LoginException.class)
.until(() -> {
Map<String, Object> authInfo = new HashMap<>();
authInfo.put(ResourceResolverFactory.USER, "admin");
authInfo.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
try (ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(authInfo)) {
return resourceResolver.getResource("/system/userManager/user") != null;
}
});
}
@After
public void after() throws Exception {
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);
}
// 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 void assertPrivilege(JsonObject privilegesObject, boolean expectedPrivilege, PrivilegeValues privilegeState, String privilegeName) {
assertPrivilege(privilegesObject, expectedPrivilege, privilegeState, privilegeName, null);
}
protected void assertPrivilege(JsonObject privilegesObject, boolean expectedPrivilege, PrivilegeValues privilegeState, String privilegeName,
VerifyAce verifyAce) {
assertPrivilege(privilegesObject, expectedPrivilege, privilegeState, privilegeName, true, verifyAce);
}
protected void assertPrivilege(JsonObject privilegesObject, boolean expectedPrivilege, PrivilegeValues privilegeState, String privilegeName,
boolean expectedForAllow,
VerifyAce verifyAce) {
assertNotNull(privilegesObject);
if (expectedPrivilege != privilegesObject.containsKey(privilegeName)) {
fail("Expected privilege " + privilegeName + " to be "
+ (expectedPrivilege ? "included" : "NOT INCLUDED")
+ " in supplied object)");
}
JsonObject privilegeObj = privilegesObject.getJsonObject(privilegeName);
if (!expectedPrivilege) {
assertNull(privilegeObj);
} else {
assertNotNull(privilegeObj);
String key = privilegeState.toString();;
if (expectedForAllow) {
assertTrue("Expected privilege " + privilegeName + " to have key: " + key,
privilegeObj.containsKey(key));
JsonValue jsonValue = privilegeObj.get(key);
if (verifyAce != null) {
verifyAce.verify(jsonValue);
}
} else {
assertFalse("Did not expect privilege " + privilegeName + " to have key: " + key,
privilegeObj.containsKey(key));
}
}
}
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);
credentialsProvider.setCredentials(authScope, creds);
result = worker.doWork();
} finally {
httpContext.setCredentialsProvider(oldCredentialsProvider);
}
return result;
}
protected void assertAuthenticatedPostStatus(Credentials creds, String url, int expectedStatusCode, List<NameValuePair> postParams, String assertMessage) throws IOException {
doAuthenticatedWork(creds, () -> {
HttpPost postRequest = new HttpPost(url);
postRequest.setEntity(new UrlEncodedFormEntity(postParams));
try (CloseableHttpResponse response = httpClient.execute(postRequest, httpContext)) {
verifyHttpStatus(response, assertMessage, expectedStatusCode);
}
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)) {
verifyHttpStatus(response, assertMessage, expectedStatusCode);
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)) {
verifyHttpStatus(response, null, expectedStatusCode);
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)) {
verifyHttpStatus(response, null, expectedStatusCode);
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)) {
verifyHttpStatus(response, null, HttpServletResponse.SC_CREATED);
jsonObj = parseJson(EntityUtils.toString(response.getEntity()));
}
return jsonObj;
});
return result;
}
/**
* @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 VerifyAce {
public void verify(JsonValue jsonValue);
}
protected enum PrivilegeValues {
ALLOW("allow"),
DENY("deny"),
NONE("none"),
BOGUS("bogus"); //to simulate invalid value
private String paramValue;
private PrivilegeValues(String paramValue) {
this.paramValue = paramValue;
}
@Override
public String toString() {
return paramValue;
}
}
protected enum DeleteValues {
ALL("all"),
ALLOW("allow"),
DENY("deny"),
// some invalid values for testing
TRUE("true"),
VALUE_DOES_NOT("value does not"),
MATTER("matter");
private String paramValue;
private DeleteValues(String paramValue) {
this.paramValue = paramValue;
}
@Override
public String toString() {
return paramValue;
}
}
protected static class AcePostParamsBuilder {
List<NameValuePair> list = new ArrayList<>();
public AcePostParamsBuilder(String principalId) {
with("principalId", principalId);
}
public AcePostParamsBuilder withPrivilege(String privilegeName, PrivilegeValues value) {
return with("privilege@" + privilegeName, value.toString());
}
public AcePostParamsBuilder withDeletePrivilege(String privilegeName, DeleteValues value) {
return with(String.format("privilege@%s@Delete", privilegeName), value.toString());
}
public AcePostParamsBuilder withRestriction(String restrictionName, String restrictionValue) {
return with(String.format("restriction@%s", restrictionName), restrictionValue);
}
public AcePostParamsBuilder withRestriction(String restrictionName, String[] restrictionValues) {
return with(String.format("restriction@%s", restrictionName), restrictionValues);
}
public AcePostParamsBuilder withDeleteRestriction(String restrictionName, DeleteValues value) {
return with(String.format("restriction@%s@Delete", restrictionName), "true");
}
public AcePostParamsBuilder withPrivilegeRestriction(PrivilegeValues value, String privilegeName, String restrictionName, String restrictionValue) {
switch (value) {
case ALLOW:
with(String.format("restriction@%s@%s@Allow", privilegeName, restrictionName), restrictionValue);
break;
case DENY:
with(String.format("restriction@%s@%s@Deny", privilegeName, restrictionName), restrictionValue);
break;
default:
break;
}
return this;
}
public AcePostParamsBuilder withPrivilegeRestriction(PrivilegeValues value, String privilegeName, String restrictionName, String[] restrictionValues) {
for (String restrictionValue : restrictionValues) {
withPrivilegeRestriction(value, privilegeName, restrictionName, restrictionValue);
}
return this;
}
public AcePostParamsBuilder withDeletePrivilegeRestriction(String privilegeName, String restrictionName, DeleteValues value) {
return with(String.format("restriction@%s@%s@Delete", privilegeName, restrictionName), value.toString());
}
public AcePostParamsBuilder withOrder(String order) {
return with("order", order);
}
public AcePostParamsBuilder withRedirect(String redirectTo) {
return with(":redirect", redirectTo);
}
public AcePostParamsBuilder with(String key, String value) {
list.add(new BasicNameValuePair(key, value));
return this;
}
public AcePostParamsBuilder with(String key, String[] values) {
for (String value : values) {
list.add(new BasicNameValuePair(key, value));
}
return this;
}
public List<NameValuePair> build() {
return list;
}
}
protected void addOrUpdateAce(String folderUrl, List<NameValuePair> postParams) throws IOException, JsonException {
addOrUpdateAce(folderUrl, postParams, HttpServletResponse.SC_OK);
}
protected void addOrUpdateAce(String folderUrl, List<NameValuePair> postParams, int expectedStatus) throws IOException, JsonException {
String postUrl = folderUrl + ".modifyAce.html";
Credentials creds = new UsernamePasswordCredentials("admin", "admin");
assertAuthenticatedPostStatus(creds, postUrl, expectedStatus, postParams, null);
}
protected String addOrUpdateAce(String folderUrl, List<NameValuePair> postParams, String contentType) throws IOException, JsonException {
return addOrUpdateAce(folderUrl, postParams, contentType, HttpServletResponse.SC_OK);
}
protected String addOrUpdateAce(String folderUrl, List<NameValuePair> postParams, String contentType, int expectedStatus) throws IOException, JsonException {
String postUrl = folderUrl + ".modifyAce." + (CONTENT_TYPE_JSON.equals(contentType) ? "json" : "html");
Credentials creds = new UsernamePasswordCredentials("admin", "admin");
return getAuthenticatedPostContent(creds, postUrl, contentType, postParams, expectedStatus);
}
protected JsonObject getAcl(String folderUrl) throws IOException, JsonException {
String getUrl = folderUrl + ".acl.json";
Credentials creds = new UsernamePasswordCredentials("admin", "admin");
String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
assertNotNull(json);
JsonObject aclObject = parseJson(json);
return aclObject;
}
protected JsonObject getPrincipalAce(String folderUrl, String principalId) throws IOException, JsonException {
return getPrincipalAce(folderUrl, principalId, CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
}
protected JsonObject getPrincipalAce(String folderUrl, String principalId, String expectedContentType, int expectedStatus) throws IOException, JsonException {
String getUrl = folderUrl + ".pace.json?pid=" + principalId;
Credentials creds = new UsernamePasswordCredentials("admin", "admin");
String json = getAuthenticatedContent(creds, getUrl, expectedContentType, expectedStatus);
JsonObject aceObject = null;
if (expectedStatus == HttpServletResponse.SC_OK) {
assertNotNull(json);
aceObject = parseJson(json);
}
return aceObject;
}
protected JsonObject getAce(String folderUrl, String principalId) throws IOException, JsonException {
JsonObject aclObject = getAcl(folderUrl);
assertNotNull(aclObject);
JsonObject aceObj = aclObject.getJsonObject(principalId);
assertNotNull(aceObj);
assertEquals(principalId, aceObj.getString("principal"));
return aceObj;
}
protected JsonObject getAcePrivleges(String folderUrl, String principalId) throws IOException, JsonException {
JsonObject ace = getAce(folderUrl, principalId);
JsonObject privilegesObject = ace.getJsonObject("privileges");
assertNotNull(privilegesObject);
return privilegesObject;
}
/**
* Verify expected status and show error message in case expected status is not returned.
*
* @param response The SlingHttpResponse of an executed request.
* @param errorMessage error message; if {@code null}, errorMessage is extracted from response
* @param expectedStatus List of acceptable HTTP Statuses
*/
protected void verifyHttpStatus(HttpResponse response, String errorMessage, int... expectedStatus) throws IOException {
if (!checkStatus(response, expectedStatus)) {
failWithErrorAndResponseContent(response, errorMessage, expectedStatus);
}
}
/**
* Check if the response status matches one of the expected values
*
* @param response the response to check
* @param expectedStatus the set of status values that are expected
* @return true if the status is as expected, false otherwise
*/
protected boolean checkStatus(HttpResponse response, int... expectedStatus) {
// if no HttpResponse was given
if (response == null) {
throw new NullPointerException("The response is null!");
}
// if no expected statuses are given
if (expectedStatus == null || expectedStatus.length == 0) {
throw new IllegalArgumentException("At least one expected HTTP Status must be set!");
}
// get the returned HTTP Status
int givenStatus = response.getStatusLine().getStatusCode();
// check if it matches with an expected one
for (int expected : expectedStatus) {
if (givenStatus == expected) {
return true;
}
}
return false;
}
/**
* Fail with a message that includes the response content
*
* @param response the response to check
* @param errorMessage the extra error message to use (or null)
* @param expectedStatus the set of status values that are expected
*/
protected void failWithErrorAndResponseContent(HttpResponse response, String errorMessage, int... expectedStatus) throws IOException {
// build error message
StringBuilder errorMsgBuilder = new StringBuilder();
errorMsgBuilder.append("Expected HTTP Status: ");
for (int expected : expectedStatus) {
errorMsgBuilder.append(expected).append(" ");
}
errorMsgBuilder.append(". Instead ")
.append(response.getStatusLine().getStatusCode())
.append(" was returned!\n");
if (errorMessage != null) {
errorMsgBuilder.append(errorMessage);
}
String content = EntityUtils.toString(response.getEntity());
errorMsgBuilder.append("\nResponse Content:\n")
.append(content);
// fail with the error message
fail(errorMsgBuilder.toString());
}
}