diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/domain/DataSource.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/domain/DataSource.java index e7d1fe9e7aa42289ad873d5f9b08cdb1c095b97e..b36f7ea218b20f5af6c838ca1aca0c46a9e50077 100644 --- a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/domain/DataSource.java +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/domain/DataSource.java @@ -34,6 +34,12 @@ public class DataSource { @TableField String password; + /** + * true 修改密码 false不修改 + */ + @TableField(exist = false) + boolean edit_password; + @TableField String type; diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/service/DataSourceService.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/service/DataSourceService.java index ab3e65d858a754820238965a3724af0896d87fb2..f207b06c6f6ea13110e4a212435f17f3dde93f9b 100644 --- a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/service/DataSourceService.java +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/service/DataSourceService.java @@ -3,6 +3,7 @@ package com.gitee.freakchicken.dbapi.basic.service; import com.gitee.freakchicken.dbapi.basic.dao.ApiConfigMapper; import com.gitee.freakchicken.dbapi.basic.dao.DataSourceMapper; import com.gitee.freakchicken.dbapi.basic.domain.DataSource; +import com.gitee.freakchicken.dbapi.basic.util.DESUtils; import com.gitee.freakchicken.dbapi.basic.util.PoolManager; import com.gitee.freakchicken.dbapi.basic.util.UUIDUtil; import com.gitee.freakchicken.dbapi.common.ResponseDto; @@ -46,6 +47,13 @@ public class DataSourceService { dataSource.setId(UUIDUtil.id()); dataSource.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); dataSource.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + + //新增数据源对密码加密 + try { + dataSource.setPassword(DESUtils.encrypt(dataSource.getPassword())); + } catch (Exception e) { + e.printStackTrace(); + } dataSourceMapper.insert(dataSource); } @@ -53,6 +61,14 @@ public class DataSourceService { @Transactional public void update(DataSource dataSource) { dataSource.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + //如果修改了密码, 需要对密码加密 + if (dataSource.isEdit_password()){ + try { + dataSource.setPassword(DESUtils.encrypt(dataSource.getPassword())); + } catch (Exception e) { + e.printStackTrace(); + } + } dataSourceMapper.updateById(dataSource); PoolManager.removeJdbcConnectionPool(dataSource.getId()); cacheManager.getCache("datasource").evictIfPresent(dataSource.getId()); diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/DESUtils.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/DESUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..db0c0197ca1e9b9f056872bd47b93ce16343bfd3 --- /dev/null +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/DESUtils.java @@ -0,0 +1,129 @@ +package com.gitee.freakchicken.dbapi.basic.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import java.io.IOException; +import java.security.*; + +public class DESUtils { + + private final static String DES = "DES"; + private final static String ENCODE = "UTF-8"; + + //key 随便写 + private final static String DES_KEY = "db-api-key"; + + + public static void main(String[] args) { + String pass = "root123456"; + System.out.println("加密前: " + pass); + try { + String encrypt = encrypt(pass); + System.err.println("加密后: " + encrypt); + System.err.println("解密后: " + decrypt(encrypt)); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + + /** + * Description 根据键值进行加密 + * + * @param data 待加密数据 + * @param key 密钥 + * @return + * @throws Exception + */ + public static String encrypt(String data) throws Exception { + byte[] bt = encrypt(data.getBytes(ENCODE), DES_KEY.getBytes(ENCODE)); + String strs = new BASE64Encoder().encode(bt); + return strs; + } + + /** + * 根据键值进行解密 + * + * @param data 待解密数据 + * @param key 密钥 + * @return + * @throws IOException + * @throws Exception + */ + public static String decrypt(String data) throws IOException, + Exception { + if (data == null) + return null; + BASE64Decoder decoder = new BASE64Decoder(); + byte[] buf = decoder.decodeBuffer(data); + byte[] bt = decrypt(buf, DES_KEY.getBytes(ENCODE)); + return new String(bt, ENCODE); + } + + /** + * Description 根据键值进行加密 + * + * @param data + * @param key 加密键byte数组 + * @return + * @throws Exception + */ + private static byte[] encrypt(byte[] data, byte[] key) throws Exception { + // 生成一个可信任的随机数源 + SecureRandom sr = new SecureRandom(); + + // 从原始密钥数据创建DESKeySpec对象 + DESKeySpec dks = new DESKeySpec(key); + + // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); + SecretKey securekey = keyFactory.generateSecret(dks); + + // Cipher对象实际完成加密操作 + Cipher cipher = Cipher.getInstance(DES); + + // 用密钥初始化Cipher对象 + cipher.init(Cipher.ENCRYPT_MODE, securekey, sr); + + return cipher.doFinal(data); + } + + /** + * Description 根据键值进行解密 + * + * @param data + * @param key 加密键byte数组 + * @return + * @throws Exception + */ + private static byte[] decrypt(byte[] data, byte[] key) throws Exception { + // 生成一个可信任的随机数源 + SecureRandom sr = new SecureRandom(); + + // 从原始密钥数据创建DESKeySpec对象 + DESKeySpec dks = new DESKeySpec(key); + + // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象 + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); + SecretKey securekey = keyFactory.generateSecret(dks); + + // Cipher对象实际完成解密操作 + Cipher cipher = Cipher.getInstance(DES); + + // 用密钥初始化Cipher对象 + cipher.init(Cipher.DECRYPT_MODE, securekey, sr); + + return cipher.doFinal(data); + } + + +} \ No newline at end of file diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java index 75211f890c7802cd6aeb216f4f2248abcd04312c..155d906a43acde3dc1f6fb26e0127c2f9ba4f311 100644 --- a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/JdbcUtil.java @@ -19,10 +19,11 @@ public class JdbcUtil { return resultSet; } - public static Connection getConnection(DataSource ds) throws SQLException { + public static Connection getConnection(DataSource ds) throws Exception { try { Class.forName(ds.getDriver()); - Connection connection = DriverManager.getConnection(ds.getUrl(), ds.getUsername(), ds.getPassword()); + String password = ds.isEdit_password() ? ds.getPassword() : DESUtils.decrypt(ds.getPassword()); + Connection connection = DriverManager.getConnection(ds.getUrl(), ds.getUsername(),password); log.info("successfully connected"); return connection; } catch (ClassNotFoundException e) { diff --git a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/PoolManager.java b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/PoolManager.java index aa682a61857f7b8e5324f713acbf6c30444fcf20..e06f338ada06f4fc8945ea503dd4dce590d1709f 100644 --- a/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/PoolManager.java +++ b/dbapi-service/src/main/java/com/gitee/freakchicken/dbapi/basic/util/PoolManager.java @@ -4,6 +4,7 @@ import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidPooledConnection; import com.gitee.freakchicken.dbapi.basic.domain.DataSource; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; import java.sql.SQLException; import java.util.HashMap; @@ -38,6 +39,12 @@ public class PoolManager { druidDataSource.setConnectionErrorRetryAttempts(3); //失败后重连次数 druidDataSource.setBreakAfterAcquireFailure(true); + try { + druidDataSource.setPassword(DESUtils.decrypt(ds.getPassword())); + } catch (Exception e) { + e.printStackTrace(); + } + map.put(ds.getId(), druidDataSource); log.info("create druid datasource:{}", ds.getName()); return map.get(ds.getId()); diff --git a/dbapi-ui/src/components/datasource/add.vue b/dbapi-ui/src/components/datasource/add.vue index 0caed9e8aa3446b802f83d08c439d51e4ac87bbe..2228d43bdb151f62d37a6b2930afba0fc1f8de88 100644 --- a/dbapi-ui/src/components/datasource/add.vue +++ b/dbapi-ui/src/components/datasource/add.vue @@ -24,6 +24,7 @@ export default { "url": data.url, "username": data.username, "password": data.password, + "edit_password": data.edit_password, "type": data.type, "driver": data.driver, "tableSql": data.tableSql diff --git a/dbapi-ui/src/components/datasource/common.vue b/dbapi-ui/src/components/datasource/common.vue index 42fe11ece224c686f1381d754b7f049a0b93900e..b83a4407ad212f145c311eb544658bfc2d9e0c40 100644 --- a/dbapi-ui/src/components/datasource/common.vue +++ b/dbapi-ui/src/components/datasource/common.vue @@ -29,8 +29,14 @@ - - + + + + + + + + @@ -48,6 +54,7 @@ export default { name: "common", data() { return { + flag: false, options: [{label: 'mysql', value: 'mysql'}, {label: 'postgresql',value: 'postgresql'}, {label: 'hive',value: 'hive'}, {label: 'sqlserver',value: 'sqlserver'}, {label: 'clickhouse',value: 'clickhouse'}, {label: 'kylin',value: 'kylin'}, {label: 'oracle',value: 'oracle'}, {label: '其他',value:'others'}], @@ -58,6 +65,7 @@ export default { type: null, username: null, password: null, + edit_password: false, driver: null, tableSql: null }, @@ -101,6 +109,11 @@ export default { }, props: ["id"], methods: { + checked(){ + if (this.detail.edit_password){ + this.detail.password = null; + } + }, selectDB() { this.detail.url = (this.ds[this.detail.type]).url this.detail.driver = (this.ds[this.detail.type]).driver @@ -118,6 +131,7 @@ export default { "url": this.detail.url, "username": this.detail.username, "password": this.detail.password, + "edit_password": this.detail.edit_password, "driver": this.detail.driver }).then((response) => { if (response.data.success) diff --git a/dbapi-ui/src/components/datasource/edit.vue b/dbapi-ui/src/components/datasource/edit.vue index 9d5ba338c83ece3647294d7317a41247b052b289..bd5e8f10ff17afabc9290f79c215f7f8f14d3f47 100644 --- a/dbapi-ui/src/components/datasource/edit.vue +++ b/dbapi-ui/src/components/datasource/edit.vue @@ -27,6 +27,7 @@ export default { "url": data.url, "username": data.username, "password": data.password, + "edit_password": data.edit_password, "type": data.type, "id": data.id, "driver": data.driver, diff --git a/dbapi-ui/src/i18n/langs/en.js b/dbapi-ui/src/i18n/langs/en.js index 1e65421b20be89e1818e7e63e262c1edae63ac94..2c401f1d2651c643b7c40c3cc75f440cf0025617 100644 --- a/dbapi-ui/src/i18n/langs/en.js +++ b/dbapi-ui/src/i18n/langs/en.js @@ -16,6 +16,7 @@ const en = { jdbc_driver_class: 'JDBC Driver Class', username: 'Username', password: 'Password', + edit_password: 'Edit', sql_query_all_table_name: 'SQL that get table names', test_connection: 'Test Connection', save: 'Save', @@ -94,4 +95,4 @@ const en = { ...enLocale } -export default en \ No newline at end of file +export default en diff --git a/dbapi-ui/src/i18n/langs/zh.js b/dbapi-ui/src/i18n/langs/zh.js index 298a0e094ed0e1c76daf0e695b393a8c825ca0f5..f85974fd56f73972d78b3dbee7e66c493eaf4c4a 100644 --- a/dbapi-ui/src/i18n/langs/zh.js +++ b/dbapi-ui/src/i18n/langs/zh.js @@ -17,6 +17,7 @@ const cn = { jdbc_driver_class: 'JDBC驱动Class', username: '用户名', password: '密码', + edit_password: '修改', sql_query_all_table_name: '查询所有表名称的SQL', test_connection: '连接测试', save: '保存', @@ -94,4 +95,4 @@ const cn = { ...zhLocale } -export default cn \ No newline at end of file +export default cn