This is an automated email from the ASF dual-hosted git repository. joerghoh pushed a commit to branch SLING-12642-cache-privileges in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git
commit a4e4b8b7be3afaace8a8eea1792f434e231a3176 Author: Joerg Hoh <[email protected]> AuthorDate: Sun Feb 9 14:11:04 2025 +0100 cache once-retrieved privileges --- .../apache/sling/jcr/repoinit/impl/AclUtil.java | 10 ++++---- .../impl/PrivilegeCachingSessionWrapper.java | 29 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/AclUtil.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/AclUtil.java index 8a3cbef..a459c45 100644 --- a/src/main/java/org/apache/sling/jcr/repoinit/impl/AclUtil.java +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/AclUtil.java @@ -168,7 +168,7 @@ public class AclUtil { AccessControlManager acMgr = pcsw.getAccessControlManager(); final String[] privArray = privileges.toArray(new String[privileges.size()]); - final Privilege[] jcrPriv = AccessControlUtils.privilegesFromNames(acMgr, privArray); + final Privilege[] jcrPriv = pcsw.privilegesFromNames(privArray); JackrabbitAccessControlList acl = getAccessControlList(acMgr, jcrPath, true); checkState(acl != null, "No JackrabbitAccessControlList available for path {0}", jcrPath); @@ -332,7 +332,7 @@ public class AclUtil { LocalRestrictions restr = createLocalRestrictions(restrictionClauses, acl, pcsw.getSession()); Privilege[] privs = - AccessControlUtils.privilegesFromNames(acMgr, privileges.toArray(new String[0])); + pcsw.privilegesFromNames(privileges.toArray(new String[0])); for (AccessControlEntry ace : acl.getAccessControlEntries()) { Principal principal = ace.getPrincipal(); @@ -404,8 +404,8 @@ public class AclUtil { modified = true; } } else if (action == AclLine.Action.ALLOW) { - final Privilege[] privileges = AccessControlUtils.privilegesFromNames( - acMgr, line.getProperty(PROP_PRIVILEGES).toArray(new String[0])); + final Privilege[] privileges = pcsw.privilegesFromNames( + line.getProperty(PROP_PRIVILEGES).toArray(new String[0])); for (String effectivePath : jcrPaths) { if (acl == null) { // no PrincipalAccessControlList available: don't fail if an equivalent path-based entry with @@ -465,7 +465,7 @@ public class AclUtil { List<String> jcrPaths = getJcrPaths(pcsw.getSession(), line.getProperty(PROP_PATHS)); LocalRestrictions restr = createLocalRestrictions(line.getRestrictions(), acl, pcsw.getSession()); List<String> privNames = line.getProperty(PROP_PRIVILEGES); - Privilege[] privs = AccessControlUtils.privilegesFromNames(acMgr, privNames.toArray(new String[0])); + Privilege[] privs = pcsw.privilegesFromNames(privNames.toArray(new String[0])); Predicate<PrincipalAccessControlList.Entry> predicate = entry -> { if (!jcrPaths.contains(entry.getEffectivePath())) { return false; diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/PrivilegeCachingSessionWrapper.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/PrivilegeCachingSessionWrapper.java index a9610cb..9c642a6 100644 --- a/src/main/java/org/apache/sling/jcr/repoinit/impl/PrivilegeCachingSessionWrapper.java +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/PrivilegeCachingSessionWrapper.java @@ -18,8 +18,15 @@ */ package org.apache.sling.jcr.repoinit.impl; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.security.AccessControlManager; +import javax.jcr.security.Privilege; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; @@ -31,6 +38,7 @@ public class PrivilegeCachingSessionWrapper { JackrabbitSession session; JackrabbitAccessControlManager acMgr; + Map<String,Privilege> nameToPrivilegeMap = new HashMap<>(); public PrivilegeCachingSessionWrapper (Session session) { AclUtil.checkState(session instanceof JackrabbitSession,"A Jackrabbit Session is required"); @@ -38,6 +46,7 @@ public class PrivilegeCachingSessionWrapper { try { AclUtil.checkState(session.getAccessControlManager() instanceof JackrabbitAccessControlManager, "A Jachrabbit AccessControlManager is required"); + this.acMgr = (JackrabbitAccessControlManager) session.getAccessControlManager(); } catch (RepositoryException e) { throw new IllegalStateException("Cannot retrieve the AcccessControlManager"); } @@ -51,4 +60,24 @@ public class PrivilegeCachingSessionWrapper { return acMgr; } + /** + * Retrieve the matching privileges from the given privilege names; uses internally a cache. The retrieval + * logic is identical to AccessControlUtils.privilegesFromName, but with caching + * @param privilegeNames the name of the privileges + * @return the matching privileges + * @throws RepositoryException in case of errors + */ + public Privilege[] privilegesFromNames(String... privilegeNames) throws RepositoryException { + Set<Privilege> privileges = new HashSet<Privilege>(privilegeNames.length); + for (String privName : privilegeNames) { + if (nameToPrivilegeMap.containsKey(privName)) { + privileges.add(nameToPrivilegeMap.get(privName)); + } else { + Privilege p = acMgr.privilegeFromName(privName); + nameToPrivilegeMap.put(privName, p); + privileges.add(p); + } + } + return privileges.toArray(new Privilege[privileges.size()]); + } }
