feat(数据源): 数据源敏感信息加密

This commit is contained in:
taojinlong 2022-12-12 17:17:55 +08:00
parent 833a86ba10
commit 214c5f1a84
7 changed files with 44 additions and 16 deletions

View File

@ -19,7 +19,6 @@ import io.dataease.plugins.common.base.domain.Datasource;
import io.dataease.service.datasource.DatasourceService; import io.dataease.service.datasource.DatasourceService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;

View File

@ -19,6 +19,7 @@ public class DatasourceDTO extends Datasource {
@ApiModelProperty("权限") @ApiModelProperty("权限")
private String privileges; private String privileges;
private List<ApiDefinition> apiConfiguration; private List<ApiDefinition> apiConfiguration;
private String apiConfigurationStr;
private String typeDesc; private String typeDesc;
private DatasourceCalculationMode calculationMode; private DatasourceCalculationMode calculationMode;
} }

View File

@ -1014,7 +1014,7 @@ public class ChartDataBuild {
if (StringUtils.isEmpty(originStr) || originStr.length() <= columnPermissionItem.getDesensitizationRule().getM() + columnPermissionItem.getDesensitizationRule().getN() + 1) { if (StringUtils.isEmpty(originStr) || originStr.length() <= columnPermissionItem.getDesensitizationRule().getM() + columnPermissionItem.getDesensitizationRule().getN() + 1) {
desensitizationStr = String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getM(), "X")) + "***" + String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getN(), "X")); desensitizationStr = String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getM(), "X")) + "***" + String.join("", Collections.nCopies(columnPermissionItem.getDesensitizationRule().getN(), "X"));
} else { } else {
desensitizationStr = StringUtils.substring(originStr, 0, columnPermissionItem.getDesensitizationRule().getM() - 1) + "***" + StringUtils.substring(originStr, originStr.length() - columnPermissionItem.getDesensitizationRule().getN(), originStr.length() - 1); desensitizationStr = StringUtils.substring(originStr, 0, columnPermissionItem.getDesensitizationRule().getM()) + "***" + StringUtils.substring(originStr, originStr.length() - columnPermissionItem.getDesensitizationRule().getN() - 1, originStr.length() - 1);
} }
break; break;
case RetainMToN: case RetainMToN:

View File

