This is an automated email from the ASF dual-hosted git repository. angela pushed a commit to branch SLING-8942 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
commit c536602fc476318972f7a01b636343d6741d3207 Author: angela <[email protected]> AuthorDate: Tue Jan 12 13:45:49 2021 +0100 SLING-8942 : Support aggregate and abstract privileges --- .../cpconverter/accesscontrol/AclManager.java | 4 +- .../accesscontrol/DefaultAclManager.java | 55 ++++++++++++++++++---- .../cpconverter/handlers/PrivilegesHandler.java | 45 ++---------------- .../handlers/PrivilegesHandlerTest.java | 13 ++++- .../handlers/META-INF/vault/privileges.xml | 5 +- 5 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java index 014b8b5..1bc0664 100644 --- a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java +++ b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java @@ -18,8 +18,10 @@ package org.apache.sling.feature.cpconverter.accesscontrol; import java.util.List; +import org.apache.jackrabbit.vault.fs.spi.PrivilegeDefinitions; import org.apache.sling.feature.cpconverter.features.FeaturesManager; import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler; +import org.jetbrains.annotations.NotNull; /** * The Manager able to collect and build System Users and related ACL policies. @@ -34,7 +36,7 @@ public interface AclManager { void addNodetypeRegistrationSentence(String nodetypeRegistrationSentence); - void addPrivilege(String privilege); + void addPrivilegeDefinitions(@NotNull PrivilegeDefinitions privilegeDefinitions); void reset(); diff --git a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java index f348c02..2975e90 100644 --- a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java +++ b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java @@ -16,11 +16,18 @@ */ package org.apache.sling.feature.cpconverter.accesscontrol; +import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.PrivilegeDefinition; +import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver; +import org.apache.jackrabbit.spi.commons.conversion.NameResolver; +import org.apache.jackrabbit.vault.fs.spi.PrivilegeDefinitions; import org.apache.jackrabbit.vault.util.PlatformNameFormat; import org.apache.sling.feature.cpconverter.features.FeaturesManager; import org.apache.sling.feature.cpconverter.shared.RepoPath; import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler; +import org.jetbrains.annotations.NotNull; +import javax.jcr.NamespaceException; import java.io.File; import java.io.FileInputStream; import java.util.Formatter; @@ -55,7 +62,7 @@ public final class DefaultAclManager implements AclManager { private List<String> nodetypeRegistrationSentences = new LinkedList<>(); - private Set<String> privileges = new LinkedHashSet<>(); + private PrivilegeDefinitions privilegeDefinitions; public boolean addSystemUser(SystemUser systemUser) { if (preProvidedSystemUsers.add(systemUser)) { @@ -88,10 +95,8 @@ public final class DefaultAclManager implements AclManager { try { formatter = new Formatter(); - if (!privileges.isEmpty()) { - for (String privilege : privileges) { - formatter.format("register privilege %s%n", privilege); - } + if (privilegeDefinitions != null) { + registerPrivileges(privilegeDefinitions, formatter); } for (String nodetypeRegistrationSentence : nodetypeRegistrationSentences) { @@ -187,15 +192,15 @@ public final class DefaultAclManager implements AclManager { } @Override - public void addPrivilege(String privilege) { - privileges.add(privilege); + public void addPrivilegeDefinitions(@NotNull PrivilegeDefinitions privilegeDefinitions) { + this.privilegeDefinitions = privilegeDefinitions; } public void reset() { systemUsers.clear(); acls.clear(); nodetypeRegistrationSentences.clear(); - privileges.clear(); + privilegeDefinitions = null; } private void addPaths(List<AccessControlEntry> authorizations, List<VaultPackageAssembler> packageAssemblers, Formatter formatter) { @@ -266,4 +271,38 @@ public final class DefaultAclManager implements AclManager { private static boolean areEmpty(List<AccessControlEntry> authorizations) { return authorizations == null || authorizations.isEmpty(); } + + private static void registerPrivileges(@NotNull PrivilegeDefinitions definitions, @NotNull Formatter formatter) { + NameResolver nameResolver = new DefaultNamePathResolver(definitions.getNamespaceMapping()); + for (PrivilegeDefinition privilege : definitions.getDefinitions()) { + try { + String name = nameResolver.getJCRName(privilege.getName()); + String aggregates = getAggregatedNames(privilege, nameResolver); + if (privilege.isAbstract()) { + formatter.format("register abstract privilege %s%s%n", name, aggregates); + } else { + formatter.format("register privilege %s%s%n", name, aggregates); + } + } catch (NamespaceException e) { + throw new IllegalStateException(e); + } + } + } + + @NotNull + private static String getAggregatedNames(@NotNull PrivilegeDefinition definition, @NotNull NameResolver nameResolver) { + Set<Name> aggregatedNames = definition.getDeclaredAggregateNames(); + if (aggregatedNames.isEmpty()) { + return ""; + } else { + Set<String> names = aggregatedNames.stream().map(name -> { + try { + return nameResolver.getJCRName(name); + } catch (NamespaceException e) { + throw new IllegalStateException(e); + } + }).collect(Collectors.toSet()); + return " with "+String.join(",", names); + } + } } diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandler.java index 00c7c40..da85262 100644 --- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandler.java +++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandler.java @@ -16,57 +16,20 @@ */ package org.apache.sling.feature.cpconverter.handlers; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - import org.apache.jackrabbit.vault.fs.io.Archive; import org.apache.jackrabbit.vault.fs.io.Archive.Entry; +import org.apache.jackrabbit.vault.fs.spi.PrivilegeDefinitions; import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter; -import org.apache.sling.feature.cpconverter.accesscontrol.AclManager; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; public class PrivilegesHandler extends AbstractRegexEntryHandler { - private static final String PRIVILEGE = "privilege"; - - private static final String NAME = "name"; - - private final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); - public PrivilegesHandler() { super("META-INF/vault/privileges\\.xml"); } @Override - public void handle(String path, Archive archive, Entry entry, ContentPackage2FeatureModelConverter converter) - throws Exception { - SAXParser saxParser = saxParserFactory.newSAXParser(); - AclManager aclManager = converter.getAclManager(); - PrivilegeHandler handler = new PrivilegeHandler(aclManager); - saxParser.parse(archive.openInputStream(entry), handler); + public void handle(String path, Archive archive, Entry entry, ContentPackage2FeatureModelConverter converter) { + PrivilegeDefinitions privileges = archive.getMetaInf().getPrivileges(); + converter.getAclManager().addPrivilegeDefinitions(privileges); } - - private static final class PrivilegeHandler extends DefaultHandler { - - private final AclManager aclManager; - - public PrivilegeHandler(AclManager aclManager) { - this.aclManager = aclManager; - } - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) - throws SAXException { - if (PRIVILEGE.equals(qName)) { - String privilege = attributes.getValue(NAME); - if (privilege != null && !privilege.isEmpty()) { - aclManager.addPrivilege(privilege); - } - } - } - - } - } diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java index 3b4309f..bfe3fa3 100644 --- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java +++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/PrivilegesHandlerTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.when; import java.util.Arrays; +import org.apache.jackrabbit.vault.fs.config.DefaultMetaInf; import org.apache.jackrabbit.vault.fs.io.Archive; import org.apache.jackrabbit.vault.fs.io.Archive.Entry; import org.apache.sling.feature.ArtifactId; @@ -69,7 +70,11 @@ public class PrivilegesHandlerTest { Archive archive = mock(Archive.class); Entry entry = mock(Entry.class); + DefaultMetaInf metaInf = new DefaultMetaInf(); + metaInf.load(getClass().getResourceAsStream(path.substring(1)), "privileges.xml"); + when(archive.openInputStream(entry)).thenReturn(getClass().getResourceAsStream(path.substring(1))); + when(archive.getMetaInf()).thenReturn(metaInf); VaultPackageAssembler packageAssembler = mock(VaultPackageAssembler.class); @@ -86,7 +91,13 @@ public class PrivilegesHandlerTest { Extension repoinitExtension = feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT); assertNotNull(repoinitExtension); - assertTrue(repoinitExtension.getText().contains("register privilege rx:replicate" + System.lineSeparator())); + String str = "register privilege sling:replicate" + System.lineSeparator() + + "register abstract privilege sling:test with "; + String txt = repoinitExtension.getText(); + assertTrue("Expect '"+txt+"' contains '"+str+"'", txt.contains(str)); + String aggregation1 = "with sling:replicate,jcr:read" + System.lineSeparator(); + String aggregation2 = "with jcr:read,sling:replicate" + System.lineSeparator(); + assertTrue(txt.contains(aggregation1) || txt.contains(aggregation2)); } } diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/META-INF/vault/privileges.xml b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/META-INF/vault/privileges.xml index 7beb9d2..625a79b 100644 --- a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/META-INF/vault/privileges.xml +++ b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/META-INF/vault/privileges.xml @@ -15,6 +15,7 @@ License for the specific language governing permissions and limitations under the License. --> -<privileges xmlns:crx="http://sling.apache.org/rx/1.0"> - <privilege name="rx:replicate"/> +<privileges xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"> + <privilege name="sling:replicate"/> + <privilege name="sling:test" abstract="true"><contains name="sling:replicate"/><contains name="jcr:read"/></privilege> </privileges>
