SLING-879: New Bundle to provide actions for interacting with the jackrabbit AccessManager 
https://issues.apache.org/jira/browse/SLING-879
Applied integration tests about jackrabbit access manager integration

git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk@756393 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/AbstractAccessManagerTest.java b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/AbstractAccessManagerTest.java
new file mode 100644
index 0000000..9d4165c
--- /dev/null
+++ b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/AbstractAccessManagerTest.java
@@ -0,0 +1,196 @@
+/*

+ * 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.launchpad.webapp.integrationtest.accessManager;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.URL;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.commons.httpclient.Credentials;

+import org.apache.commons.httpclient.Header;

+import org.apache.commons.httpclient.HttpException;

+import org.apache.commons.httpclient.NameValuePair;

+import org.apache.commons.httpclient.UsernamePasswordCredentials;

+import org.apache.commons.httpclient.auth.AuthScope;

+import org.apache.commons.httpclient.methods.GetMethod;

+import org.apache.commons.httpclient.methods.PostMethod;

+import org.apache.sling.commons.testing.integration.HttpTestBase;

+import org.apache.sling.servlets.post.SlingPostConstants;

+

+/**

+ * Base class for AccessManager tests.

+ */

+public abstract class AbstractAccessManagerTest extends HttpTestBase {

+

+	public static final String TEST_BASE_PATH = "/sling-tests";

+

+    /** Execute a POST request and check status */

+    protected void assertAuthenticatedPostStatus(Credentials creds, String url, int expectedStatusCode, List<NameValuePair> postParams, String assertMessage)

+    throws IOException {

+        final PostMethod post = new PostMethod(url);

+        post.setFollowRedirects(false);

+        

+        URL baseUrl = new URL(HTTP_BASE_URL);

+        AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);

+        post.setDoAuthentication(true);

+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);

+        try {

+			httpClient.getState().setCredentials(authScope, creds);

+	        

+	        if(postParams!=null) {

+	            final NameValuePair [] nvp = {};

+	            post.setRequestBody(postParams.toArray(nvp));

+	        }

+	

+	        final int status = httpClient.executeMethod(post);

+	        if(assertMessage == null) {

+	            assertEquals(expectedStatusCode, status);

+	        } else {

+	            assertEquals(assertMessage, expectedStatusCode, status);

+	        }

+        } finally {

+        	httpClient.getState().setCredentials(authScope, oldCredentials);

+        }

+    }

+

+    /** Verify that given URL returns expectedStatusCode

+     * @throws IOException */

+    protected void assertAuthenticatedHttpStatus(Credentials creds, String urlString, int expectedStatusCode, String assertMessage) throws IOException {

+        URL baseUrl = new URL(HTTP_BASE_URL);

+        AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);

+        GetMethod getMethod = new GetMethod(urlString);

+        getMethod.setDoAuthentication(true);

+        

+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);

+    	try {

+			httpClient.getState().setCredentials(authScope, creds);

+

+			final int status = httpClient.executeMethod(getMethod);

+            if(assertMessage == null) {

+                assertEquals(urlString,expectedStatusCode, status);

+            } else {

+                assertEquals(assertMessage, expectedStatusCode, status);

+            }

+    	} finally {

+        	httpClient.getState().setCredentials(authScope, oldCredentials);

+    	}

+    }

+

+    

+    /** retrieve the contents of given URL and assert its content type

+     * @param expectedContentType use CONTENT_TYPE_DONTCARE if must not be checked 

+     * @throws IOException

+     * @throws HttpException */

