SLING-11321 add declaredAt structure for effective acl/ace (#12)
effective acl/ace json output should contain the paths where the privileges were declared
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/JsonConvert.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/JsonConvert.java
index 6918aa9..cc4e029 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/JsonConvert.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/impl/JsonConvert.java
@@ -21,6 +21,7 @@
import java.security.Principal;
import java.util.Collection;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import javax.jcr.PropertyType;
@@ -33,6 +34,7 @@
import org.apache.sling.jcr.jackrabbit.accessmanager.LocalPrivilege;
import org.apache.sling.jcr.jackrabbit.accessmanager.LocalRestriction;
+import org.apache.sling.jcr.jackrabbit.accessmanager.post.DeclarationType;
/**
* Utilities to help convert ACL/ACE data to JSON
@@ -43,6 +45,7 @@
public static final String KEY_PRIVILEGES = "privileges";
public static final String KEY_ALLOW = "allow";
public static final String KEY_DENY = "deny";
+ public static final String KEY_DECLARED_AT = "declaredAt";
private JsonConvert() {
// no-op
@@ -77,6 +80,30 @@
return principalObj;
}
+ /**
+ * Add details about where the privileges were declared, usually
+ * for viewing the effective access list or entry
+ */
+ public static void addDeclaredAt(JsonObjectBuilder principalObj, Map<DeclarationType, Set<String>> declaredAt) {
+ JsonObjectBuilder declaredAtBuilder = Json.createObjectBuilder();
+ for (Entry<DeclarationType, Set<String>> daentry : declaredAt.entrySet()) {
+ DeclarationType type = daentry.getKey();
+ if (type != null) {
+ Set<String> value = daentry.getValue();
+ if (value.size() == 1) {
+ declaredAtBuilder.add(type.getJsonKey(), value.iterator().next());
+ } else {
+ JsonArrayBuilder typeBuilder = Json.createArrayBuilder();
+ for (String at : value) {
+ typeBuilder.add(at);
+ }
+ declaredAtBuilder.add(type.getJsonKey(), typeBuilder);
+ }
+ }
+ }
+ principalObj.add(JsonConvert.KEY_DECLARED_AT, declaredAtBuilder);
+ }
+
public static void addRestrictions(JsonObjectBuilder privilegeObj, String key, Set<LocalRestriction> restrictions) {
if (restrictions.isEmpty()) {
privilegeObj.add(key, true);
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessGetServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessGetServlet.java
index 752baff..6adc061 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessGetServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractAccessGetServlet.java
@@ -224,7 +224,8 @@
* @return map of sorted entries, key is the effectivePath and value is the list of entries for that path
*/
protected @NotNull Map<String, List<AccessControlEntry>> entriesSortedByEffectivePath(@NotNull AccessControlPolicy[] policies,
- @NotNull Predicate<? super AccessControlEntry> accessControlEntryFilter) throws RepositoryException {
+ @NotNull Predicate<? super AccessControlEntry> accessControlEntryFilter,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
Comparator<? super String> effectivePathComparator = (k1, k2) -> Objects.compare(k1, k2, Comparator.nullsFirst(String::compareTo));
Map<String, List<AccessControlEntry>> effectivePathToEntriesMap = new TreeMap<>(effectivePathComparator);
@@ -235,6 +236,7 @@
Stream.of(accessControlEntries)
.filter(accessControlEntryFilter)
.forEach(entry -> {
+ DeclarationType dt = null;
String effectivePath = null;
if (entry instanceof PrincipalAccessControlList.Entry) {
// for principal-based ACE, the effectivePath comes from the entry
@@ -243,12 +245,18 @@
// special case
effectivePath = PrincipalAceHelper.RESOURCE_PATH_REPOSITORY;
}
+ dt = DeclarationType.PRINCIPAL;
} else if (accessControlPolicy instanceof JackrabbitAccessControlList) {
// for basic ACE, the effectivePath comes from the ACL path
effectivePath = ((JackrabbitAccessControlList)accessControlPolicy).getPath();
+ dt = DeclarationType.NODE;
}
List<AccessControlEntry> entriesForPath = effectivePathToEntriesMap.computeIfAbsent(effectivePath, key -> new ArrayList<>());
entriesForPath.add(entry);
+
+ Map<DeclarationType, Set<String>> map = declaredAtPaths.computeIfAbsent(entry.getPrincipal(), k -> new HashMap<>());
+ Set<String> set = map.computeIfAbsent(dt, k -> new HashSet<>());
+ set.add(effectivePath);
});
}
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAceServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAceServlet.java
index 4d56cad..a200611 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAceServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAceServlet.java
@@ -50,7 +50,8 @@
protected JsonObject internalGetAce(Session jcrSession, String resourcePath, String principalId) throws RepositoryException {
Principal principal = validateArgs(jcrSession, resourcePath, principalId);
- Map<String, List<AccessControlEntry>> effectivePathToEntriesMap = getAccessControlEntriesMap(jcrSession, resourcePath, principal);
+ Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths = new HashMap<>();
+ Map<String, List<AccessControlEntry>> effectivePathToEntriesMap = getAccessControlEntriesMap(jcrSession, resourcePath, principal, principalToDeclaredAtPaths);
if (effectivePathToEntriesMap == null || effectivePathToEntriesMap.isEmpty()) {
throw new ResourceNotFoundException(resourcePath, "No access control entries were found");
}
@@ -81,18 +82,32 @@
PrivilegesHelper.consolidateAggregates(jcrSession, resourcePath, privilegeToLocalPrivilegesMap, privilegeLongestDepthMap);
// convert the data to JSON
- JsonObjectBuilder jsonObj = JsonConvert.convertToJson(principal, privilegeToLocalPrivilegesMap, -1);
- return jsonObj.build();
+ JsonObjectBuilder principalObj = JsonConvert.convertToJson(principal, privilegeToLocalPrivilegesMap, -1);
+ addExtraInfo(principalObj, principal, principalToDeclaredAtPaths);
+ return principalObj.build();
}
- protected abstract Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath, Principal principal) throws RepositoryException;
+ /**
+ * Override to add additional data to the principal object
+ *
+ * @param principalObj the current principal object
+ * @param principal the current principal
+ * @param principalToDeclaredAtPaths a map of principal the paths where ACEs are declared
+ */
+ protected void addExtraInfo(JsonObjectBuilder principalJson,
+ Principal principal, Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths) {
+ // no-op
+ }
+
+ protected abstract Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath, Principal principal,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException;
/**
* @deprecated use {@link #getAccessControlEntriesMap(Session, String, Principal, Map)} instead
*/
@Deprecated
protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath, Principal principal) throws RepositoryException {
- return getAccessControlEntriesMap(session, absPath, principal).values().stream()
+ return getAccessControlEntriesMap(session, absPath, principal, new HashMap<>()).values().stream()
.toArray(size -> new AccessControlEntry[size]);
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
index a51902f..910c364 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/AbstractGetAclServlet.java
@@ -79,7 +79,8 @@
srMap.put(restrictionDefinition.getName(), restrictionDefinition);
}
- Map<String, List<AccessControlEntry>> effectivePathToEntriesMap = getAccessControlEntriesMap(jcrSession, resourcePath);
+ Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths = new HashMap<>();
+ Map<String, List<AccessControlEntry>> effectivePathToEntriesMap = getAccessControlEntriesMap(jcrSession, resourcePath, principalToDeclaredAtPaths);
Map<Principal, Integer> principalToOrderMap = new HashMap<>();
Map<Principal, Map<Privilege, LocalPrivilege>> principalToPrivilegesMap = new HashMap<>();
for (Entry<String, List<AccessControlEntry>> entry : effectivePathToEntriesMap.entrySet()) {
@@ -115,22 +116,37 @@
Collections.sort(entrySetList, (e1, e2) -> principalToOrderMap.get(e1.getKey()).compareTo(principalToOrderMap.get(e2.getKey())));
// convert the data to JSON
- JsonObjectBuilder jsonObj = convertToJson(entrySetList);
+ JsonObjectBuilder jsonObj = convertToJson(entrySetList, principalToDeclaredAtPaths);
return jsonObj.build();
}
- protected JsonObjectBuilder convertToJson(List<Entry<Principal, Map<Privilege, LocalPrivilege>>> entrySetList) {
+ protected JsonObjectBuilder convertToJson(List<Entry<Principal, Map<Privilege, LocalPrivilege>>> entrySetList,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) {
JsonObjectBuilder jsonObj = Json.createObjectBuilder();
for (int i = 0; i < entrySetList.size(); i++) {
Entry<Principal, Map<Privilege, LocalPrivilege>> entry = entrySetList.get(i);
Principal principal = entry.getKey();
JsonObjectBuilder principalObj = JsonConvert.convertToJson(entry.getKey(), entry.getValue(), i);
+ addExtraInfo(principalObj, principal, declaredAtPaths);
jsonObj.add(principal.getName(), principalObj);
}
return jsonObj;
}
/**
+ * Override to add additional data to the principal object
+ *
+ * @param principalObj the current principal object
+ * @param principal the current principal
+ * @param principalToDeclaredAtPaths a map of principal the paths where ACEs are declared
+ */
+ protected void addExtraInfo(JsonObjectBuilder principalJson,
+ Principal principal, Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths) {
+ // no-op
+ }
+
+
+ /**
* @deprecated use {@link JsonConvert#addRestrictions(JsonObjectBuilder, String, Set)} instead
*/
@Deprecated
@@ -154,14 +170,15 @@
return JsonConvert.addTo(builder, value);
}
- protected abstract Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath) throws RepositoryException;
+ protected abstract Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException;
/**
* @deprecated use {@link #getAccessControlEntriesMap(Session, String, Map)} instead
*/
@Deprecated
protected AccessControlEntry[] getAccessControlEntries(Session session, String absPath) throws RepositoryException {
- return getAccessControlEntriesMap(session, absPath).values().stream()
+ return getAccessControlEntriesMap(session, absPath, new HashMap<>()).values().stream()
.toArray(size -> new AccessControlEntry[size]);
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeclarationType.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeclarationType.java
new file mode 100644
index 0000000..eb863a2
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/DeclarationType.java
@@ -0,0 +1,32 @@
+/*
+ * 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.post;
+
+/**
+ * Enumerates the types of ACE declarations, typically
+ * used for constructing the output of the declaredAt structure of
+ * the effective ace/acl json
+ */
+public enum DeclarationType {
+ PRINCIPAL,
+ NODE;
+
+ public String getJsonKey() {
+ return name().toLowerCase();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAceServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAceServlet.java
index 19edf38..17cc42c 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAceServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAceServlet.java
@@ -21,6 +21,7 @@
import java.security.Principal;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -93,10 +94,10 @@
@Override
protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
- Principal principal) throws RepositoryException {
+ Principal principal, Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
AccessControlManager acMgr = session.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(absPath);
- return entriesSortedByEffectivePath(policies, ace -> principal.equals(ace.getPrincipal()));
+ return entriesSortedByEffectivePath(policies, ace -> principal.equals(ace.getPrincipal()), declaredAtPaths);
}
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
index 0017e1c..d325c42 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetAclServlet.java
@@ -16,8 +16,10 @@
*/
package org.apache.sling.jcr.jackrabbit.accessmanager.post;
+import java.security.Principal;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -121,10 +123,11 @@
}
@Override
- protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath) throws RepositoryException {
+ protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
AccessControlManager accessControlManager = session.getAccessControlManager();
AccessControlPolicy[] policies = accessControlManager.getPolicies(absPath);
- return entriesSortedByEffectivePath(policies, ace -> true);
+ return entriesSortedByEffectivePath(policies, ace -> true, declaredAtPaths);
}
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAceServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAceServlet.java
index d001350..738bd8a 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAceServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAceServlet.java
@@ -21,6 +21,7 @@
import java.security.Principal;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -28,11 +29,13 @@
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
import javax.servlet.Servlet;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.jcr.jackrabbit.accessmanager.GetEffectiveAce;
+import org.apache.sling.jcr.jackrabbit.accessmanager.impl.JsonConvert;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -92,12 +95,22 @@
return internalGetAce(jcrSession, resourcePath, principalId);
}
+ /**
+ * Overridden to add the declaredAt data to the json
+ */
+ @Override
+ protected void addExtraInfo(JsonObjectBuilder principalJson, Principal principal,
+ Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths) {
+ Map<DeclarationType, Set<String>> map = principalToDeclaredAtPaths.get(principal);
+ JsonConvert.addDeclaredAt(principalJson, map);
+ }
+
@Override
protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
- Principal principal) throws RepositoryException {
+ Principal principal, Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
AccessControlManager acMgr = AccessControlUtil.getAccessControlManager(session);
AccessControlPolicy[] policies = acMgr.getEffectivePolicies(absPath);
- return entriesSortedByEffectivePath(policies, ace -> principal.equals(ace.getPrincipal()));
+ return entriesSortedByEffectivePath(policies, ace -> principal.equals(ace.getPrincipal()), declaredAtPaths);
}
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
index f917e75..224de8b 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetEffectiveAclServlet.java
@@ -16,8 +16,10 @@
*/
package org.apache.sling.jcr.jackrabbit.accessmanager.post;
+import java.security.Principal;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -25,10 +27,12 @@
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
import javax.servlet.Servlet;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionProvider;
import org.apache.sling.jcr.jackrabbit.accessmanager.GetEffectiveAcl;
+import org.apache.sling.jcr.jackrabbit.accessmanager.impl.JsonConvert;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -120,11 +124,22 @@
return internalGetAcl(jcrSession, resourcePath);
}
+ /**
+ * Overridden to add the declaredAt data to the json
+ */
@Override
- protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath) throws RepositoryException {
+ protected void addExtraInfo(JsonObjectBuilder principalJson, Principal principal,
+ Map<Principal, Map<DeclarationType, Set<String>>> principalToDeclaredAtPaths) {
+ Map<DeclarationType, Set<String>> map = principalToDeclaredAtPaths.get(principal);
+ JsonConvert.addDeclaredAt(principalJson, map);
+ }
+
+ @Override
+ protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
+ Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
AccessControlManager accessControlManager = session.getAccessControlManager();
AccessControlPolicy[] policies = accessControlManager.getEffectivePolicies(absPath);
- return entriesSortedByEffectivePath(policies, ace -> true);
+ return entriesSortedByEffectivePath(policies, ace -> true, declaredAtPaths);
}
}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetPrincipalAceServlet.java b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetPrincipalAceServlet.java
index 6dba636..4d40d88 100644
--- a/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetPrincipalAceServlet.java
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/accessmanager/post/GetPrincipalAceServlet.java
@@ -22,6 +22,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -111,12 +112,12 @@
@Override
protected Map<String, List<AccessControlEntry>> getAccessControlEntriesMap(Session session, String absPath,
- Principal principal) throws RepositoryException {
+ Principal principal, Map<Principal, Map<DeclarationType, Set<String>>> declaredAtPaths) throws RepositoryException {
AccessControlManager acMgr = session.getAccessControlManager();
if (acMgr instanceof JackrabbitAccessControlManager) {
JackrabbitAccessControlManager jacMgr = (JackrabbitAccessControlManager)acMgr;
JackrabbitAccessControlPolicy[] policies = jacMgr.getPolicies(principal);
- return entriesSortedByEffectivePath(policies, ace -> matchesPrincipalAccessControlEntry(ace, absPath, principal));
+ return entriesSortedByEffectivePath(policies, ace -> matchesPrincipalAccessControlEntry(ace, absPath, principal), declaredAtPaths);
} else {
return Collections.emptyMap();
}
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/AccessManagerTestSupport.java b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/AccessManagerTestSupport.java
index 34c86c2..7837055 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/AccessManagerTestSupport.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/AccessManagerTestSupport.java
@@ -83,21 +83,24 @@
}
// switch to the minimum oak version that supports principalbased access control
- versionResolver.setVersion("org.apache.jackrabbit", "oak-api", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-blob", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-blob-plugins", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-commons", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-core", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-core-spi", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-jcr", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-lucene", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-query-spi", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-security-spi", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-segment-tar", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-store-composite", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-store-document", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-store-spi", "1.16.0");
- versionResolver.setVersion("org.apache.jackrabbit", "oak-jackrabbit-api", "1.16.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-api", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-blob", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-blob-plugins", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-commons", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-core", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-core-spi", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-jcr", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-lucene", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-query-spi", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-security-spi", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-segment-tar", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-store-composite", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-store-document", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-store-spi", "1.18.0");
+ versionResolver.setVersion("org.apache.jackrabbit", "oak-jackrabbit-api", "1.18.0");
+ versionResolver.setVersion("commons-codec", "commons-codec", "1.14");
+ versionResolver.setVersion("org.apache.tika", "tika-core", "1.24");
+ versionResolver.setVersion("org.apache.tika", "tika-parsers", "1.24");
// newer version of sling.api and dependencies for SLING-10034
// may remove at a later date if the superclass includes these versions or later
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetEaceIT.java b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetEaceIT.java
index 9812d13..14bb7b7 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetEaceIT.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetEaceIT.java
@@ -21,8 +21,10 @@
import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.net.URI;
import java.util.List;
+import javax.json.JsonArray;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonString;
@@ -75,6 +77,11 @@
assertEquals(1, privilegesObject.size());
//allow privilege
assertPrivilege(privilegesObject, true, PrivilegeValues.ALLOW, PrivilegeConstants.JCR_WRITE);
+
+ JsonObject declaredAtObj = aceObject.getJsonObject("declaredAt");
+ assertNotNull(declaredAtObj);
+ String testFolderPath = URI.create(testFolderUrl).getPath();
+ assertEquals(testFolderPath, declaredAtObj.getString("node"));
}
/**
@@ -205,5 +212,58 @@
});
}
+ /**
+ * Verify that when the effective ace is a merge of ACEs in multiple
+ * ancestor nodes, that an array of those node paths is returned in the
+ * declaredAt structure
+ */
+ @Test
+ public void testDeclaredAtArrayInEffectiveAceForUser() throws IOException {
+ testUserId = createTestUser();
+ testFolderUrl = createTestFolder(null, "sling-tests1",
+ "{ \"jcr:primaryType\": \"nt:unstructured\", \"child\" : { \"childPropOne\" : true } }");
+
+ //1. create an initial set of privileges
+ List<NameValuePair> postParams = new AcePostParamsBuilder(testUserId)
+ .withPrivilege(PrivilegeConstants.JCR_WRITE, PrivilegeValues.ALLOW)
+ .build();
+ addOrUpdateAce(testFolderUrl, postParams);
+
+ List<NameValuePair> postParams2 = new AcePostParamsBuilder(testUserId)
+ .withPrivilege(PrivilegeConstants.JCR_READ, PrivilegeValues.ALLOW)
+ .build();
+ addOrUpdateAce(testFolderUrl + "/child", postParams2);
+
+ Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+ //fetch the JSON for the ace to verify the settings.
+ String getUrl = testFolderUrl + "/child.eace.json?pid=" + testUserId;
+
+ String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+ assertNotNull(json);
+ JsonObject aceObject = parseJson(json);
+
+ String principalString = aceObject.getString("principal");
+ assertEquals(testUserId, principalString);
+
+ JsonObject privilegesObject = aceObject.getJsonObject("privileges");
+ assertNotNull(privilegesObject);
+ assertEquals(2, privilegesObject.size());
+ //allow privilege
+ assertPrivilege(privilegesObject, true, PrivilegeValues.ALLOW, PrivilegeConstants.JCR_WRITE);
+ assertPrivilege(privilegesObject, true, PrivilegeValues.ALLOW, PrivilegeConstants.JCR_READ);
+
+ JsonObject declaredAtObj = aceObject.getJsonObject("declaredAt");
+ assertNotNull(declaredAtObj);
+ JsonValue nodeObj = declaredAtObj.get("node");
+ assertTrue (nodeObj instanceof JsonArray);
+ JsonArray nodeArray = (JsonArray)nodeObj;
+ assertEquals(2, nodeArray.size());
+ String testFolderPath = URI.create(testFolderUrl).getPath();
+ assertTrue (nodeArray.get(0) instanceof JsonString);
+ assertEquals(testFolderPath + "/child", ((JsonString)nodeArray.get(0)).getString());
+ assertTrue (nodeArray.get(1) instanceof JsonString);
+ assertEquals(testFolderPath, ((JsonString)nodeArray.get(1)).getString());
+ }
}
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetPaceIT.java b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetPaceIT.java
index 5b80ed0..80e7cc9 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetPaceIT.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/GetPaceIT.java
@@ -21,8 +21,10 @@
import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.net.URI;
import java.util.List;
+import javax.json.JsonArray;
import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonString;
@@ -187,5 +189,58 @@
});
}
+ /**
+ * Verify that when the effective ace is a merge of ACEs in multiple
+ * ancestor nodes, that an array of those node paths is returned in the
+ * declaredAt structure
+ */
+ @Test
+ public void testDeclaredAtArrayInEffectiveAceForServiceUser() throws IOException {
+ testFolderUrl = createTestFolder(null, "sling-tests5",
+ "{ \"jcr:primaryType\": \"nt:unstructured\", \"child\" : { \"childPropOne\" : true } }");
+ String testServiceUserId = "pacetestuser";
+
+ //1. create an initial set of privileges
+ List<NameValuePair> postParams = new AcePostParamsBuilder(testServiceUserId)
+ .withPrivilege(PrivilegeConstants.JCR_WRITE, PrivilegeValues.ALLOW)
+ .build();
+ addOrUpdatePrincipalAce(testFolderUrl, postParams);
+
+ List<NameValuePair> postParams2 = new AcePostParamsBuilder(testServiceUserId)
+ .withPrivilege(PrivilegeConstants.JCR_READ, PrivilegeValues.ALLOW)
+ .build();
+ addOrUpdatePrincipalAce(testFolderUrl + "/child", postParams2);
+
+ Credentials creds = new UsernamePasswordCredentials("admin", "admin");
+
+ //fetch the JSON for the ace to verify the settings.
+ String getUrl = testFolderUrl + "/child.eace.json?pid=" + testServiceUserId;
+
+ String json = getAuthenticatedContent(creds, getUrl, CONTENT_TYPE_JSON, HttpServletResponse.SC_OK);
+ assertNotNull(json);
+ JsonObject aceObject = parseJson(json);
+
+ String principalString = aceObject.getString("principal");
+ assertEquals(testServiceUserId, principalString);
+
+ JsonObject privilegesObject = aceObject.getJsonObject("privileges");
+ assertNotNull(privilegesObject);
+ assertEquals(2, privilegesObject.size());
+ //allow privilege
+ assertPrivilege(privilegesObject, true, PrivilegeValues.ALLOW, PrivilegeConstants.JCR_WRITE);
+ assertPrivilege(privilegesObject, true, PrivilegeValues.ALLOW, PrivilegeConstants.JCR_READ);
+
+ JsonObject declaredAtObj = aceObject.getJsonObject("declaredAt");
+ assertNotNull(declaredAtObj);
+ JsonValue nodeObj = declaredAtObj.get("principal");
+ assertTrue (nodeObj instanceof JsonArray);
+ JsonArray nodeArray = (JsonArray)nodeObj;
+ assertEquals(2, nodeArray.size());
+ String testFolderPath = URI.create(testFolderUrl).getPath();
+ assertTrue (nodeArray.get(0) instanceof JsonString);
+ assertEquals(testFolderPath + "/child", ((JsonString)nodeArray.get(0)).getString());
+ assertTrue (nodeArray.get(1) instanceof JsonString);
+ assertEquals(testFolderPath, ((JsonString)nodeArray.get(1)).getString());
+ }
}
diff --git a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/PrincipalAceTestSupport.java b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/PrincipalAceTestSupport.java
index 1412893..4bede5c 100644
--- a/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/PrincipalAceTestSupport.java
+++ b/src/test/java/org/apache/sling/jcr/jackrabbit/accessmanager/it/PrincipalAceTestSupport.java
@@ -44,7 +44,7 @@
@Override
protected Option[] additionalOptions() throws IOException {
return composite(super.additionalOptions())
- .add(mavenBundle().groupId("org.apache.jackrabbit").artifactId("oak-authorization-principalbased").version("1.16.0"),
+ .add(mavenBundle().groupId("org.apache.jackrabbit").artifactId("oak-authorization-principalbased").version("1.18.0"),
newConfiguration("org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.PrincipalBasedAuthorizationConfiguration")
.put("enableAggregationFilter", true)
.asOption(),