You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/01/12 12:46:11 UTC

[sling-org-apache-sling-feature-cpconverter] 01/01: SLING-8942 : Support aggregate and abstract privileges

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 <an...@adobe.com>
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>