+    protected String getAuthenticatedContent(Credentials creds, String url, String expectedContentType, List<NameValuePair> params, int expectedStatusCode) throws IOException {

+        final GetMethod get = new GetMethod(url);

+

+        URL baseUrl = new URL(HTTP_BASE_URL);

+        AuthScope authScope = new AuthScope(baseUrl.getHost(), baseUrl.getPort(), AuthScope.ANY_REALM);

+        get.setDoAuthentication(true);

+        Credentials oldCredentials = httpClient.getState().getCredentials(authScope);

+    	try {

+			httpClient.getState().setCredentials(authScope, creds);

+			

+	        if(params != null) {

+	            final NameValuePair [] nvp = new NameValuePair[0];

+	            get.setQueryString(params.toArray(nvp));

+	        }

+	        final int status = httpClient.executeMethod(get);

+	        final InputStream is = get.getResponseBodyAsStream();

+	        final StringBuffer content = new StringBuffer();

+	        final String charset = get.getResponseCharSet();

+	        final byte [] buffer = new byte[16384];

+	        int n = 0;

+	        while( (n = is.read(buffer, 0, buffer.length)) > 0) {

+	            content.append(new String(buffer, 0, n, charset));

+	        }

+	        assertEquals("Expected status " + expectedStatusCode + " for " + url + " (content=" + content + ")",

+	                expectedStatusCode,status);

+	        final Header h = get.getResponseHeader("Content-Type");

+	        if(expectedContentType == null) {

+	            if(h!=null) {

+	                fail("Expected null Content-Type, got " + h.getValue());

+	            }

+	        } else if(CONTENT_TYPE_DONTCARE.equals(expectedContentType)) {

+	            // no check

+	        } 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 content.toString();

+			

+    	} finally {

+        	httpClient.getState().setCredentials(authScope, oldCredentials);

+    	}

+    }

+    

+    

+    protected static int counter = 1;

+    

+	protected String createTestUser() throws IOException {

+        String postUrl = HTTP_BASE_URL + "/system/userManager/user.create.html";

+

+		String testUserId = "testUser" + (counter++);

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair(":name", testUserId));

+		postParams.add(new NameValuePair("pwd", "testPwd"));

+		postParams.add(new NameValuePair("pwdConfirm", "testPwd"));

+		assertPostStatus(postUrl, HttpServletResponse.SC_OK, postParams, null);

+		

+		return testUserId;

+	}

+    

+	protected String createTestGroup() throws IOException {

+        String postUrl = HTTP_BASE_URL + "/system/userManager/group.create.html";

+

+		String testGroupId = "testGroup" + (counter++);

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair(":name", testGroupId));

+		

+		//success would be a redirect to the welcome page of the webapp

+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		

+		return testGroupId;

+	}

+	

+	protected String createTestFolder() throws IOException {

+        String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + "testFolder" + (counter++);

+

+        final String location = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);

+        assertHttpStatus(location + DEFAULT_EXT, HttpServletResponse.SC_OK,

+                "POST must redirect to created resource (" + location + ")");

+        assertTrue("Node (" + location + ") must have generated name",

+                !location.endsWith("/*"));

+        assertTrue("Node (" + location + ") must created be under POST URL (" + postUrl + ")",

+                location.contains(postUrl + "/"));

+

+        return location;

+	}

+}

diff --git a/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
new file mode 100644
index 0000000..ccfefa7
--- /dev/null
+++ b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
@@ -0,0 +1,140 @@
+/*

+ * 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.launchpad.webapp.integrationtest.accessManager;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.commons.httpclient.Credentials;

+import org.apache.commons.httpclient.NameValuePair;

+import org.apache.commons.httpclient.UsernamePasswordCredentials;

+import org.apache.sling.commons.json.JSONArray;

+import org.apache.sling.commons.json.JSONException;

+import org.apache.sling.commons.json.JSONObject;

+

+/**

+ * Tests for the 'modifyAce' Sling Post Operation

+ */

