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

peacewong pushed a commit to branch dev-1.3.0
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git


The following commit(s) were added to refs/heads/dev-1.3.0 by this push:
     new 6bef23903 [Feature] [JDBC-Engine] Optimize JDBC parameter acquisition 
logic. (#3239)
6bef23903 is described below

commit 6bef2390385aac964f478ab0cb4d399fcd4b349d
Author: weixiao <[email protected]>
AuthorDate: Mon Sep 5 11:55:28 2022 +0800

    [Feature] [JDBC-Engine] Optimize JDBC parameter acquisition logic. (#3239)
---
 .../engineplugin/jdbc/ConnectionManager.java       |  39 ++-----
 .../engineplugin/jdbc/utils/JdbcParamUtils.java    | 119 +++++++++++++++++++++
 .../jdbc/utils/JdbcParamUtilsTest.java             |  82 ++++++++++++++
 3 files changed, 209 insertions(+), 31 deletions(-)

diff --git 
a/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/ConnectionManager.java
 
b/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/ConnectionManager.java
index a62166058..f80037f65 100644
--- 
a/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/ConnectionManager.java
+++ 
b/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/ConnectionManager.java
@@ -20,6 +20,7 @@ package org.apache.linkis.manager.engineplugin.jdbc;
 import org.apache.linkis.hadoop.common.utils.KerberosUtils;
 import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant;
 import 
org.apache.linkis.manager.engineplugin.jdbc.exception.JDBCParamsIllegalException;
+import org.apache.linkis.manager.engineplugin.jdbc.utils.JdbcParamUtils;
 
 import org.apache.commons.dbcp.BasicDataSource;
 import org.apache.commons.lang3.StringUtils;
@@ -42,7 +43,6 @@ import org.slf4j.LoggerFactory;
 import static org.apache.linkis.manager.engineplugin.jdbc.JdbcAuthType.*;
 
 public class ConnectionManager {
-
   private static final Logger LOG = 
LoggerFactory.getLogger(ConnectionManager.class);
 
   private final Map<String, DataSource> dataSourceFactories;
@@ -109,27 +109,20 @@ public class ConnectionManager {
 
   protected DataSource buildDataSource(String dbUrl, Map<String, String> 
properties)
       throws JDBCParamsIllegalException {
+
     String driverClassName =
         JDBCPropertiesParser.getString(properties, 
JDBCEngineConnConstant.JDBC_DRIVER, "");
-
     if (StringUtils.isBlank(driverClassName)) {
       LOG.error("The driver class name is not empty.");
       throw new JDBCParamsIllegalException("The driver class name is not 
empty.");
     }
 
-    String username =
-        JDBCPropertiesParser.getString(properties, 
JDBCEngineConnConstant.JDBC_USERNAME, "");
-    String password =
-        JDBCPropertiesParser.getString(properties, 
JDBCEngineConnConstant.JDBC_PASSWORD, "");
+    String username = JdbcParamUtils.getJdbcUsername(properties);
+    String password = JdbcParamUtils.getJdbcPassword(properties);
     JdbcAuthType jdbcAuthType = getJdbcAuthType(properties);
     switch (jdbcAuthType) {
       case USERNAME:
-        if (StringUtils.isBlank(username)) {
-          throw new JDBCParamsIllegalException("The jdbc username is not 
empty.");
-        }
-        if (StringUtils.isBlank(password)) {
-          throw new JDBCParamsIllegalException("The jdbc password is not 
empty.");
-        }
+        LOG.info("The jdbc auth type is username and password.");
         break;
       case SIMPLE:
         LOG.info("The jdbc auth type is simple.");
@@ -294,28 +287,12 @@ public class ConnectionManager {
     if (StringUtils.isBlank(url)) {
       throw new SQLException(JDBCEngineConnConstant.JDBC_URL + " is not 
empty.");
     }
-    url = clearJDBCUrl(url);
-    validateJDBCUrl(url);
+    url = JdbcParamUtils.clearJdbcUrl(url);
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    JdbcParamUtils.validateJdbcUrl(url);
     return url.trim();
   }
 
-  private String clearJDBCUrl(String url) {
-    if (url.startsWith("\"") && url.endsWith("\"")) {
-      url = url.trim();
-      return url.substring(1, url.length() - 1);
-    }
-    return url;
-  }
-
-  private void validateJDBCUrl(String url) {
-    if (StringUtils.isEmpty(url)) {
-      throw new NullPointerException(JDBCEngineConnConstant.JDBC_URL + " 
cannot be null.");
-    }
-    if (!url.matches("jdbc:\\w+://\\S+:[0-9]{2,6}(/\\S*)?") && 
!url.startsWith("jdbc:h2")) {
-      throw new IllegalArgumentException("JDBC url format error!" + url);
-    }
-  }
-
   private String appendProxyUserToJDBCUrl(
       String jdbcUrl, String execUser, Map<String, String> properties) {
     StringBuilder jdbcUrlSb = new StringBuilder(jdbcUrl);
diff --git 
a/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtils.java
 
b/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtils.java
new file mode 100644
index 000000000..a6d3c7961
--- /dev/null
+++ 
b/linkis-engineconn-plugins/jdbc/src/main/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtils.java
@@ -0,0 +1,119 @@
+/*
+ * 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.linkis.manager.engineplugin.jdbc.utils;
+
+import org.apache.linkis.manager.engineplugin.jdbc.JDBCPropertiesParser;
+import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant;
+import 
org.apache.linkis.manager.engineplugin.jdbc.exception.JDBCParamsIllegalException;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JdbcParamUtils {
+  private static final Logger LOG = 
LoggerFactory.getLogger(JdbcParamUtils.class);
+  private static final String JDBC_MATCH_REGEX = 
"jdbc:\\w+://\\S+:[0-9]{2,6}(/\\S*)?";
+  private static final String JDBC_H2_PROTOCOL = "jdbc:h2";
+
+  private static final String JDBC_MYSQL_PROTOCOL = "jdbc:mysql";
+
+  private static final String SENSITIVE_PARAM = "autoDeserialize=true";
+  private static final String AUTO_DESERIALIZE = "autoDeserialize";
+
+  private static final String APPEND_PARAMS =
+      
"allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false";
+
+  private static final char AND_SYMBOL = '&';
+
+  private static final String QUOTATION_MARKS = "\"";
+
+  private static final char QUESTION_MARK = '?';
+
+  public static String clearJdbcUrl(String url) {
+    if (url.startsWith(QUOTATION_MARKS) && url.endsWith(QUOTATION_MARKS)) {
+      url = url.trim();
+      return url.substring(1, url.length() - 1);
+    }
+    return url;
+  }
+
+  public static void validateJdbcUrl(String url) {
+    if (!url.matches(JDBC_MATCH_REGEX) && !url.startsWith(JDBC_H2_PROTOCOL)) {
+      throw new IllegalArgumentException("JDBC url format error!" + url);
+    }
+  }
+
+  public static String filterJdbcUrl(String url) {
+    // temporarily filter only mysql jdbc url.
+    if (!url.startsWith(JDBC_MYSQL_PROTOCOL)) {
+      return url;
+    }
+    if (url.contains(SENSITIVE_PARAM)) {
+      int index = url.indexOf(SENSITIVE_PARAM);
+      String tmp = SENSITIVE_PARAM;
+      if (url.charAt(index - 1) == AND_SYMBOL) {
+        tmp = AND_SYMBOL + tmp;
+      } else if (url.charAt(index + 1) == AND_SYMBOL) {
+        tmp = tmp + AND_SYMBOL;
+      }
+      LOG.warn("Sensitive param: {} in jdbc url is filtered.", tmp);
+      url = url.replace(tmp, "");
+    }
+    if (url.endsWith(String.valueOf(QUESTION_MARK))) {
+      url = url + APPEND_PARAMS;
+    } else if (url.lastIndexOf(QUESTION_MARK) < 0) {
+      url = url + QUESTION_MARK + APPEND_PARAMS;
+    } else {
+      url = url + AND_SYMBOL + APPEND_PARAMS;
+    }
+    LOG.info("The filtered jdbc url is: {}", url);
+    return url;
+  }
+
+  public static String getJdbcUsername(Map<String, String> properties)
+      throws JDBCParamsIllegalException {
+    String username =
+        JDBCPropertiesParser.getString(properties, 
JDBCEngineConnConstant.JDBC_USERNAME, "");
+    if (StringUtils.isBlank(username)) {
+      throw new JDBCParamsIllegalException("The jdbc username is not empty.");
+    }
+    if (username.contains(AUTO_DESERIALIZE)) {
+      LOG.warn("Sensitive param : {} in username field is filtered.", 
AUTO_DESERIALIZE);
+      username = username.replace(AUTO_DESERIALIZE, "");
+    }
+    LOG.info("The jdbc username is: {}", username);
+    return username;
+  }
+
+  public static String getJdbcPassword(Map<String, String> properties)
+      throws JDBCParamsIllegalException {
+    String password =
+        JDBCPropertiesParser.getString(properties, 
JDBCEngineConnConstant.JDBC_PASSWORD, "");
+    if (StringUtils.isBlank(password)) {
+      throw new JDBCParamsIllegalException("The jdbc password is not empty.");
+    }
+    if (password.contains(AUTO_DESERIALIZE)) {
+      LOG.warn("Sensitive param : {} in password field is filtered", 
AUTO_DESERIALIZE);
+      password = password.replace(AUTO_DESERIALIZE, "");
+    }
+    return password;
+  }
+}
diff --git 
a/linkis-engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtilsTest.java
 
b/linkis-engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtilsTest.java
new file mode 100644
index 000000000..a8997d7ca
--- /dev/null
+++ 
b/linkis-engineconn-plugins/jdbc/src/test/java/org/apache/linkis/manager/engineplugin/jdbc/utils/JdbcParamUtilsTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.linkis.manager.engineplugin.jdbc.utils;
+
+import 
org.apache.linkis.manager.engineplugin.jdbc.constant.JDBCEngineConnConstant;
+import 
org.apache.linkis.manager.engineplugin.jdbc.exception.JDBCParamsIllegalException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+public class JdbcParamUtilsTest {
+  @Test
+  @DisplayName("testFilterJdbcUrl")
+  public void testFilterJdbcUrl() {
+    String url = "jdbc:mysql://localhost:3306/db_name";
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    Assertions.assertEquals(
+        
"jdbc:mysql://localhost:3306/db_name?allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false",
+        url);
+
+    url = "jdbc:mysql://localhost:3306/db_name?p1=v1";
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    Assertions.assertEquals(
+        
"jdbc:mysql://localhost:3306/db_name?p1=v1&allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false",
+        url);
+
+    url = "jdbc:mysql://localhost:3306/db_name?autoDeserialize=true";
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    Assertions.assertEquals(
+        
"jdbc:mysql://localhost:3306/db_name?allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false",
+        url);
+
+    url = "jdbc:mysql://localhost:3306/db_name?p1=v1&autoDeserialize=true";
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    Assertions.assertEquals(
+        
"jdbc:mysql://localhost:3306/db_name?p1=v1&allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false",
+        url);
+
+    url = 
"jdbc:mysql://localhost:3306/db_name?p1=v1&autoDeserialize=true&p2=v2";
+    url = JdbcParamUtils.filterJdbcUrl(url);
+    Assertions.assertEquals(
+        
"jdbc:mysql://localhost:3306/db_name?p1=v1&p2=v2&allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false",
+        url);
+  }
+
+  @Test
+  @DisplayName("testGetJdbcUsername")
+  public void testGetJdbcUsername() throws JDBCParamsIllegalException {
+    Map<String, String> properties = new HashMap<>();
+    properties.put(JDBCEngineConnConstant.JDBC_USERNAME, 
"test123?autoDeserialize=true");
+    String username = JdbcParamUtils.getJdbcUsername(properties);
+    Assertions.assertEquals("test123?=true", username);
+  }
+
+  @Test
+  @DisplayName("testGetJdbcPassword")
+  public void testGetJdbcPassword() throws JDBCParamsIllegalException {
+    Map<String, String> properties = new HashMap<>();
+    properties.put(JDBCEngineConnConstant.JDBC_USERNAME, 
"test_pwd?autoDeserialize=true");
+    String password = JdbcParamUtils.getJdbcUsername(properties);
+    Assertions.assertEquals("test_pwd?=true", password);
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to