diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 6acfd61c..9a0e3dc0 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - jdk: [11, 17, 21] + jdk: [11, 17, 21, 25-ea] include: # lengthy build steps should only be performed on linux with Java 17 (Sonarcloud analysis, deployment) - os: ubuntu-latest @@ -25,10 +25,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v5 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: ${{ matrix.jdk }} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index d58dfb70..12fbe1e9 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,4 +16,4 @@ # under the License. wrapperVersion=3.3.2 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/accesscontroltool-bundle/pom.xml b/accesscontroltool-bundle/pom.xml index 08a6b533..cfa68b5b 100644 --- a/accesscontroltool-bundle/pom.xml +++ b/accesscontroltool-bundle/pom.xml @@ -25,7 +25,7 @@ 10.1.44 - 1.48.0 + 1.74.0 @@ -168,18 +168,7 @@ org.apache.sling.hc.api provided - - - org.apache.jackrabbit - oak-security-spi - provided - - - * - * - - - + org.apache.jackrabbit oak-auth-external diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java index 0a89f40b..c88aebbb 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/aceinstaller/AceBeanInstallerClassic.java @@ -35,7 +35,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; -import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +44,7 @@ import biz.netcentric.cq.tools.actool.helper.AccessControlUtils; import biz.netcentric.cq.tools.actool.helper.RestrictionsHolder; import biz.netcentric.cq.tools.actool.history.InstallationLogger; +import biz.netcentric.cq.tools.actool.impl.SimpleNamePrincipal; /** The way ACEs were installed in version one is still available and can be configured in "global_config" section by setting * "installAclsIncrementally=false". */ @@ -71,7 +71,7 @@ protected void installAcl(Set aceBeanSetFromConfig, String path, Set aceBeanSetFromConfig, String path, Set getPrincipalAceBeansForActionAceBean(AceBean origAceBean, Session s Principal getTestActionMapperPrincipal() { String groupPrincipalId = "actool-tester-action-mapper"; // does not have to exist since the ACEs for it are not saved - Principal principal = new PrincipalImpl(groupPrincipalId); + Principal principal = new SimpleNamePrincipal(groupPrincipalId); return principal; } diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java index f2fa5cc4..50dabf34 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthInstallerUserManagerPrefetchingImpl.java @@ -35,7 +35,6 @@ import org.apache.jackrabbit.api.security.user.QueryBuilder; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; -import org.apache.jackrabbit.oak.spi.security.user.UserConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,6 +67,18 @@ class AuthInstallerUserManagerPrefetchingImpl implements AuthInstallerUserManage private static final Logger LOG = LoggerFactory.getLogger(AuthInstallerUserManagerPrefetchingImpl.class); + /** + * Node type used for system users in Oak/JR2. + * Defined for Oak in {@code org.apache.jackrabbit.oak.spi.security.user.UserConstants.NT_REP_SYSTEM_USER}. + */ + private static final String NT_REP_SYSTEM_USER = "rep:SystemUser"; + + /** + * Node type used for groups in Oak/JR2. + * Defined for Oak in {@code org.apache.jackrabbit.oak.spi.security.user.UserConstants.NT_REP_GROUP}. + */ + private static final String NT_REP_GROUP = "rep:Group"; + private final UserManager delegate; private final Map> nonRegularUserMembersByAuthorizableId = new CaseInsensitiveMap<>(); @@ -83,8 +94,8 @@ public AuthInstallerUserManagerPrefetchingImpl(UserManager delegate, final Value public void build(QueryBuilder builder) { builder.setCondition( builder.or( - builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(UserConstants.NT_REP_SYSTEM_USER)), - builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(UserConstants.NT_REP_GROUP)) + builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(NT_REP_SYSTEM_USER)), + builder.eq("@" + JcrConstants.JCR_PRIMARYTYPE, valueFactory.createValue(NT_REP_GROUP)) ) ); } @@ -100,7 +111,7 @@ public void build(QueryBuilder builder) { authorizableIdsAndPaths.put(auth.getID(), auth.getPath()); } - Authorizable anonymous = delegate.getAuthorizable(UserConstants.DEFAULT_ANONYMOUS_ID); + Authorizable anonymous = delegate.getAuthorizable(Constants.USER_ANONYMOUS); if (anonymous != null) { membershipCount += prefetchAuthorizable(anonymous); authorizableIdsAndPaths.put(anonymous.getID(), anonymous.getPath()); diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java index b9700d9d..8a891ad7 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/AuthorizableInstallerServiceImpl.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.security.GeneralSecurityException; +import java.security.Principal; import java.security.cert.Certificate; import java.util.Arrays; import java.util.Collection; @@ -45,7 +46,6 @@ import org.apache.jackrabbit.api.security.user.AuthorizableExistsException; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.User; -import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl; import org.apache.sling.api.SlingIOException; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.PersistenceException; @@ -79,6 +79,7 @@ import biz.netcentric.cq.tools.actool.helper.Constants; import biz.netcentric.cq.tools.actool.helper.ContentHelper; import biz.netcentric.cq.tools.actool.history.InstallationLogger; +import biz.netcentric.cq.tools.actool.impl.SimpleNamePrincipal; @org.osgi.service.component.annotations.Component() public class AuthorizableInstallerServiceImpl implements @@ -705,7 +706,7 @@ private Authorizable createNewGroup( LOG.info("Successfully created new external group: {}", groupID); } else { - PrincipalImpl principalForNewGroup = new PrincipalImpl(groupID); + Principal principalForNewGroup = new SimpleNamePrincipal(groupID); if (StringUtils.isNotBlank(intermediatePath)) { newGroup = userManager.createGroup(principalForNewGroup, intermediatePath); } else { @@ -841,7 +842,7 @@ private Authorizable createNewUser( } newUser = userManager.createSystemUser(authorizableId, intermediatePath); } else { - newUser = userManager.createUser(authorizableId, password, new PrincipalImpl(authorizableId), intermediatePath); + newUser = userManager.createUser(authorizableId, password, new SimpleNamePrincipal(authorizableId), intermediatePath); } setAuthorizableProperties(newUser, principalConfigBean, authorizablesConfig, session, installLog); diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java index a63a955b..3ea13f13 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/authorizableinstaller/impl/ImpersonationInstallerServiceImpl.java @@ -25,7 +25,6 @@ import org.apache.jackrabbit.api.security.principal.PrincipalIterator; import org.apache.jackrabbit.api.security.user.Impersonation; import org.apache.jackrabbit.api.security.user.User; -import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,6 +32,7 @@ import biz.netcentric.cq.tools.actool.configmodel.AuthorizableConfigBean; import biz.netcentric.cq.tools.actool.configmodel.AuthorizablesConfig; import biz.netcentric.cq.tools.actool.history.InstallationLogger; +import biz.netcentric.cq.tools.actool.impl.SimpleNamePrincipal; /** Installs impersonators to users. */ @Component(service = ImpersonationInstallerServiceImpl.class) @@ -61,7 +61,7 @@ private void applyChanges(User user, InstallationLogger installationLog, List impersonatorsToAddIt = impersonatorsToAdd.iterator(); while (impersonatorsToAddIt.hasNext()) { String impersonatorToAdd = impersonatorsToAddIt.next(); - boolean success = impersonation.grantImpersonation(new PrincipalImpl(impersonatorToAdd)); + boolean success = impersonation.grantImpersonation(new SimpleNamePrincipal(impersonatorToAdd)); if (!success) { impersonatorsToAddIt.remove(); installationLog.addWarning(LOG, "Impersonator '" + impersonatorToAdd + "' can not be added to user " + user); @@ -74,7 +74,7 @@ private void applyChanges(User user, InstallationLogger installationLog, List impersonatorsToRemoveIt = impersonatorsToRemove.iterator(); while (impersonatorsToRemoveIt.hasNext()) { String impersonatorToRemove = impersonatorsToRemoveIt.next(); - boolean success = impersonation.revokeImpersonation(new PrincipalImpl(impersonatorToRemove)); + boolean success = impersonation.revokeImpersonation(new SimpleNamePrincipal(impersonatorToRemove)); if (!success) { impersonatorsToRemoveIt.remove(); installationLog.addWarning(LOG, "Impersonator '" + impersonatorToRemove + "' can not be removed from user " + user); diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/impl/DumpServiceImpl.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/impl/DumpServiceImpl.java index 0e4ae346..fb8895e1 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/impl/DumpServiceImpl.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/dumpservice/impl/DumpServiceImpl.java @@ -54,8 +54,6 @@ import org.apache.jackrabbit.api.security.user.QueryBuilder.Direction; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; -import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal; -import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl; import org.apache.jackrabbit.util.Text; import org.apache.sling.jcr.api.SlingRepository; import org.osgi.service.component.annotations.Activate; @@ -87,6 +85,7 @@ import biz.netcentric.cq.tools.actool.helper.Constants; import biz.netcentric.cq.tools.actool.helper.QueryHelper; import biz.netcentric.cq.tools.actool.history.impl.HistoryUtils; +import biz.netcentric.cq.tools.actool.impl.SimpleNamePrincipal; @Component @Designate(ocd=Configuration.class) @@ -308,7 +307,7 @@ private Set getUsersFromAces(int mapOrder, Session session, userIds = aclDumpMap.keySet(); for (String id : userIds) { - Authorizable authorizable = um.getAuthorizable(new PrincipalImpl(id)); + Authorizable authorizable = um.getAuthorizable(new SimpleNamePrincipal(id)); if (!authorizable.isGroup()) { User user = (User) authorizable; usersFromACEs.add(user); @@ -322,7 +321,7 @@ private Set getUsersFromAces(int mapOrder, Session session, for (AceBean aceBean : aceBeanSet) { String principalId = aceBean.getPrincipalName(); - Authorizable authorizable = um.getAuthorizable(new PrincipalImpl(principalId)); + Authorizable authorizable = um.getAuthorizable(new SimpleNamePrincipal(principalId)); if (!authorizable.isGroup()) { User user = (User) authorizable; usersFromACEs.add(user); @@ -438,7 +437,7 @@ public AceDumpData createAclDumpMap(final int keyOrder, final int aclOrdering, } } - Authorizable authorizable = um.getAuthorizable(new PrincipalImpl(tmpAceBean.getPrincipalName())); + Authorizable authorizable = um.getAuthorizable(new SimpleNamePrincipal(tmpAceBean.getPrincipalName())); // if this group exists under home if (authorizable != null) { @@ -593,7 +592,7 @@ private void addDeclaredMembers(Authorizable authorizable, while (it.hasNext()) { String groupId = it.next().getID(); - if (StringUtils.equals(groupId, EveryonePrincipal.NAME)) { + if (StringUtils.equals(groupId, Constants.PRINCIPAL_EVERYONE)) { continue; } memberOfList.add(groupId); diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/Constants.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/Constants.java index 6237c15c..2b51168a 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/Constants.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/helper/Constants.java @@ -38,7 +38,14 @@ private Constants() { ACE_CONFIGURATION_KEY, OBSOLETE_AUTHORIZABLES_KEY)); + /** + * Default user ID for the anonymous user in Oak/JR2. + * Defined for Oak in {@code org.apache.jackrabbit.oak.spi.security.user.UserConstants.DEFAULT_ANONYMOUS_ID}. + */ public static final String USER_ANONYMOUS = "anonymous"; + /** + * Principal name for the everyone principal in Oak/JR2. + */ public static final String PRINCIPAL_EVERYONE = "everyone"; public static final String GROUPS_ROOT = "/home/groups"; diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/impl/SimpleNamePrincipal.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/impl/SimpleNamePrincipal.java new file mode 100644 index 00000000..c2bd1475 --- /dev/null +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/impl/SimpleNamePrincipal.java @@ -0,0 +1,54 @@ +package biz.netcentric.cq.tools.actool.impl; + +/*- + * #%L + * Access Control Tool Bundle + * %% + * Copyright (C) 2025 Cognizant Netcentric + * %% + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * #L% + */ + +import java.util.Objects; + +import org.apache.jackrabbit.api.security.principal.JackrabbitPrincipal; + +/** + * Simple implementation of JackrabbitPrincipal based on a name only. + */ +public class SimpleNamePrincipal implements JackrabbitPrincipal { + + private final String name; + + public SimpleNamePrincipal(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SimpleNamePrincipal other = (SimpleNamePrincipal) obj; + return Objects.equals(name, other.name); + } + +} diff --git a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/ui/AcToolUiService.java b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/ui/AcToolUiService.java index 1a5f11a4..e6b5084c 100644 --- a/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/ui/AcToolUiService.java +++ b/accesscontroltool-bundle/src/main/java/biz/netcentric/cq/tools/actool/ui/AcToolUiService.java @@ -52,7 +52,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.User; -import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal; import org.apache.sling.api.SlingHttpServletRequest; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -67,6 +66,7 @@ import biz.netcentric.cq.tools.actool.api.AcInstallationService; import biz.netcentric.cq.tools.actool.api.InstallationOptionsBuilder; import biz.netcentric.cq.tools.actool.dumpservice.ConfigDumpService; +import biz.netcentric.cq.tools.actool.helper.Constants; import biz.netcentric.cq.tools.actool.helper.UncheckedRepositoryException; import biz.netcentric.cq.tools.actool.history.AcHistoryService; import biz.netcentric.cq.tools.actool.history.AcToolExecution; @@ -512,7 +512,7 @@ private static String getDeclaredMemberOfAsStrings(User user) throws RepositoryE try { user.declaredMemberOf().forEachRemaining(g -> { try { - if (!EveryonePrincipal.NAME.equals(g.getID())) { + if (!Constants.PRINCIPAL_EVERYONE.equals(g.getID())) { groupNames.add(g.getID()); } } catch (RepositoryException e) {