+public class ModifyAceTest extends AbstractAccessManagerTest {

+

+	String testUserId = null;

+	String testGroupId = null;

+	String testFolderUrl = null;

+	

+	@Override

+	protected void tearDown() throws Exception {

+		super.tearDown();

+

+		Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+

+		if (testFolderUrl != null) {

+			//remove the test user if it exists.

+			String postUrl = testFolderUrl;

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			postParams.add(new NameValuePair(":operation", "delete"));

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		if (testGroupId != null) {

+			//remove the test user if it exists.

+			String postUrl = HTTP_BASE_URL + "/system/userManager/group/" + testGroupId + ".delete.html";

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		if (testUserId != null) {

+			//remove the test user if it exists.

+			String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".delete.html";

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+	}

+

+	public void testModifyAceForUser() throws IOException, JSONException {

+		testUserId = createTestUser();

+		

+		testFolderUrl = createTestFolder();

+		

+        String postUrl = testFolderUrl + ".modifyAce.html";

+

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair("principalId", testUserId));

+		postParams.add(new NameValuePair("privilege@jcr:read", "granted"));

+		postParams.add(new NameValuePair("privilege@jcr:write", "denied"));

+		

+		Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		

+		

+		//fetch the JSON for the acl to verify the settings.

+		String getUrl = testFolderUrl + ".acl.json";

+

+		String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);

+		assertNotNull(json);

+		JSONObject jsonObj = new JSONObject(json);

+		String aceString = jsonObj.getString(testUserId);

+		assertNotNull(aceString);

+		

+		JSONObject aceObject = new JSONObject(aceString); 

+		assertNotNull(aceObject);

+		

+		JSONArray grantedArray = aceObject.getJSONArray("granted");

+		assertNotNull(grantedArray);

+		assertEquals("jcr:read", grantedArray.getString(0));

+

+		JSONArray deniedArray = aceObject.getJSONArray("denied");

+		assertNotNull(deniedArray);

+		assertEquals("jcr:write", deniedArray.getString(0));

+	}

+

+	public void testModifyAceForGroup() throws IOException, JSONException {

+		testGroupId = createTestGroup();

+

+		testFolderUrl = createTestFolder();

+

+        String postUrl = testFolderUrl + ".modifyAce.html";

+

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair("principalId", testGroupId));

+		postParams.add(new NameValuePair("privilege@jcr:read", "granted"));

+		postParams.add(new NameValuePair("privilege@jcr:write", "denied"));

+		

+		Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		

+		

+		//fetch the JSON for the acl to verify the settings.

+		String getUrl = testFolderUrl + ".acl.json";

+

+		String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);

+		assertNotNull(json);

+		JSONObject jsonObj = new JSONObject(json);

+		String aceString = jsonObj.getString(testGroupId);

+		assertNotNull(aceString);

+

+		JSONObject aceObject = new JSONObject(aceString);

+		assertNotNull(aceObject);

+		

+		JSONArray grantedArray = aceObject.getJSONArray("granted");

+		assertNotNull(grantedArray);

+		assertEquals("jcr:read", grantedArray.getString(0));

+

+		//denied rights are not applied for groups, so make sure it is not there

+		assertTrue(aceObject.isNull("denied"));

+	}

+}

diff --git a/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/RemoveAcesTest.java b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/RemoveAcesTest.java
new file mode 100644
index 0000000..c117d90
--- /dev/null
+++ b/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/RemoveAcesTest.java
@@ -0,0 +1,171 @@
+/*

+ * 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.launchpad.webapp.integrationtest.accessManager;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.commons.httpclient.Credentials;

+import org.apache.commons.httpclient.NameValuePair;

+import org.apache.commons.httpclient.UsernamePasswordCredentials;

+import org.apache.sling.commons.json.JSONArray;

+import org.apache.sling.commons.json.JSONException;

+import org.apache.sling.commons.json.JSONObject;

+

+/**

+ * Tests for the 'removeAce' Sling POST operation

+ */

