You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2022/06/24 15:30:02 UTC

[jackrabbit-filevault] branch feature/remove-sling-dependency created (now 791695a4)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch feature/remove-sling-dependency
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git


      at 791695a4 JCRVLT-640 get rid of Sling Commons Classloader and JSON dependencies

This branch includes the following new commits:

     new 791695a4 JCRVLT-640 get rid of Sling Commons Classloader and JSON dependencies

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[jackrabbit-filevault] 01/01: JCRVLT-640 get rid of Sling Commons Classloader and JSON dependencies

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/remove-sling-dependency
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 791695a49e5d83de2430d0259e53630566906de7
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Fri Jun 24 17:29:55 2022 +0200

    JCRVLT-640 get rid of Sling Commons Classloader and JSON dependencies
    
    Ignore false-positive warning for
    https://www.cve.org/CVERecord?id=CVE-2022-32549
---
 suppressions.xml                                   |  14 +--
 target-osgi-environment/pom.xml                    |  12 ---
 vault-rcp/bnd.bnd                                  |   2 +-
 vault-rcp/pom.xml                                  |  30 +++----
 .../jackrabbit/vault/rcp/impl/RcpServlet.java      |  71 ++++++---------
 .../jackrabbit/vault/rcp/impl/TypedMapWrapper.java | 100 +++++++++++++++++++++
 6 files changed, 149 insertions(+), 80 deletions(-)

diff --git a/suppressions.xml b/suppressions.xml
index ac2b5813..53e81488 100644
--- a/suppressions.xml
+++ b/suppressions.xml
@@ -17,7 +17,7 @@
 <suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">
     <suppress>
        <notes><![CDATA[
-       Oak GAV must not apply to JR2 CPE (like for 
+       Oak GAV must not apply to JR2 CPE
        ]]></notes>
        <packageUrl regex="true">^pkg:maven/org\.apache\.jackrabbit/oak\-.*@.*$</packageUrl>
        <cpe>cpe:/a:apache:jackrabbit</cpe>
@@ -38,16 +38,16 @@
     </suppress>
     <suppress>
        <notes><![CDATA[
-       file name: org.apache.sling.commons.classloader-1.2.2.jar
+       false positive for Oak classes e.g. for CVE-2021-40690
        ]]></notes>
-       <packageUrl regex="true">^pkg:maven/org\.apache\.sling/org\.apache\.sling\.commons\.classloader@.*$</packageUrl>
-       <cpe>cpe:/a:apache-ssl:apache-ssl</cpe>
+       <packageUrl regex="true">^pkg:maven/org\.apache\.jackrabbit/oak-.*@.*$</packageUrl>
+       <cpe>cpe:/a:apache:xml_security_for_java</cpe>
     </suppress>
     <suppress>
        <notes><![CDATA[
-       false positive for Oak classes e.g. for CVE-2021-40690
+       file name: org.apache.sling.api-2.16.4.jar, is not embedded here but only a runtime dependency
        ]]></notes>
-       <packageUrl regex="true">^pkg:maven/org\.apache\.jackrabbit/oak-.*@.*$</packageUrl>
-       <cpe>cpe:/a:apache:xml_security_for_java</cpe>
+       <packageUrl regex="true">^pkg:maven/org\.apache\.sling/org\.apache\.sling\.api@.*$</packageUrl>
+       <vulnerabilityName>CVE-2022-32549</vulnerabilityName>
     </suppress>
 </suppressions>
\ No newline at end of file
diff --git a/target-osgi-environment/pom.xml b/target-osgi-environment/pom.xml
index 3c44ddd2..58357ae4 100644
--- a/target-osgi-environment/pom.xml
+++ b/target-osgi-environment/pom.xml
@@ -188,18 +188,6 @@
             <version>5.1.0</version>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.classloader</artifactId>
-            <version>1.4.2</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.20</version>
-            <scope>provided</scope>
-        </dependency>
         <dependency>
             <groupId>javax.jcr</groupId>
             <artifactId>jcr</artifactId>
diff --git a/vault-rcp/bnd.bnd b/vault-rcp/bnd.bnd
index 0fd45fec..5daae1b0 100644
--- a/vault-rcp/bnd.bnd
+++ b/vault-rcp/bnd.bnd
@@ -19,7 +19,7 @@
                   @jackrabbit-spi2dav-[0-9.]*(-SNAPSHOT)?.jar,\
                   @jackrabbit-jcr-client-[0-9.]*(-SNAPSHOT)?.jar,\
                   @jackrabbit-jcr2spi-[0-9.]*(-SNAPSHOT)?.jar
--conditionalpackage: org.apache.jackrabbit.util,org.apache.jackrabbit.api.security
+-conditionalpackage: org.apache.jackrabbit.util,org.apache.jackrabbit.api.security,org.apache.felix.utils.json
 # make sure to only export the relevant packages (https://github.com/bndtools/bnd/issues/4219)
 -exportcontents: org.apache.jackrabbit.vault.rcp
 # due to Jackrabbit2 JARs poorly designed for OSGi, only export the class used in the API from package "org.apache.jackrabbit.spi2dav", as the other classes in that package have lots of private references
diff --git a/vault-rcp/pom.xml b/vault-rcp/pom.xml
index 6eb3eb9a..b3d97a02 100644
--- a/vault-rcp/pom.xml
+++ b/vault-rcp/pom.xml
@@ -140,24 +140,7 @@
             <artifactId>slf4j-api</artifactId>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.6</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.classloader</artifactId>
-            <version>1.2.2</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
-            <version>2.16.4</version>
-            <scope>provided</scope>
-        </dependency>
+        
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
@@ -174,6 +157,17 @@
             <artifactId>org.osgi.service.cm</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+            <version>1.11.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.16.4</version>
+            <scope>provided</scope>
+        </dependency>
         <!-- OSGi Annotations: @Version -->
         <dependency>
             <groupId>org.osgi</groupId>
diff --git a/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/RcpServlet.java b/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/RcpServlet.java
index 21e06a98..3a478ecc 100644
--- a/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/RcpServlet.java
+++ b/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/RcpServlet.java
@@ -21,7 +21,6 @@ import java.io.IOException;
 import java.io.Writer;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.jcr.Credentials;
@@ -32,6 +31,8 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.felix.utils.json.JSONParser;
+import org.apache.felix.utils.json.JSONWriter;
 import org.apache.jackrabbit.spi2dav.ConnectionOptions;
 import org.apache.jackrabbit.vault.fs.api.RepositoryAddress;
 import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
@@ -41,14 +42,9 @@ import org.apache.jackrabbit.vault.rcp.RcpTaskManager;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
-import org.apache.sling.commons.json.JSONArray;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.JSONObject;
-import org.apache.sling.commons.json.io.JSONWriter;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -124,7 +120,6 @@ public class RcpServlet extends SlingAllMethodsServlet {
             } else {
                 String taskId = request.getRequestPathInfo().getSuffix();
                 JSONWriter w = new JSONWriter(response.getWriter());
-                w.setTidy(true);
     
                 if (taskId != null) {
                     taskId = taskId.substring(1);
@@ -146,14 +141,13 @@ public class RcpServlet extends SlingAllMethodsServlet {
                     w.endObject();
                 }
             }
-        } catch (JSONException e) {
-            throw new IOException(e.toString());
+        } catch (IOException e) {
+            throw new ServletException("Error writing JSON", e);
         }
     }
 
