From 86f4276f0fd8d3d42ce9bcc13463eb015232b56f Mon Sep 17 00:00:00 2001 From: Tboy Date: Tue, 19 May 2020 18:48:58 +0800 Subject: [PATCH] Fix MySQL autoDeserialize bug (#2728) * Fix MySQL autoDeserialize bug * add MySQLDataSourceTest --- .../dao/datasource/BaseDataSource.java | 13 ++-- .../dao/datasource/MySQLDataSource.java | 43 +++++++++++++ .../dao/datasource/MySQLDataSourceTest.java | 64 +++++++++++++++++++ 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSourceTest.java diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/BaseDataSource.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/BaseDataSource.java index 1132147faf..30d5d778d3 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/BaseDataSource.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/BaseDataSource.java @@ -34,12 +34,12 @@ public abstract class BaseDataSource { /** * user name */ - private String user; + protected String user; /** * user password */ - private String password; + protected String password; /** * data source address @@ -124,7 +124,8 @@ public abstract class BaseDataSource { * @param jdbcUrl jdbc url */ private void appendOther(StringBuilder jdbcUrl) { - if (StringUtils.isNotEmpty(getOther())) { + String otherParams = filterOther(getOther()); + if (StringUtils.isNotEmpty(otherParams)) { String separator = ""; switch (dbTypeSelector()) { case CLICKHOUSE: @@ -144,10 +145,14 @@ public abstract class BaseDataSource { default: logger.error("Db type mismatch!"); } - jdbcUrl.append(separator).append(getOther()); + jdbcUrl.append(separator).append(otherParams); } } + protected String filterOther(String otherParams){ + return otherParams; + } + /** * test whether the data source can be connected successfully */ diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSource.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSource.java index 94a4895df9..d2024ecfde 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSource.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSource.java @@ -18,12 +18,20 @@ package org.apache.dolphinscheduler.dao.datasource; import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.enums.DbType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * data source of mySQL */ public class MySQLDataSource extends BaseDataSource { + private final Logger logger = LoggerFactory.getLogger(MySQLDataSource.class); + + private final String sensitiveParam = "autoDeserialize=true"; + + private final char symbol = '&'; + /** * gets the JDBC url for the data source connection * @return jdbc url @@ -41,4 +49,39 @@ public class MySQLDataSource extends BaseDataSource { return DbType.MYSQL; } + @Override + protected String filterOther(String other){ + if(other.contains(sensitiveParam)){ + int index = other.indexOf(sensitiveParam); + String tmp = sensitiveParam; + if(index == 0 || other.charAt(index + 1) == symbol){ + tmp = tmp + symbol; + } else if(other.charAt(index - 1) == symbol){ + tmp = symbol + tmp; + } + logger.warn("sensitive param : {} in otherParams field is filtered", tmp); + other = other.replace(tmp, ""); + } + logger.debug("other : {}", other); + return other; + } + + @Override + public String getUser() { + if(user.contains(sensitiveParam)){ + logger.warn("sensitive param : {} in username field is filtered", sensitiveParam); + user = user.replace(sensitiveParam, ""); + } + logger.debug("username : {}", user); + return user; + } + + @Override + public String getPassword() { + if(password.contains(sensitiveParam)){ + logger.warn("sensitive param : {} in password field is filtered", sensitiveParam); + password = password.replace(sensitiveParam, ""); + } + return password; + } } diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSourceTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSourceTest.java new file mode 100644 index 0000000000..59bf5c412e --- /dev/null +++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/datasource/MySQLDataSourceTest.java @@ -0,0 +1,64 @@ +/* + * 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.dolphinscheduler.dao.datasource; + +import org.junit.Assert; +import org.junit.Test; + +/** + * test data source of mySQL + */ +public class MySQLDataSourceTest { + + @Test + public void testGetUser(){ + MySQLDataSource dataSource = new MySQLDataSource(); + String safeUsername= "test123"; + dataSource.setUser(safeUsername); + Assert.assertEquals("test123", dataSource.getUser()); + String sensitiveUsername= "test123?autoDeserialize=true"; + dataSource.setUser(sensitiveUsername); + Assert.assertEquals("test123?", dataSource.getUser()); + } + + @Test + public void testGetPassword(){ + MySQLDataSource dataSource = new MySQLDataSource(); + String safePwd= "test_pwd"; + dataSource.setPassword(safePwd); + Assert.assertEquals("test_pwd", dataSource.getPassword()); + String sensitivePwd= "test_pwd?autoDeserialize=true"; + dataSource.setPassword(sensitivePwd); + Assert.assertEquals("test_pwd?", dataSource.getPassword()); + } + + @Test + public void testFilterOther(){ + MySQLDataSource dataSource = new MySQLDataSource(); + String other = dataSource.filterOther("serverTimezone=Asia/Shanghai&characterEncoding=utf8"); + Assert.assertEquals("serverTimezone=Asia/Shanghai&characterEncoding=utf8", other); + //at the first + other = dataSource.filterOther("autoDeserialize=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8"); + Assert.assertEquals("serverTimezone=Asia/Shanghai&characterEncoding=utf8", other); + //at the end + other = dataSource.filterOther("serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoDeserialize=true"); + Assert.assertEquals("serverTimezone=Asia/Shanghai&characterEncoding=utf8", other); + //in the middle + other = dataSource.filterOther("serverTimezone=Asia/Shanghai&autoDeserialize=true&characterEncoding=utf8"); + Assert.assertEquals("serverTimezone=Asia/Shanghai&characterEncoding=utf8", other); + } +}