@ -108,7 +108,7 @@ public class DatasourceService {
if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(datasource.getType())) { if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(datasource.getType())) {
throw new Exception("Datasource type not supported."); throw new Exception("Datasource type not supported.");
} }
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType()); Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType());
datasourceProvider.checkConfiguration(datasource); datasourceProvider.checkConfiguration(datasource);
@ -212,6 +212,14 @@ public class DatasourceService {
} }
} }
} }
if(StringUtils.isNotEmpty(datasourceDTO.getConfiguration())){
datasourceDTO.setConfiguration(new String(java.util.Base64.getEncoder().encode(datasourceDTO.getConfiguration().getBytes())));
}
if(CollectionUtils.isNotEmpty(datasourceDTO.getApiConfiguration())){
String config = new Gson().toJson(datasourceDTO.getApiConfiguration());
datasourceDTO.setApiConfigurationStr(new String(java.util.Base64.getEncoder().encode(config.getBytes())));
datasourceDTO.setApiConfiguration(null);
}
} }
public DatasourceDTO getDataSourceDetails(String datasourceId){ public DatasourceDTO getDataSourceDetails(String datasourceId){
@ -253,6 +261,7 @@ public class DatasourceService {
if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(updataDsRequest.getType())) { if (!types().stream().map(DataSourceType::getType).collect(Collectors.toList()).contains(updataDsRequest.getType())) {
throw new Exception("Datasource type not supported."); throw new Exception("Datasource type not supported.");
} }
updataDsRequest.setConfiguration(new String(java.util.Base64.getDecoder().decode(updataDsRequest.getConfiguration())));
checkName(updataDsRequest.getName(), updataDsRequest.getType(), updataDsRequest.getId()); checkName(updataDsRequest.getName(), updataDsRequest.getType(), updataDsRequest.getId());
Datasource datasource = new Datasource(); Datasource datasource = new Datasource();
datasource.setName(updataDsRequest.getName()); datasource.setName(updataDsRequest.getName());
@ -284,6 +293,7 @@ public class DatasourceService {
} }
public ResultHolder validate(Datasource datasource) throws Exception { public ResultHolder validate(Datasource datasource) throws Exception {
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
DatasourceDTO datasourceDTO = new DatasourceDTO(); DatasourceDTO datasourceDTO = new DatasourceDTO();
BeanUtils.copyBean(datasourceDTO, datasource); BeanUtils.copyBean(datasourceDTO, datasource);
try { try {
@ -372,6 +382,7 @@ public class DatasourceService {
} }
public List<String> getSchema(Datasource datasource) throws Exception { public List<String> getSchema(Datasource datasource) throws Exception {
datasource.setConfiguration(new String(java.util.Base64.getDecoder().decode(datasource.getConfiguration())));
Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType()); Provider datasourceProvider = ProviderFactory.getProvider(datasource.getType());
DatasourceRequest datasourceRequest = new DatasourceRequest(); DatasourceRequest datasourceRequest = new DatasourceRequest();
datasourceRequest.setDatasource(datasource); datasourceRequest.setDatasource(datasource);

View File

@ -216,6 +216,7 @@ import PluginCom from '@/views/system/plugin/PluginCom'
import { groupTree, appApply } from '@/api/panel/panel' import { groupTree, appApply } from '@/api/panel/panel'
import { dsGroupTree } from '@/api/dataset/dataset' import { dsGroupTree } from '@/api/dataset/dataset'
import { deepCopy } from '@/components/canvas/utils/utils' import { deepCopy } from '@/components/canvas/utils/utils'
import { Base64 } from 'js-base64'
export default { export default {
name: 'DsForm', name: 'DsForm',
components: { components: {
@ -707,9 +708,9 @@ export default {
if (valid) { if (valid) {
const data = JSON.parse(JSON.stringify(this.form)) const data = JSON.parse(JSON.stringify(this.form))
if (data.type === 'api') { if (data.type === 'api') {
data.configuration = JSON.stringify(data.apiConfiguration) data.configuration = Base64.encode(JSON.stringify(data.apiConfiguration))
} else { } else {
data.configuration = JSON.stringify(data.configuration) data.configuration = Base64.encode(JSON.stringify(data.configuration))
} }
if (data.showModel === 'show' && !this.canEdit) { if (data.showModel === 'show' && !this.canEdit) {
validateDsById(data.id).then(res => { validateDsById(data.id).then(res => {

View File

@ -226,10 +226,7 @@
>{{ $t('commons.cancel') }} >{{ $t('commons.cancel') }}
</deBtn> </deBtn>
<deBtn <deBtn
v-if=" v-if="formType === 'add' || hasDataPermission('manage', params.privileges)"
formType === 'add' ||
hasDataPermission('manage', params.privileges)
"
secondary secondary
@click="validaDatasource" @click="validaDatasource"
>{{ $t('commons.validate') }} >{{ $t('commons.validate') }}
@ -307,6 +304,7 @@ import { dsGroupTree } from '@/api/dataset/dataset'
import { appApply, appEdit, groupTree } from '@/api/panel/panel' import { appApply, appEdit, groupTree } from '@/api/panel/panel'
import { deepCopy } from '@/components/canvas/utils/utils' import { deepCopy } from '@/components/canvas/utils/utils'
import { hasDataPermission } from '@/utils/permission' import { hasDataPermission } from '@/utils/permission'
import { Base64 } from 'js-base64'
export default { export default {
name: 'DsForm', name: 'DsForm',
@ -710,6 +708,12 @@ export default {
getDatasourceDetail(id, showModel) { getDatasourceDetail(id, showModel) {
this.$emit('update:formLoading', true) this.$emit('update:formLoading', true)
return getDatasourceDetail(id).then((res) => { return getDatasourceDetail(id).then((res) => {
if(res.data.configuration){
res.data.configuration = Base64.decode(res.data.configuration)
}
if(res.data.apiConfigurationStr){
res.data.apiConfiguration = JSON.parse(Base64.decode(res.data.apiConfigurationStr))
}
this.params = { ...res.data, showModel } this.params = { ...res.data, showModel }
this.$emit('setParams', { ...this.params }) this.$emit('setParams', { ...this.params })
}).finally(() => { }).finally(() => {
@ -729,6 +733,12 @@ export default {
const newArr = [] const newArr = []
for (let index = 0; index < array.length; index++) { for (let index = 0; index < array.length; index++) {
const element = array[index] const element = array[index]
if(element.configuration){
element.configuration = Base64.decode(element.configuration)
}
if(element.apiConfigurationStr){
element.apiConfiguration = Base64.decode(element.apiConfigurationStr)
}
if (this.msgNodeId) { if (this.msgNodeId) {
if (element.id === this.msgNodeId) { if (element.id === this.msgNodeId) {
element.msgNode = true element.msgNode = true
@ -967,9 +977,9 @@ export default {
form.apiConfiguration.forEach((item) => { form.apiConfiguration.forEach((item) => {
delete item.status delete item.status
}) })
form.configuration = JSON.stringify(form.apiConfiguration) form.configuration = Base64.encode(JSON.stringify(form.apiConfiguration))
} else { } else {
form.configuration = JSON.stringify(form.configuration) form.configuration = Base64.encode(JSON.stringify(form.configuration))
} }
const isAppMarket = this.positionCheck('appMarket') const isAppMarket = this.positionCheck('appMarket')
let appApplyForm let appApplyForm
@ -1051,7 +1061,7 @@ export default {
this.$refs.dsForm.validate((valid) => { this.$refs.dsForm.validate((valid) => {
if (valid) { if (valid) {
const data = JSON.parse(JSON.stringify(this.form)) const data = JSON.parse(JSON.stringify(this.form))
data.configuration = JSON.stringify(data.configuration) data.configuration = Base64.encode(JSON.stringify(data.configuration))
getSchema(data).then((res) => { getSchema(data).then((res) => {
this.schemas = res.data this.schemas = res.data
this.openMessageSuccess('commons.success') this.openMessageSuccess('commons.success')
@ -1102,9 +1112,9 @@ export default {
if (valid) { if (valid) {
const data = JSON.parse(JSON.stringify(this.form)) const data = JSON.parse(JSON.stringify(this.form))
if (data.type === 'api') { if (data.type === 'api') {
data.configuration = JSON.stringify(data.apiConfiguration) data.configuration = Base64.encode(JSON.stringify(data.apiConfiguration))
} else { } else {
data.configuration = JSON.stringify(data.configuration) data.configuration = Base64.encode(JSON.stringify(data.configuration))
} }
if (data.showModel === 'show' && !this.canEdit) { if (data.showModel === 'show' && !this.canEdit) {
validateDsById(data.id).then((res) => { validateDsById(data.id).then((res) => {

View File

@ -316,6 +316,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import i18n from '@/lang' import i18n from '@/lang'
import { Base64 } from 'js-base64'
import { import {
listDatasource, listDatasource,
listDatasourceByType, listDatasourceByType,
@ -502,8 +503,7 @@ export default {
}) })
}, },
refreshType(datasource) { refreshType(datasource) {
const method = const method = this.showView === 'Datasource' ? listDatasourceByType : listDriverByType
this.showView === 'Datasource' ? listDatasourceByType : listDriverByType
let typeData = [] let typeData = []
method(datasource.type).then((res) => { method(datasource.type).then((res) => {
typeData = this.buildTree(res.data) typeData = this.buildTree(res.data)
@ -538,6 +538,12 @@ export default {
const newArr = [] const newArr = []
for (let index = 0; index < array.length; index++) { for (let index = 0; index < array.length; index++) {
const element = array[index] const element = array[index]
if(element.configuration){
element.configuration = Base64.decode(element.configuration)
}
if(element.apiConfigurationStr){
element.apiConfiguration = JSON.parse(Base64.decode(element.apiConfigurationStr))
}
if (this.msgNodeId) { if (this.msgNodeId) {
if (element.id === this.msgNodeId) { if (element.id === this.msgNodeId) {
element.msgNode = true element.msgNode = true