Author: enorman
Date: Wed Feb 24 04:44:43 2010
New Revision: 915670
URL: http://svn.apache.org/viewvc?rev=915670&view=rev
Log:
SLING-997 handle merges involving aggregate privileges properly
Modified:
sling/trunk/bundles/jcr/jackrabbit-accessmanager/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
Modified:
sling/trunk/bundles/jcr/jackrabbit-accessmanager/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-accessmanager/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java?rev=915670&r1=915669&r2=915670&view=diff
==============================================================================
---
sling/trunk/bundles/jcr/jackrabbit-accessmanager/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
(original)
+++
sling/trunk/bundles/jcr/jackrabbit-accessmanager/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/ModifyAceServlet.java
Wed Feb 24 04:44:43 2010
@@ -100,7 +100,6 @@
/* (non-Javadoc)
* @see
org.apache.sling.jackrabbit.accessmanager.post.AbstractAccessPostServlet#handleOperation(org.apache.sling.api.SlingHttpServletRequest,
org.apache.sling.api.servlets.HtmlResponse, java.util.List)
*/
- @SuppressWarnings("unchecked")
@Override
protected void handleOperation(SlingHttpServletRequest request,
HtmlResponse htmlResponse, List<Modification> changes)
@@ -133,12 +132,70 @@
}
}
+ try {
+ AccessControlManager accessControlManager =
AccessControlUtil.getAccessControlManager(session);
- List<String> grantedPrivilegeNames = new ArrayList<String>();
- List<String> deniedPrivilegeNames = new ArrayList<String>();
- //SLING-997: keep track of the privilege names that were
posted, so the others can be preserved
- Set<String> postedPrivilegeNames = new HashSet<String>();
- Enumeration parameterNames = request.getParameterNames();
+ //SLING-997: keep track of the privilege names that
were posted, so the others can be preserved
+ PrivilegesState privilegesInfo = new
PrivilegesState(log.isDebugEnabled());
+
+ //calculate which privileges were POSTed.
+ collectPostedPrivilegeNames(request,
+ accessControlManager,
+ privilegesInfo);
+
+ //find the existing ACL
+ AccessControlList updatedAcl =
getAccessControlList(accessControlManager, resourcePath, true);
+
+ //keep track of the existing ACEs for the target
principal
+ List<AccessControlEntry> oldAces =
processExistingAccessControlEntries(resourcePath,
+ authorizable,
+ accessControlManager,
+ updatedAcl,
+ privilegesInfo);
+
+ //remove the old ACEs. Re-created below.
+ if (!oldAces.isEmpty()) {
+ for (AccessControlEntry ace : oldAces) {
+
updatedAcl.removeAccessControlEntry(ace);
+ }
+ }
+
+ //re-aggregate the granted/denied privileges into the
best matched aggregate privilege
+ reaggregatePrivileges(resourcePath,
+ accessControlManager,
+ privilegesInfo);
+
+ //add fresh ACEs with the granted privileges
+ buildFreshAccessControlEntries(authorizable,
+ accessControlManager,
+ updatedAcl,
+ privilegesInfo);
+
+ //store the updated ACL
+ accessControlManager.setPolicy(resourcePath,
updatedAcl);
+ if (session.hasPendingChanges()) {
+ session.save();
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Updated ACE for principalId {0} for
resource {1) from {2} to {3}", new Object [] {
+ authorizable.getID(),
resourcePath, privilegesInfo.oldPrivileges.toString(),
privilegesInfo.newPrivileges.toString()
+ });
+ }
+ } catch (RepositoryException re) {
+ throw new RepositoryException("Failed to create ace.",
re);
+ }
+ }
+
+
+ /**
+ * Collect the privileges to assign from the http request.
+ */
+ private void collectPostedPrivilegeNames(SlingHttpServletRequest
request,
+ AccessControlManager accessControlManager,
+ PrivilegesState privilegesInfo) throws
RepositoryException {
+
+ Enumeration<?> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
Object nextElement = parameterNames.nextElement();
if (nextElement instanceof String) {
@@ -146,144 +203,236 @@
if (paramName.startsWith("privilege@")) {
String privilegeName =
paramName.substring(10);
//keep track of which privileges should
be changed
-
postedPrivilegeNames.add(privilegeName);
+
privilegesInfo.postedPrivilegeNames.add(privilegeName);
String parameterValue =
request.getParameter(paramName);
if (parameterValue != null &&
parameterValue.length() > 0) {
if
("granted".equals(parameterValue)) {
-
grantedPrivilegeNames.add(privilegeName);
+ Privilege privilege =
accessControlManager.privilegeFromName(privilegeName);
+ if
(privilege.isAggregate()) {
+ Privilege[]
aggregatePrivileges = privilege.getAggregatePrivileges();
+ for (Privilege
privilege2 : aggregatePrivileges) {
+
privilegesInfo.grantedPrivilegeNames.add(privilege2.getName());
+ }
+ } else {
+
privilegesInfo.grantedPrivilegeNames.add(privilegeName);
+ }
} else if
("denied".equals(parameterValue)) {
-
deniedPrivilegeNames.add(privilegeName);
+ Privilege privilege =
accessControlManager.privilegeFromName(privilegeName);
+ if
(privilege.isAggregate()) {
+ Privilege[]
aggregatePrivileges = privilege.getAggregatePrivileges();
+ for (Privilege
privilege2 : aggregatePrivileges) {
+
privilegesInfo.deniedPrivilegeNames.add(privilege2.getName());
+ }
+ } else {
+
privilegesInfo.deniedPrivilegeNames.add(privilegeName);
+ }
}
}
}
}
}
+ }
+
+ /**
+ * Process the existing ACL to determine which privileges to preserve.
+ */
+ private List<AccessControlEntry> processExistingAccessControlEntries(
+ String resourcePath,
+ Authorizable authorizable,
+ AccessControlManager accessControlManager,
+ AccessControlList updatedAcl,
+ PrivilegesState privilegesInfo) throws
RepositoryException {
+
+ String principalId = authorizable.getPrincipal().getName();
+ AccessControlEntry[] accessControlEntries =
updatedAcl.getAccessControlEntries();
+ List<AccessControlEntry> oldAces = new
ArrayList<AccessControlEntry>();
+ for (AccessControlEntry ace : accessControlEntries) {
+ if (principalId.equals(ace.getPrincipal().getName())) {
+ if (log.isDebugEnabled()) {
+ log.debug("Found Existing ACE for
principal {0} on resource: ", new Object[] {principalId, resourcePath});
+ }
+ oldAces.add(ace);
- try {
- AccessControlManager accessControlManager =
AccessControlUtil.getAccessControlManager(session);
- AccessControlList updatedAcl =
getAccessControlList(accessControlManager, resourcePath, true);
-
- StringBuilder oldPrivileges = null;
- StringBuilder newPrivileges = null;
- if (log.isDebugEnabled()) {
- oldPrivileges = new StringBuilder();
- newPrivileges = new StringBuilder();
- }
+ boolean isAllow =
AccessControlUtil.isAllow(ace);
+ Privilege[] privileges = ace.getPrivileges();
- List<Privilege> preserveGrantedPrivileges = new
ArrayList<Privilege>();
- List<Privilege> preserveDeniedPrivileges = new
ArrayList<Privilege>();
-
- //keep track of the existing Aces for the target
principal
- AccessControlEntry[] accessControlEntries =
updatedAcl.getAccessControlEntries();
- List<AccessControlEntry> oldAces = new
ArrayList<AccessControlEntry>();
- for (AccessControlEntry ace : accessControlEntries) {
- if
(principalId.equals(ace.getPrincipal().getName())) {
- if (log.isDebugEnabled()) {
- log.debug("Found Existing ACE
for principal {0} on resource: ", new Object[] {principalId, resourcePath});
+ //build a list of (merged and expanded)
privileges
+ Set<Privilege> mergedExistingPrivileges = new
HashSet<Privilege>();
+ for (Privilege privilege : privileges) {
+ if (privilege.isAggregate()) {
+ Privilege[] aggregatePrivileges
= privilege.getAggregatePrivileges();
+ for (Privilege privilege2 :
aggregatePrivileges) {
+
mergedExistingPrivileges.add(privilege2);
+ }
+ } else {
+
mergedExistingPrivileges.add(privilege);
}
- oldAces.add(ace);
-
- boolean isAllow =
AccessControlUtil.isAllow(ace);
- Privilege[] privileges =
ace.getPrivileges();
- for (Privilege privilege : privileges) {
- String privilegeName =
privilege.getName();
- if
(!postedPrivilegeNames.contains(privilegeName)) {
- //this privilege was
not posted, so record the existing state to be
- // preserved when the
ACE is re-created below
- if (isAllow) {
-
preserveGrantedPrivileges.add(privilege);
- } else {
-
preserveDeniedPrivileges.add(privilege);
- }
+ }
+
+ //now process the merged privileges set
+ for (Privilege privilege :
mergedExistingPrivileges) {
+ String privilegeName =
privilege.getName();
+ if
(!privilegesInfo.postedPrivilegeNames.contains(privilegeName)) {
+ //this privilege was not
posted, so record the existing state to be
+ // preserved when the ACE is
re-created below
+ if (isAllow) {
+
privilegesInfo.grantedPrivilegeNames.add(privilegeName);
+ } else {
+
privilegesInfo.deniedPrivilegeNames.add(privilegeName);
}
+ }
- if (log.isDebugEnabled()) {
- //collect the
information for debug logging
- if
(oldPrivileges.length() > 0) {
-
oldPrivileges.append(", "); //separate entries by commas
- }
+ if (log.isDebugEnabled()) {
+ //collect the information for
debug logging
+ if
(privilegesInfo.oldPrivileges.length() > 0) {
+
privilegesInfo.oldPrivileges.append(", "); //separate entries by commas
+ }
+ if (isAllow) {
+
privilegesInfo.oldPrivileges.append("granted=");
+ } else {
+
privilegesInfo.oldPrivileges.append("denied=");
}
+
privilegesInfo.oldPrivileges.append(privilege.getName());
}
}
}
+ }
+
+ return oldAces;
+ }
+
+ /**
+ * Given the set of granted/denied privileges, try to combine them
+ * into the best aggregate Privilege that contains them all.
+ */
+ private void reaggregatePrivileges(
+ String resourcePath,
+ AccessControlManager accessControlManager,
+ PrivilegesState privilegesInfo) throws
RepositoryException {
+ Privilege[] supportedPrivileges =
accessControlManager.getSupportedPrivileges(resourcePath);
+ for (Privilege privilege : supportedPrivileges) {
+ if (privilege.isAggregate()) {
+ boolean grantedAggregatePrivilege = true;
+ boolean deniedAggregatePrivilege = true;
+ Privilege[] aggregatePrivileges =
privilege.getAggregatePrivileges();
+ for (Privilege privilege2 :
aggregatePrivileges) {
+ String name = privilege2.getName();
+ if
(!privilegesInfo.grantedPrivilegeNames.contains(name)) {
+ grantedAggregatePrivilege =
false;
+ }
+ if
(!privilegesInfo.deniedPrivilegeNames.contains(name)) {
+ deniedAggregatePrivilege =
false;
+ }
+ }
+
+ if (grantedAggregatePrivilege) {
+ //add the aggregate privilege and
remove the containing parts
+
privilegesInfo.grantedPrivilegeNames.add(privilege.getName());
+ for (Privilege privilege2 :
aggregatePrivileges) {
+ String name =
privilege2.getName();
+
privilegesInfo.grantedPrivilegeNames.remove(name);
+ }
+ }
- //remove the old aces
- if (!oldAces.isEmpty()) {
- for (AccessControlEntry ace : oldAces) {
-
updatedAcl.removeAccessControlEntry(ace);
+ if (deniedAggregatePrivilege) {
+ //add the aggregate privilege and
remove the containing parts
+
privilegesInfo.deniedPrivilegeNames.add(privilege.getName());
+ for (Privilege privilege2 :
aggregatePrivileges) {
+ String name =
privilege2.getName();
+
privilegesInfo.deniedPrivilegeNames.remove(name);
+ }
}
}
+ }
+ }
+
+ /**
+ * Create new ACE for the granted and denied privileges.
+ */
+ private void buildFreshAccessControlEntries(
+ Authorizable authorizable,
+ AccessControlManager accessControlManager,
+ AccessControlList updatedAcl,
+ PrivilegesState privilegesInfo) throws
RepositoryException {
+ List<Privilege> grantedPrivilegeList = new
ArrayList<Privilege>();
+ for (String name : privilegesInfo.grantedPrivilegeNames) {
+ if (name.length() == 0) {
+ continue; //empty, skip it.
+ }
+ Privilege privilege =
accessControlManager.privilegeFromName(name);
+ grantedPrivilegeList.add(privilege);
+ }
+
+ if (log.isDebugEnabled()) {
+ for (Privilege privilege : grantedPrivilegeList) {
+ if (privilegesInfo.newPrivileges.length() > 0) {
+ privilegesInfo.newPrivileges.append(",
"); //separate entries by commas
+ }
+ privilegesInfo.newPrivileges.append("granted=");
+
privilegesInfo.newPrivileges.append(privilege.getName());
+ }
+ }
+
+ if (grantedPrivilegeList.size() > 0) {
+ Principal principal = authorizable.getPrincipal();
+ updatedAcl.addAccessControlEntry(principal,
grantedPrivilegeList.toArray(new Privilege[grantedPrivilegeList.size()]));
+ }
- //add a fresh ACE with the granted privileges
- List<Privilege> grantedPrivilegeList = new
ArrayList<Privilege>();
- for (String name : grantedPrivilegeNames) {
+ //if the authorizable is a user (not a group) process any
denied privileges
+ if (!authorizable.isGroup()) {
+ //add a fresh ACE with the denied privileges
+ List<Privilege> deniedPrivilegeList = new
ArrayList<Privilege>();
+ for (String name : privilegesInfo.deniedPrivilegeNames)
{
if (name.length() == 0) {
continue; //empty, skip it.
}
Privilege privilege =
accessControlManager.privilegeFromName(name);
- grantedPrivilegeList.add(privilege);
+ deniedPrivilegeList.add(privilege);
}
- //add the privileges that should be preserved
- grantedPrivilegeList.addAll(preserveGrantedPrivileges);
-
+
if (log.isDebugEnabled()) {
- for (Privilege privilege :
grantedPrivilegeList) {
- if (newPrivileges.length() > 0) {
- newPrivileges.append(", ");
//separate entries by commas
- }
- newPrivileges.append("granted=");
-
newPrivileges.append(privilege.getName());
- }
- }
-
- if (grantedPrivilegeList.size() > 0) {
- Principal principal =
authorizable.getPrincipal();
- updatedAcl.addAccessControlEntry(principal,
grantedPrivilegeList.toArray(new Privilege[grantedPrivilegeList.size()]));
- }
-
- //if the authorizable is a user (not a group) process
any denied privileges
- if (!authorizable.isGroup()) {
- //add a fresh ACE with the denied privileges
- List<Privilege> deniedPrivilegeList = new
ArrayList<Privilege>();
- for (String name : deniedPrivilegeNames) {
- if (name.length() == 0) {
- continue; //empty, skip it.
- }
- Privilege privilege =
accessControlManager.privilegeFromName(name);
- deniedPrivilegeList.add(privilege);
- }
- //add the privileges that should be preserved
-
deniedPrivilegeList.addAll(preserveDeniedPrivileges);
-
- if (log.isDebugEnabled()) {
- for (Privilege privilege :
deniedPrivilegeList) {
- if (newPrivileges.length() > 0)
{
- newPrivileges.append(",
"); //separate entries by commas
- }
- newPrivileges.append("denied=");
-
newPrivileges.append(privilege.getName());
+ for (Privilege privilege : deniedPrivilegeList)
{
+ if
(privilegesInfo.newPrivileges.length() > 0) {
+
privilegesInfo.newPrivileges.append(", "); //separate entries by commas
}
- }
-
- if (deniedPrivilegeList.size() > 0) {
- Principal principal =
authorizable.getPrincipal();
- AccessControlUtil.addEntry(updatedAcl,
principal, deniedPrivilegeList.toArray(new
Privilege[deniedPrivilegeList.size()]), false);
+
privilegesInfo.newPrivileges.append("denied=");
+
privilegesInfo.newPrivileges.append(privilege.getName());
}
}
-
- accessControlManager.setPolicy(resourcePath,
updatedAcl);
- if (session.hasPendingChanges()) {
- session.save();
+
+ if (deniedPrivilegeList.size() > 0) {
+ Principal principal =
authorizable.getPrincipal();
+ AccessControlUtil.addEntry(updatedAcl,
principal, deniedPrivilegeList.toArray(new
Privilege[deniedPrivilegeList.size()]), false);
}
+ }
+ }
+
+ /**
+ * Contains the information about the privilege state as it
+ * progresses through the update process.
+ */
+ private static class PrivilegesState {
+ //stores the names of the privileges that were POSTed
+ Set<String> postedPrivilegeNames = new HashSet<String>();
+
+ //stores the names of the privileges to be granted
+ Set<String> grantedPrivilegeNames = new HashSet<String>();
+
+ //stores the names of the privileges to be denied
+ Set<String> deniedPrivilegeNames = new HashSet<String>();
+
+ //collects debug information about the previous privileges
+ StringBuilder oldPrivileges = null;
+
+ //collects debug information about the new privileges
+ StringBuilder newPrivileges = null;
- if (log.isDebugEnabled()) {
- log.debug("Updated ACE for principalId {0} for
resource {1) from {2} to {3}", new Object [] {
- authorizable.getID(),
resourcePath, oldPrivileges.toString(), newPrivileges.toString()
- });
+ public PrivilegesState(boolean isDebugEnabled) {
+ if (isDebugEnabled) {
+ oldPrivileges = new StringBuilder();
+ newPrivileges = new StringBuilder();
}
- } catch (RepositoryException re) {
- throw new RepositoryException("Failed to create ace.",
re);
}
}
}
Modified:
sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java?rev=915670&r1=915669&r2=915670&view=diff
==============================================================================
---
sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
(original)
+++
sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/accessManager/ModifyAceTest.java
Wed Feb 24 04:44:43 2010
@@ -243,5 +243,197 @@
assertTrue(deniedPrivilegeNames2.contains("jcr:modifyAccessControl"));
assertTrue(deniedPrivilegeNames2.contains("jcr:removeNode"));
}
+
+
+ /**
+ * Test for SLING-997, preserve privileges that were not posted with
the modifyAce
+ * request.
+ */
+ public void testMergeAceForUserSplitAggregatePrincipal() throws
IOException, JSONException {
+ testUserId = createTestUser();
+ testFolderUrl = createTestFolder();
+
+ String postUrl = testFolderUrl + ".modifyAce.html";
+
+ //1. create an initial set of privileges
+ List<NameValuePair> postParams = new ArrayList<NameValuePair>();
+ postParams.add(new NameValuePair("principalId", testUserId));
+ postParams.add(new NameValuePair("privil...@jcr:read",
"granted"));
+ postParams.add(new NameValuePair("privil...@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(1, grantedArray.length());
+ Set<String> grantedPrivilegeNames = new HashSet<String>();
+ for (int i=0; i < grantedArray.length(); i++) {
+ grantedPrivilegeNames.add(grantedArray.getString(i));
+ }
+ assertTrue(grantedPrivilegeNames.contains("jcr:read"));
+
+ JSONArray deniedArray = aceObject.getJSONArray("denied");
+ assertNotNull(deniedArray);
+ assertEquals(1, deniedArray.length());
+ Set<String> deniedPrivilegeNames = new HashSet<String>();
+ for (int i=0; i < deniedArray.length(); i++) {
+ deniedPrivilegeNames.add(deniedArray.getString(i));
+ }
+ assertTrue(deniedPrivilegeNames.contains("jcr:write"));
+
+
+
+ //2. post a new set of privileges to merge with the existing privileges
+ List<NameValuePair> postParams2 = new
ArrayList<NameValuePair>();
+ postParams2.add(new NameValuePair("principalId", testUserId));
+ //jcr:read is not posted, so it should remain in the granted ACE
+ postParams2.add(new
NameValuePair("privil...@jcr:modifyProperties", "granted")); //add a new
privilege
+ //jcr:write is not posted, but one of the aggregate privileges
is now granted, so the aggregate priviledge should be disagreaged into
+ // the remaining denied privileges in the denied ACE
+
+ assertAuthenticatedPostStatus(creds, postUrl,
HttpServletResponse.SC_OK, postParams2, null);
+
+
+ //fetch the JSON for the acl to verify the settings.
+ String json2 = getAuthenticatedContent(creds, getUrl,
CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);
+
+ assertNotNull(json2);
+ JSONObject jsonObj2 = new JSONObject(json2);
+ String aceString2 = jsonObj2.getString(testUserId);
+ assertNotNull(aceString2);
+
+ JSONObject aceObject2 = new JSONObject(aceString2);
+ assertNotNull(aceObject2);
+
+ JSONArray grantedArray2 = aceObject2.getJSONArray("granted");
+ assertNotNull(grantedArray2);
+ assertEquals(2, grantedArray2.length());
+ Set<String> grantedPrivilegeNames2 = new HashSet<String>();
+ for (int i=0; i < grantedArray2.length(); i++) {
+ grantedPrivilegeNames2.add(grantedArray2.getString(i));
+ }
+ assertTrue(grantedPrivilegeNames2.contains("jcr:read"));
+
assertTrue(grantedPrivilegeNames2.contains("jcr:modifyProperties"));
+
+ JSONArray deniedArray2 = aceObject2.getJSONArray("denied");
+ assertNotNull(deniedArray2);
+ assertEquals(3, deniedArray2.length());
+ Set<String> deniedPrivilegeNames2 = new HashSet<String>();
+ for (int i=0; i < deniedArray2.length(); i++) {
+ deniedPrivilegeNames2.add(deniedArray2.getString(i));
+ }
+ assertFalse(deniedPrivilegeNames2.contains("jcr:write"));
+ //only the remaining privileges from the disaggregated
jcr:write collection should remain.
+ assertTrue(deniedPrivilegeNames2.contains("jcr:addChildNodes"));
+ assertTrue(deniedPrivilegeNames2.contains("jcr:removeNode"));
+
assertTrue(deniedPrivilegeNames2.contains("jcr:removeChildNodes"));
+ }
+
+ /**
+ * Test for SLING-997, preserve privileges that were not posted with
the modifyAce
+ * request.
+ */
+ public void testMergeAceForUserCombineAggregatePrincipal() throws
IOException, JSONException {
+ testUserId = createTestUser();
+ testFolderUrl = createTestFolder();
+
+ String postUrl = testFolderUrl + ".modifyAce.html";
+
+ //1. create an initial set of privileges
+ List<NameValuePair> postParams = new ArrayList<NameValuePair>();
+ postParams.add(new NameValuePair("principalId", testUserId));
+ postParams.add(new NameValuePair("privil...@jcr:read",
"granted"));
+ postParams.add(new NameValuePair("privil...@jcr:removeNode",
"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(1, grantedArray.length());
+ Set<String> grantedPrivilegeNames = new HashSet<String>();
+ for (int i=0; i < grantedArray.length(); i++) {
+ grantedPrivilegeNames.add(grantedArray.getString(i));
+ }
+ assertTrue(grantedPrivilegeNames.contains("jcr:read"));
+
+ JSONArray deniedArray = aceObject.getJSONArray("denied");
+ assertNotNull(deniedArray);
+ assertEquals(1, deniedArray.length());
+ Set<String> deniedPrivilegeNames = new HashSet<String>();
+ for (int i=0; i < deniedArray.length(); i++) {
+ deniedPrivilegeNames.add(deniedArray.getString(i));
+ }
+ assertTrue(deniedPrivilegeNames.contains("jcr:removeNode"));
+
+
+
+ //2. post a new set of privileges to merge with the existing privileges
+ List<NameValuePair> postParams2 = new
ArrayList<NameValuePair>();
+ postParams2.add(new NameValuePair("principalId", testUserId));
+ //jcr:read is not posted, so it should remain in the granted ACE
+
+ //post the remaining privileges that when combined, correspond
to the jcr:write aggregate privilege
+ postParams2.add(new
NameValuePair("privil...@jcr:addChildNodes", "denied")); //add a new privilege
+ postParams2.add(new
NameValuePair("privil...@jcr:removeChildNodes", "denied")); //add a new
privilege
+ postParams2.add(new
NameValuePair("privil...@jcr:modifyProperties", "denied")); //add a new
privilege
+
+ assertAuthenticatedPostStatus(creds, postUrl,
HttpServletResponse.SC_OK, postParams2, null);
+
+
+ //fetch the JSON for the acl to verify the settings.
+ String json2 = getAuthenticatedContent(creds, getUrl,
CONTENT_TYPE_JSON, null, HttpServletResponse.SC_OK);
+
+ assertNotNull(json2);
+ JSONObject jsonObj2 = new JSONObject(json2);
+ String aceString2 = jsonObj2.getString(testUserId);
+ assertNotNull(aceString2);
+
+ JSONObject aceObject2 = new JSONObject(aceString2);
+ assertNotNull(aceObject2);
+
+ JSONArray grantedArray2 = aceObject2.getJSONArray("granted");
+ assertNotNull(grantedArray2);
+ assertEquals(1, grantedArray2.length());
+ Set<String> grantedPrivilegeNames2 = new HashSet<String>();
+ for (int i=0; i < grantedArray2.length(); i++) {
+ grantedPrivilegeNames2.add(grantedArray2.getString(i));
+ }
+ assertTrue(grantedPrivilegeNames2.contains("jcr:read"));
+
+ JSONArray deniedArray2 = aceObject2.getJSONArray("denied");
+ assertNotNull(deniedArray2);
+ assertEquals(1, deniedArray2.length());
+ Set<String> deniedPrivilegeNames2 = new HashSet<String>();
+ for (int i=0; i < deniedArray2.length(); i++) {
+ deniedPrivilegeNames2.add(deniedArray2.getString(i));
+ }
+ assertTrue(deniedPrivilegeNames2.contains("jcr:write"));
+ }
}