Skip to content

Commit d3afefb

Browse files
committed
[Bug][Seatunnel-web] Support encyrption of datasource data
1 parent 53a89aa commit d3afefb

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/DatasourceServiceImpl.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.seatunnel.app.service.ITableSchemaService;
3838
import org.apache.seatunnel.app.thirdparty.datasource.DataSourceClientFactory;
3939
import org.apache.seatunnel.app.thirdparty.framework.SeaTunnelOptionRuleWrapper;
40+
import org.apache.seatunnel.app.utils.ConfigShadeUtil;
4041
import org.apache.seatunnel.common.utils.JsonUtils;
4142
import org.apache.seatunnel.datasource.plugin.api.DataSourcePluginInfo;
4243
import org.apache.seatunnel.datasource.plugin.api.DatasourcePluginTypeEnum;
@@ -53,6 +54,7 @@
5354
import org.springframework.beans.BeansException;
5455
import org.springframework.beans.factory.annotation.Autowired;
5556
import org.springframework.beans.factory.annotation.Qualifier;
57+
import org.springframework.beans.factory.annotation.Value;
5658
import org.springframework.context.ApplicationContext;
5759
import org.springframework.context.ApplicationContextAware;
5860
import org.springframework.stereotype.Service;
@@ -93,6 +95,9 @@ public class DatasourceServiceImpl extends SeatunnelBaseServiceImpl
9395

9496
protected static final String DEFAULT_DATASOURCE_PLUGIN_VERSION = "1.0.0";
9597

