| /* |
| * 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()); |
| } |
| |
| } |