-    private void writeInfoJson(Writer writer) throws JSONException {
+    private void writeInfoJson(Writer writer) throws IOException {
         JSONWriter w = new JSONWriter(writer);
-        w.setTidy(true);
         w.object();
         w.key(Constants.BUNDLE_SYMBOLICNAME).value(bundle.getSymbolicName());
         w.key(Constants.BUNDLE_VERSION).value(bundle.getVersion().toString());
@@ -164,12 +158,11 @@ public class RcpServlet extends SlingAllMethodsServlet {
     @Override
     protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
             throws ServletException, IOException {
-        String json = IOUtils.toString(request.getReader());
-        JSONObject data;
+        TypedMapWrapper data;
         try {
-            data = new JSONObject(json);
-        } catch (JSONException e) {
-            log.error("Error while reading json: {}", e.toString());
+            data = new TypedMapWrapper(new JSONParser(request.getInputStream()).getParsed());
+        } catch (IOException e) {
+            log.error("Error while reading json", e);
             response.setStatus(500);
             return;
         }
@@ -205,14 +198,14 @@ public class RcpServlet extends SlingAllMethodsServlet {
                     creds = createCredentials(srcCreds);
                 }
                 Boolean recursive = null;
-                if (data.has(PARAM_RECURSIVE)) {
+                if (data.containsKey(PARAM_RECURSIVE)) {
                     recursive = data.optBoolean(PARAM_RECURSIVE, false);
                 }
 
                 ConnectionOptions.Builder connectionOptionsBuilder = ConnectionOptions.builder();
-                connectionOptionsBuilder.useSystemProperties(data.optBoolean(PARAM_USE_SYSTEM_PROPERTIES));
-                connectionOptionsBuilder.allowSelfSignedCertificates(data.optBoolean(PARAM_ALLOW_SELF_SIGNED_CERTIFICATE));
-                connectionOptionsBuilder.disableHostnameVerification(data.optBoolean(PARAM_DISABLE_HOSTNAME_VERIFICATION));
+                connectionOptionsBuilder.useSystemProperties(data.optBoolean(PARAM_USE_SYSTEM_PROPERTIES, false));
+                connectionOptionsBuilder.allowSelfSignedCertificates(data.optBoolean(PARAM_ALLOW_SELF_SIGNED_CERTIFICATE, false));
+                connectionOptionsBuilder.disableHostnameVerification(data.optBoolean(PARAM_DISABLE_HOSTNAME_VERIFICATION, false));
                 int connectionTimeoutMs = data.optInt(PARAM_CONNECTION_TIMEOUT_MS, -1);
                 connectionOptionsBuilder.connectionTimeoutMs(connectionTimeoutMs);
                 int requestTimeoutMs = data.optInt(PARAM_REQUEST_TIMEOUT_MS, -1);
@@ -220,27 +213,23 @@ public class RcpServlet extends SlingAllMethodsServlet {
                 int socketTimeoutMs = data.optInt(PARAM_SOCKET_TIMEOUT_MS, -1);
                 connectionOptionsBuilder.socketTimeoutMs(socketTimeoutMs);
 
-                if (data.has(PARAM_PROXY_HOST)) {
+                if (data.containsKey(PARAM_PROXY_HOST)) {
                     connectionOptionsBuilder.proxyHost(data.getString(PARAM_PROXY_HOST));
-                    if (data.has(PARAM_PROXY_PORT)) {
+                    if (data.containsKey(PARAM_PROXY_PORT)) {
                         connectionOptionsBuilder.proxyPort(data.getInt(PARAM_PROXY_PORT));
                     }
-                    if (data.has(PARAM_PROXY_PROTOCOL)) {
+                    if (data.containsKey(PARAM_PROXY_PROTOCOL)) {
                         connectionOptionsBuilder.proxyProtocol(data.getString(PARAM_PROXY_PROTOCOL));
                     }
-                    if (data.has(PARAM_PROXY_USERNAME)) {
+                    if (data.containsKey(PARAM_PROXY_USERNAME)) {
                         connectionOptionsBuilder.proxyUsername(data.getString(PARAM_PROXY_USERNAME));
-                        if (data.has(PARAM_PROXY_PASSWORD)) {
+                        if (data.containsKey(PARAM_PROXY_PASSWORD)) {
                             connectionOptionsBuilder.proxyPassword(data.getString(PARAM_PROXY_PASSWORD));
                         }
                     }
                 }
-                if (data.has(PARAM_EXCLUDES)) {
-                    List<String> excludeList = new LinkedList<>();
-                    JSONArray excludes = data.getJSONArray(PARAM_EXCLUDES);
-                    for (int idx = 0; idx < excludes.length(); idx++) {
-                        excludeList.add(excludes.getString(idx));
-                    }
+                if (data.containsKey(PARAM_EXCLUDES)) {
+                    List<String> excludeList = data.getStringList(PARAM_EXCLUDES);
                     if (isEdit) {
                         task = taskMgr.editTask(id, address, connectionOptionsBuilder.build(), creds, dst, excludeList, null, recursive);
                     } else {
@@ -248,7 +237,7 @@ public class RcpServlet extends SlingAllMethodsServlet {
                     }
                 } else {
                     final WorkspaceFilter filter;
-                    if (data.has(PARAM_FILTER)) {
+                    if (data.containsKey(PARAM_FILTER)) {
                         DefaultWorkspaceFilter filterImpl = new DefaultWorkspaceFilter();
                         filterImpl.load(IOUtils.toInputStream(data.getString(PARAM_FILTER), StandardCharsets.UTF_8));
                         filter = filterImpl;
@@ -263,22 +252,22 @@ public class RcpServlet extends SlingAllMethodsServlet {
                 }
 
                 // add additional data
-                if (data.has(PARAM_BATCHSIZE)) {
+                if (data.containsKey(PARAM_BATCHSIZE)) {
                     task.getRcp().setBatchSize((int) data.getLong(PARAM_BATCHSIZE));
                 }
-                if (data.has(PARAM_UPDATE)) {
+                if (data.containsKey(PARAM_UPDATE)) {
                     task.getRcp().setUpdate(data.optBoolean(PARAM_UPDATE, false));
                 }
-                if (data.has(PARAM_ONLY_NEWER)) {
+                if (data.containsKey(PARAM_ONLY_NEWER)) {
                     task.getRcp().setOnlyNewer(data.optBoolean(PARAM_ONLY_NEWER, false));
                 }
-                if (data.has(PARAM_NO_ORDERING)) {
+                if (data.containsKey(PARAM_NO_ORDERING)) {
                     task.getRcp().setNoOrdering(data.optBoolean(PARAM_NO_ORDERING, false));
                 }
-                if (data.has(PARAM_THROTTLE)) {
+                if (data.containsKey(PARAM_THROTTLE)) {
                     task.getRcp().setThrottle(data.getLong(PARAM_THROTTLE));
                 }
-                if (data.has(PARAM_RESUME_FROM)) {
+                if (data.containsKey(PARAM_RESUME_FROM)) {
                     task.getRcp().setResumeFrom(data.getString(PARAM_RESUME_FROM));
                 }
                 if (isEdit) {
@@ -340,7 +329,6 @@ public class RcpServlet extends SlingAllMethodsServlet {
             response.setContentType("application/json");
             response.setCharacterEncoding("utf-8");
             JSONWriter w = new JSONWriter(response.getWriter());
-            w.setTidy(true);
             w.object();
             w.key("status").value("ok");
             w.key("id").value(id);
@@ -352,13 +340,12 @@ public class RcpServlet extends SlingAllMethodsServlet {
             response.setCharacterEncoding("utf-8");
             response.setStatus(500);
             JSONWriter w = new JSONWriter(response.getWriter());
-            w.setTidy(true);
             try {
                 w.object();
                 w.key("status").value("error");
                 w.key("message").value("Error while executing '" + cmd + "': " + e.getMessage());
                 w.endObject();
-            } catch (JSONException e1) {
+            } catch (IOException e1) {
                 // ignore
             }
         }
@@ -377,7 +364,7 @@ public class RcpServlet extends SlingAllMethodsServlet {
         return creds;
     }
 
-    private static void write(JSONWriter w, RcpTask rcpTask) throws JSONException {
+    private static void write(JSONWriter w, RcpTask rcpTask) throws IOException {
         w.object();
         w.key(RcpServlet.PARAM_ID).value(rcpTask.getId());
         w.key(RcpServlet.PARAM_SRC).value(rcpTask.getSource().toString());
diff --git a/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/TypedMapWrapper.java b/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/TypedMapWrapper.java
new file mode 100644
index 00000000..9a498bd3
--- /dev/null
+++ b/vault-rcp/src/main/java/org/apache/jackrabbit/vault/rcp/impl/TypedMapWrapper.java
@@ -0,0 +1,100 @@
+/*
+ * 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.jackrabbit.vault.rcp.impl;
+
+import java.util.AbstractMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Adds helper methods to a wrapped Map containing objects of different types.
+ * Those additional getter methods allow to retrieve a specific typed value.
+ * The method names are inspired by <a href="https://sling.apache.org/apidocs/sling8/org/apache/sling/commons/json/JSONObject.html">org.apache.sling.commons.json.JSONObject</a>.
+ */
+public class TypedMapWrapper extends AbstractMap<String,Object> implements Map<String, Object> {
+
+    private final Map<String, Object> wrappedMap;
+    public TypedMapWrapper(Map<String, Object> wrappedMap) {
+        this.wrappedMap = wrappedMap;
+    }
+
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        return wrappedMap.entrySet();
+    }
+
+    public String getString(String key) {
+        return getTypedOrThrow(key, String.class);
+    }
+
+    public String optString(String key, String defaultValue) {
+        return getTypedOrDefault(key, String.class, defaultValue);
+    }
+
+    public List<String> getStringList(String key) {
+        List<?> objects = getTypedOrThrow(key, List.class);
+        return objects.stream().map( o -> {
+            if (o.getClass().isAssignableFrom(String.class)) {
+                return String.class.cast(o);
+            }
+            throw new IllegalArgumentException("List does not contain out of strings");
+        }).collect(Collectors.toList());
+    }
+
+    public long getLong(String key) throws IllegalArgumentException {
+        return getTypedOrThrow(key, Long.class);
+    }
+
+    public boolean getBoolean(String key) throws IllegalArgumentException {
+        return getTypedOrThrow(key, Boolean.class);
+    }
+
+    public boolean optBoolean(String key, boolean defaultValue) {
+        return getTypedOrDefault(key, Boolean.class, defaultValue);
+    }
+
+    public int getInt(String key) throws IllegalArgumentException {
+        return getTypedOrThrow(key, Integer.class);
+    }
+
+    public int optInt(String key, int defaultValue) {
+        return getTypedOrDefault(key, Integer.class, defaultValue);
+    }
+
+    private <T> T getTypedOrDefault(String key, Class<T> clazz, T defaultValue) {
+        return getTyped(key, clazz).orElse(defaultValue);
+    }
+
+    private <T> T getTypedOrThrow(String key, Class<T> clazz) {
+        return getTyped(key, clazz).orElseThrow(() -> new IllegalArgumentException("Key is unknown or value is no " + clazz));
+    }
+
+    private <T> Optional<T> getTyped(String key, Class<T> clazz) {
+        Object object = get(key);
+        if (object.getClass().isAssignableFrom(clazz)) {
+            return Optional.of(clazz.cast(object));
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    
+}