+public class RemoveAcesTest extends AbstractAccessManagerTest {

+	String testUserId = null;

+	String testGroupId = null;

+	String testFolderUrl = null;

+	

+	@Override

+	protected void tearDown() throws Exception {

+		super.tearDown();

+

+		Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+

+		if (testFolderUrl != null) {

+			//remove the test user if it exists.

+			String postUrl = testFolderUrl;

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			postParams.add(new NameValuePair(":operation", "delete"));

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		if (testGroupId != null) {

+			//remove the test user if it exists.

+			String postUrl = HTTP_BASE_URL + "/system/userManager/group/" + testGroupId + ".delete.html";

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		if (testUserId != null) {

+			//remove the test user if it exists.

+			String postUrl = HTTP_BASE_URL + "/system/userManager/user/" + testUserId + ".delete.html";

+			List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		//todo delete test folder

+	}

+	

+	private String createFolderWithAces(boolean addGroupAce) throws IOException, JSONException {

+		testUserId = createTestUser();

+		testFolderUrl = createTestFolder();

+

+        String postUrl = testFolderUrl + ".modifyAce.html";

+

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair("principalId", testUserId));

+		postParams.add(new NameValuePair("privilege@jcr:read", "granted"));

+		postParams.add(new NameValuePair("privilege@jcr:write", "denied"));

+		

+		Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+

+		if (addGroupAce) {

+			testGroupId = createTestGroup();

+			

+			postParams = new ArrayList<NameValuePair>();

+			postParams.add(new NameValuePair("principalId", testGroupId));

+			postParams.add(new NameValuePair("privilege@jcr:read", "granted"));

+			

+			assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+		}

+		

+		//fetch the JSON for the acl to verify the settings.

+		String getUrl = testFolderUrl + ".acl.json";

+

+		String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);

+		assertNotNull(json);

+		

+		JSONObject jsonObj = new JSONObject(json);

+		String aceString = jsonObj.getString(testUserId);

+		assertNotNull(aceString);

+

+		JSONObject aceObject = new JSONObject(aceString);

+		assertNotNull(aceObject);

+		

+		JSONArray grantedArray = aceObject.getJSONArray("granted");

+		assertNotNull(grantedArray);

+		assertEquals("jcr:read", grantedArray.getString(0));

+

+		JSONArray deniedArray = aceObject.getJSONArray("denied");

+		assertNotNull(deniedArray);

+		assertEquals("jcr:write", deniedArray.getString(0));

+

+		if (addGroupAce) {

+			aceString = jsonObj.getString(testGroupId);

+			assertNotNull(aceString);

+

+			aceObject = new JSONObject(aceString);

+			assertNotNull(aceObject);

+

+			grantedArray = aceObject.getJSONArray("granted");

+			assertNotNull(grantedArray);

+			assertEquals("jcr:read", grantedArray.getString(0));

+		}

+		

+		return testFolderUrl;

+	}

+	

+	//test removing a single ace

+	public void testRemoveAce() throws IOException, JSONException {

+		String folderUrl = createFolderWithAces(false);

+		

+		//remove the ace for the testUser principal

+		String postUrl = folderUrl + ".deleteAce.html"; 

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair(":applyTo", testUserId));

+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+

+		//fetch the JSON for the acl to verify the settings.

+		String getUrl = folderUrl + ".acl.json";

+

+		String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);

+		assertNotNull(json);

+

+		JSONObject jsonObj = new JSONObject(json);

+		assertTrue(jsonObj.isNull(testUserId));

+	}

+

+	//test removing multiple aces

+	public void testRemoveAces() throws IOException, JSONException {

+		String folderUrl = createFolderWithAces(true);

+		

+		//remove the ace for the testUser principal

+		String postUrl = folderUrl + ".deleteAce.html"; 

+		List<NameValuePair> postParams = new ArrayList<NameValuePair>();

+		postParams.add(new NameValuePair(":applyTo", testUserId));

+		postParams.add(new NameValuePair(":applyTo", testGroupId));

+        Credentials creds = new UsernamePasswordCredentials("admin", "admin");

+		assertAuthenticatedPostStatus(creds, postUrl, HttpServletResponse.SC_OK, postParams, null);

+

+		//fetch the JSON for the acl to verify the settings.

+		String getUrl = folderUrl + ".acl.json";

+

+		String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);

+		assertNotNull(json);

+

+		JSONObject jsonObj = new JSONObject(json);

+		assertTrue(jsonObj.isNull(testUserId));

+		assertTrue(jsonObj.isNull(testGroupId));

+	}

+}