98+
@Value("${datasource.encryption.type:default}")
99+
private String datasourceEncryptionType;
100+
96101
@Override
97102
public String createDatasource(
98103
Integer userId,
@@ -113,6 +118,7 @@ public String createDatasource(
113118
throw new SeatunnelException(
114119
SeatunnelErrorEnum.DATASOURCE_PRAM_NOT_ALLOWED_NULL, "datasourceConfig");
115120
}
121+
ConfigShadeUtil.encryptData(datasourceConfig, datasourceEncryptionType);
116122
String datasourceConfigStr = JsonUtils.toJsonString(datasourceConfig);
117123
Datasource datasource =
118124
Datasource.builder()
@@ -171,6 +177,7 @@ public boolean updateDatasource(
171177
datasource.setUpdateTime(new Date());
172178
datasource.setDescription(description);
173179
if (MapUtils.isNotEmpty(datasourceConfig)) {
180+
ConfigShadeUtil.encryptData(datasourceConfig, datasourceEncryptionType);
174181
String configJson = JsonUtils.toJsonString(datasourceConfig);
175182
datasource.setDatasourceConfig(configJson);
176183
}
@@ -208,6 +215,7 @@ public boolean testDatasourceConnectionAble(
208215
String pluginVersion,
209216
Map<String, String> datasourceConfig) {
210217
funcPermissionCheck(SeatunnelFuncPermissionKeyConstant.DATASOURCE_TEST_CONNECT, userId);
218+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
211219
return DataSourceClientFactory.getDataSourceClient()
212220
.checkDataSourceConnectivity(pluginName, datasourceConfig);
213221
}
@@ -227,6 +235,7 @@ public boolean testDatasourceConnectionAble(Integer userId, Long datasourceId) {
227235
String configJson = datasource.getDatasourceConfig();
228236
Map<String, String> datasourceConfig =
229237
JsonUtils.toMap(configJson, String.class, String.class);
238+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
230239
String pluginName = datasource.getPluginName();
231240
return DataSourceClientFactory.getDataSourceClient()
232241
.checkDataSourceConnectivity(pluginName, datasourceConfig);
@@ -276,6 +285,7 @@ public List<String> queryDatabaseByDatasourceName(String datasourceName) {
276285
Map<String, String> datasourceConfig =
277286
JsonUtils.toMap(config, String.class, String.class);
278287

288+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
279289
return DataSourceClientFactory.getDataSourceClient()
280290
.getDatabases(pluginName, datasourceConfig);
281291
}
@@ -435,6 +445,7 @@ public PageInfo<DatasourceRes> queryDatasourceList(
435445
datasource.getDatasourceConfig(),
436446
String.class,
437447
String.class);
448+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
438449
datasourceRes.setDatasourceConfig(datasourceConfig);
439450
datasourceRes.setCreateUserId(datasource.getCreateUserId());
440451
datasourceRes.setUpdateUserId(datasource.getUpdateUserId());
@@ -504,7 +515,10 @@ public Map<String, String> queryDatasourceConfigById(String datasourceId) {
504515
throw new SeatunnelException(SeatunnelErrorEnum.DATASOURCE_NOT_FOUND, datasourceId);
505516
}
506517
String configJson = datasource.getDatasourceConfig();
507-
return JsonUtils.toMap(configJson, String.class, String.class);
518+
Map<String, String> datasourceConfig =
519+
JsonUtils.toMap(configJson, String.class, String.class);
520+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
521+
return datasourceConfig;
508522
}
509523

510524
@Override
@@ -579,6 +593,7 @@ private List<DatasourceDetailRes> convertDatasourceDetailRes(List<Datasource> da
579593
datasourceDetailRes.setCreateTime(datasource.getCreateTime());
580594
datasourceDetailRes.setUpdateTime(datasource.getUpdateTime());
581595
Map<String, String> config = JsonUtils.toMap(datasource.getDatasourceConfig());
596+
ConfigShadeUtil.decryptData(config, datasourceEncryptionType);
582597
datasourceDetailRes.setDatasourceConfig(config);
583598
datasourceDetailResList.add(datasourceDetailRes);
584599
});
@@ -610,6 +625,7 @@ public DatasourceDetailRes queryDatasourceDetailByDatasourceName(String datasour
610625

611626
Map<String, String> datasourceConfig =
612627
JsonUtils.toMap(datasource.getDatasourceConfig(), String.class, String.class);
628+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
613629
// convert option rule
614630
datasourceDetailRes.setDatasourceConfig(datasourceConfig);
615631

@@ -635,6 +651,7 @@ public DatasourceDetailRes queryDatasourceDetailById(String datasourceId) {
635651

636652
Map<String, String> datasourceConfig =
637653
JsonUtils.toMap(datasource.getDatasourceConfig(), String.class, String.class);
654+
ConfigShadeUtil.decryptData(datasourceConfig, datasourceEncryptionType);
638655
// convert option rule
639656
datasourceDetailRes.setDatasourceConfig(datasourceConfig);
640657

seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/JobInstanceServiceImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.seatunnel.app.service.impl;
1919

20+
import org.apache.seatunnel.app.utils.ConfigShadeUtil;
2021
import org.apache.seatunnel.shade.com.fasterxml.jackson.core.type.TypeReference;
2122
import org.apache.seatunnel.shade.com.typesafe.config.Config;
2223
import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
@@ -70,6 +71,7 @@
7071
import org.apache.commons.collections4.CollectionUtils;
7172
import org.apache.commons.lang3.StringUtils;
7273

74+
import org.springframework.beans.factory.annotation.Value;
7375
import org.springframework.stereotype.Service;
7476

7577
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -123,6 +125,9 @@ public class JobInstanceServiceImpl extends SeatunnelBaseServiceImpl
123125

124126
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
125127

128+
@Value("${datasource.encryption.type:default}")
129+
private String datasourceEncryptionType;
130+
126131
@Override
127132
public JobExecutorRes createExecuteResource(
128133
@NonNull Integer userId, @NonNull Long jobDefineId) {
@@ -324,6 +329,7 @@ public String generateJobConfig(
324329
.setJson(false)
325330
.setComments(false)
326331
.setOriginComments(false));
332+
env = env + "\"shade.identifier\"=" + datasourceEncryptionType + "\n";
327333
return SeaTunnelConfigUtil.generateConfig(env, sources, transforms, sinks);
328334
}
329335

@@ -606,6 +612,7 @@ private Config parseConfigWithOptionRule(
606612
String connectorType,
607613
Map<String, String> config,
608614
OptionRule optionRule) {
615+
ConfigShadeUtil.encryptData(config, datasourceEncryptionType);
609616
return parseConfigWithOptionRule(
610617
pluginType, connectorType, ConfigFactory.parseMap(config), optionRule);
611618
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.apache.seatunnel.app.utils;
2+
3+
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.apache.seatunnel.app.common.Constants;
6+
import org.apache.seatunnel.core.starter.utils.ConfigShadeUtils;
7+
8+
import java.util.Map;
9+
10+
@Slf4j
11+
public class ConfigShadeUtil {
12+
13+
public static void encryptData(Map<String, String> datasourceConfig, String datasourceEncryptionType) {
14+
String password = datasourceConfig.get(Constants.PASSWORD);
15+
if(!password.isEmpty()) {
16+
try {
17+
datasourceConfig.replace(
18+
Constants.PASSWORD,
19+
ConfigShadeUtils.encryptOption(
20+
datasourceEncryptionType, password));
21+
} catch (IllegalArgumentException ex) {
22+
log.warn("encrypt password failed");
23+
}
24+
}
25+
}
26+
27+
public static void decryptData(Map<String, String> datasourceConfig, String datasourceEncryptionType) {
28+
String password = datasourceConfig.get(Constants.PASSWORD);
29+
if(!password.isEmpty()) {
30+
try {
31+
datasourceConfig.replace(
32+
Constants.PASSWORD,
33+
ConfigShadeUtils.decryptOption(
34+
datasourceEncryptionType, password));
35+
} catch (IllegalArgumentException ex) {
36+
log.warn("decrypt password failed as password is not encrypted");
37+
}
38+
}
39+
}
40+
41+
42+
}

seatunnel-server/seatunnel-app/src/main/resources/application.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ jwt:
3838
secretKey:
3939
algorithm: HS256
4040

41+
datasource:
42+
encryption:
43+
type: base64
44+
4145
---
4246
spring:
4347
config:

0 commit comments

Comments
 (0)