fix: 日志列表接口sql-inject

This commit is contained in:
fit2cloud-chenyw 2023-09-11 13:45:11 +08:00
parent 6ca92d239a
commit 7fa8c53718
7 changed files with 102 additions and 190 deletions

View File

@ -7,7 +7,7 @@ import io.dataease.auth.annotation.SqlInjectValidator;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.handler.annotation.I18n;
import io.dataease.controller.sys.request.KeyGridRequest;
import io.dataease.controller.sys.request.LogGridRequest;
import io.dataease.dto.SysLogGridDTO;
import io.dataease.dto.log.FolderItem;
import io.dataease.service.sys.log.LogService;
@ -39,8 +39,7 @@ public class SysLogController {
})
@SqlInjectValidator(value = {"time"})
public Pager<List<SysLogGridDTO>> logGrid(@PathVariable int goPage, @PathVariable int pageSize,
@RequestBody KeyGridRequest request) {
request = logService.logRetentionProxy(request);
@RequestBody LogGridRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
return PageUtils.setPageInfo(page, logService.query(request));
}
@ -54,7 +53,7 @@ public class SysLogController {
@ApiOperation("导出操作日志")
@PostMapping("/export")
@ApiImplicitParam(name = "request", value = "查询条件", required = true)
public void export(@RequestBody KeyGridRequest request) throws Exception {
public void export(@RequestBody LogGridRequest request) throws Exception {
logService.exportExcel(request);
}
}

View File

@ -0,0 +1,16 @@
package io.dataease.controller.sys.request;
import io.dataease.plugins.common.request.KeywordRequest;
import lombok.Data;
import java.util.List;
@Data
public class LogGridRequest extends KeywordRequest {
private List<String> optypeList;
private List<Long> userIdList;
private Long[] timeList;
}

View File

@ -1,16 +1,15 @@
package io.dataease.ext;
import io.dataease.controller.sys.request.LogGridRequest;
import io.dataease.dto.log.FolderItem;
import io.dataease.ext.query.GridExample;
import io.dataease.plugins.common.base.domain.SysLogWithBLOBs;
import io.dataease.service.sys.log.LogQueryParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtSysLogMapper {
List<SysLogWithBLOBs> query(LogQueryParam example);
List<SysLogWithBLOBs> query(LogGridRequest request);
List<FolderItem> idAndName(@Param("ids") List<String> ids, @Param("type") Integer type);
}

View File

@ -3,51 +3,59 @@
<mapper namespace="io.dataease.ext.ExtSysLogMapper">
<select id="query" parameterType="io.dataease.service.sys.log.LogQueryParam" resultMap="io.dataease.plugins.common.base.mapper.SysLogMapper.ResultMapWithBLOBs">
<select id="query" parameterType="io.dataease.controller.sys.request.LogGridRequest"
resultMap="io.dataease.plugins.common.base.mapper.SysLogMapper.ResultMapWithBLOBs">
select * from
(select * from sys_log where 1 = 1
<if test="extendCondition != null">
and
(
nick_name like concat('%', #{extendCondition} , '%')
or
source_name like concat('%', #{extendCondition} , '%')
or
position like concat('%', #{extendCondition} , '%')
<if test="unionIds != null">
or
concat(operate_type, '-', source_type) in
<foreach collection="unionIds" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</if>
)
</if>
) t
(select * from sys_log where 1 = 1
<if test="keyword != null">
and
(
nick_name like concat('%', #{keyword} , '%')
or
source_name like concat('%', #{keyword} , '%')
or
position like concat('%', #{keyword} , '%')
)
</if>
) t
where 1 = 1
<if test="optypeList != null and optypeList.size() > 0">
and concat(operate_type, '-', source_type) in
<foreach collection="optypeList" item="operate" open='(' separator=',' close=')'>
#{operate}
</foreach>
</if>
<if test="userIdList != null and userIdList.size() > 0">
and user_id in
<foreach collection="userIdList" item="userId" open='(' separator=',' close=')'>
#{userId}
</foreach>
</if>
<if test="timeList != null and timeList.length > 1">
and (time between #{timeList.[0]} and #{timeList.[1]})
</if>
<if test="_parameter != null">
<include refid="io.dataease.ext.query.GridSql.gridCondition" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
<if test="orderByClause == null">
order by time desc
</if>
<choose>
<when test="orders!=null and orders.size > 0">
order by
<foreach collection="orders" item="item" open='' separator=',' close=''>
${item}
</foreach>
</when>
<otherwise>
order by time desc
</otherwise>
</choose>
</select>
<select id="idAndName" resultType="io.dataease.dto.log.FolderItem" >
<select id="idAndName" resultType="io.dataease.dto.log.FolderItem">
select
<if test="type == 1">
id, name
from datasource
<where>
id in
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
@ -57,23 +65,23 @@
<if test="type == 2">
id, name
from (
select id, name from dataset_group
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
select id, name from dataset_group
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
union all
union all
select id, name from dataset_table
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
select id, name from dataset_table
<where>
id in
<foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
#{id}
</foreach>
</where>
) dataset
@ -175,9 +183,9 @@
<if test="type == 11">
menu_id as id ,title as name
from (
select menu_id, title from sys_menu
union all
select menu_id, title from plugin_sys_menu
select menu_id, title from sys_menu
union all
select menu_id, title from plugin_sys_menu
) plugin_union
<where>
menu_id in

View File

@ -2,7 +2,6 @@ package io.dataease.service.sys.log;
import cn.hutool.core.date.DateUtil;
import com.google.gson.Gson;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.constants.ParamConstants;
@ -11,14 +10,12 @@ import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.IPUtils;
import io.dataease.commons.utils.ServletUtils;
import io.dataease.controller.sys.base.ConditionEntity;
import io.dataease.controller.sys.request.KeyGridRequest;
import io.dataease.controller.sys.request.LogGridRequest;
import io.dataease.dto.SysLogDTO;
import io.dataease.dto.SysLogGridDTO;
import io.dataease.dto.log.FolderItem;
import io.dataease.exception.DataEaseException;
import io.dataease.ext.ExtSysLogMapper;
import io.dataease.ext.query.GridExample;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.SysLogExample;
import io.dataease.plugins.common.base.domain.SysLogWithBLOBs;
@ -35,7 +32,10 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Service
@ -95,100 +95,10 @@ public class LogService {
}
public KeyGridRequest logRetentionProxy(KeyGridRequest request) {
String value = systemParameterService.getValue(ParamConstants.BASIC.LOG_TIME_OUT.getValue());
value = StringUtils.isBlank(value) ? LOG_RETENTION : value;
int logRetention = Integer.parseInt(value);
Calendar instance = Calendar.getInstance();
public List<SysLogGridDTO> query(LogGridRequest request) {
Calendar startInstance = (Calendar) instance.clone();
startInstance.add(Calendar.DATE, -logRetention);
startInstance.set(Calendar.HOUR_OF_DAY, 0);
startInstance.set(Calendar.MINUTE, 0);
startInstance.set(Calendar.SECOND, 0);
long startTime = startInstance.getTimeInMillis();
Calendar endInstance = (Calendar) instance.clone();
endInstance.add(Calendar.DATE, 1);
endInstance.set(Calendar.HOUR_OF_DAY, 0);
endInstance.set(Calendar.MINUTE, 0);
endInstance.set(Calendar.SECOND, 0);
long endTime = endInstance.getTimeInMillis();
List<ConditionEntity> conditions = request.getConditions();
if (CollectionUtils.isNotEmpty(conditions) && conditions.stream().anyMatch(condition -> StringUtils.equals("time", condition.getField()))) {
conditions.forEach(condition -> {
if (StringUtils.equals("time", condition.getField()) && startTime > ((List<Long>) condition.getValue()).get(0)) {
((List<Long>) condition.getValue()).set(0, startTime);
}
});
} else {
ConditionEntity conditionEntity = new ConditionEntity();
conditionEntity.setField("time");
conditionEntity.setOperator("between");
List<Long> times = new ArrayList<>();
times.add(startTime);
times.add(endTime);
conditionEntity.setValue(times);
conditions.add(conditionEntity);
}
return request;
}
public List<SysLogGridDTO> query(KeyGridRequest request) {
request = detailRequest(request);
String keyWord = request.getKeyWord();
List<String> ids = null;
GridExample gridExample = request.convertExample();
gridExample.setExtendCondition(keyWord);
LogQueryParam logQueryParam = gson.fromJson(gson.toJson(gridExample), LogQueryParam.class);
if (StringUtils.isNotBlank(keyWord)) {
List<FolderItem> types = types();
ids = types.stream().filter(item -> item.getName().toLowerCase().contains(keyWord.toLowerCase())).map(FolderItem::getId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(ids))
logQueryParam.setUnionIds(ids);
}
List<SysLogWithBLOBs> voLogs = extSysLogMapper.query(logQueryParam);
List<SysLogGridDTO> dtos = voLogs.stream().map(this::convertDTO).collect(Collectors.toList());
return dtos;
}
private KeyGridRequest detailRequest(KeyGridRequest request) {
List<ConditionEntity> conditions = request.getConditions();
if (CollectionUtils.isNotEmpty(conditions)) {
ConditionEntity uninCondition = null;
int matchIndex = -1;
for (int i = 0; i < conditions.size(); i++) {
ConditionEntity conditionEntity = conditions.get(i);
String field = conditionEntity.getField();
Object value = conditionEntity.getValue();
if (StringUtils.isNotBlank(field) && StringUtils.equals("optype", field) && ObjectUtils.isNotEmpty(value)) {
matchIndex = i;
uninCondition = new ConditionEntity();
List<String> values = (List<String>) value;
uninCondition.setField("concat(operate_type, '-de-', source_type)");
List<String> uninValue = values.stream().map(v -> v.replace("-", "-de-")).collect(Collectors.toList());
uninCondition.setValue(uninValue);
uninCondition.setOperator(conditionEntity.getOperator());
}
}
if (matchIndex >= 0) {
conditions.remove(matchIndex);
if (ObjectUtils.isNotEmpty(uninCondition)) conditions.add(uninCondition);
}
}
return request;
List<SysLogWithBLOBs> voLogs = extSysLogMapper.query(request);
return voLogs.stream().map(this::convertDTO).collect(Collectors.toList());
}
@ -350,24 +260,12 @@ public class LogService {
}
public void exportExcel(KeyGridRequest request) throws Exception {
request = logRetentionProxy(request);
request = detailRequest(request);
String keyWord = request.getKeyWord();
List<String> ids = null;
public void exportExcel(LogGridRequest request) throws Exception {
HttpServletResponse response = ServletUtils.response();
OutputStream outputStream = response.getOutputStream();
try {
GridExample gridExample = request.convertExample();
gridExample.setExtendCondition(keyWord);
LogQueryParam logQueryParam = gson.fromJson(gson.toJson(gridExample), LogQueryParam.class);
if (StringUtils.isNotBlank(keyWord)) {
List<FolderItem> types = types();
ids = types.stream().filter(item -> item.getName().toLowerCase().contains(keyWord.toLowerCase())).map(FolderItem::getId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(ids))
logQueryParam.setUnionIds(ids);
}
List<SysLogWithBLOBs> lists = extSysLogMapper.query(logQueryParam);
List<SysLogWithBLOBs> lists = extSysLogMapper.query(request);
List<String[]> details = lists.stream().map(item -> {
String operateTypeName = SysLogConstants.operateTypeName(item.getOperateType());
String sourceTypeName = SysLogConstants.sourceTypeName(item.getSourceType());

View File

@ -208,8 +208,8 @@ export default {
},
formatCondition() {
const fildMap = {
optype: this.activeType,
'user_id': this.activeUser
optypeList: this.activeType,
userIdList: this.activeUser
}
const conditions = []
Object.keys(fildMap).forEach((ele) => {
@ -228,7 +228,7 @@ export default {
max = +max + 24 * 3600 * 1000
}
conditions.push({
field: 'time',
field: 'timeList',
operator: 'between',
value: [+min, +max]
})

View File

@ -146,6 +146,7 @@ import GridTable from '@/components/gridTable/index.vue'
import filterUser from './FilterUser'
import _ from 'lodash'
import keyEnter from '@/components/msgCfm/keyEnter.js'
import { buildParam } from '@/utils/GridConditionUtil'
import {
addOrder,
formatOrders
@ -197,13 +198,8 @@ export default {
})
},
exportData() {
const param = {
orders: formatOrders(this.orderConditions),
conditions: [...this.cacheCondition]
}
if (this.nickName) {
param.keyWord = this.nickName
}
const param = buildParam(this.cacheCondition, this.nickName)
param.orders = formatOrders(this.orderConditions)
exportExcel(param).then((res) => {
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
@ -289,13 +285,9 @@ export default {
this.$refs.filterUser.init()
},
search() {
const param = {
orders: formatOrders(this.orderConditions),
conditions: [...this.cacheCondition]
}
if (this.nickName) {
param.keyWord = this.nickName
}
const param = buildParam(this.cacheCondition, this.nickName)
param.orders = formatOrders(this.orderConditions)
const { currentPage, pageSize } = this.paginationConfig
logGrid(currentPage, pageSize, param).then((response) => {
this.data = response.data.listObject