fix: 分享组织备选项接口sql-inject

This commit is contained in:
fit2cloud-chenyw 2023-09-11 18:07:09 +08:00
parent 5dd5c3b31b
commit f2df9b655e
9 changed files with 72 additions and 113 deletions

View File

@ -2,16 +2,14 @@ package io.dataease.controller.panel.api;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.auth.annotation.DePermission;
import io.dataease.auth.annotation.SqlInjectValidator;
import io.dataease.plugins.common.base.domain.PanelShare;
import io.dataease.commons.constants.DePermissionType;
import io.dataease.controller.request.panel.PanelShareFineDto;
import io.dataease.controller.request.panel.PanelShareRemoveRequest;
import io.dataease.controller.request.panel.PanelShareSearchRequest;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.dto.panel.PanelShareDto;
import io.dataease.dto.panel.PanelShareOutDTO;
import io.dataease.dto.panel.PanelSharePo;
import io.dataease.plugins.common.base.domain.PanelShare;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

View File

@ -3,10 +3,10 @@ package io.dataease.controller.sys;
import io.dataease.auth.annotation.SqlInjectValidator;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.ResultHolder;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.response.DeptNodeResponse;
import io.dataease.controller.sys.response.DeptTreeNode;
import io.dataease.plugins.common.base.domain.SysDept;
import io.dataease.plugins.xpack.dept.dto.request.XpackDeptGridRequest;
import io.dataease.service.sys.DeptService;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
@ -42,7 +42,7 @@ public class SysDeptController extends ResultHolder {
@PostMapping("/search")
@SqlInjectValidator({"name"})
public List<DeptNodeResponse> search(@RequestBody BaseGridRequest request){
public List<DeptNodeResponse> search(@RequestBody XpackDeptGridRequest request){
List<SysDept> nodes = deptService.nodesTreeByCondition(request);
List<DeptNodeResponse> nodeResponses = nodes.stream().map(node -> {
DeptNodeResponse deptNodeResponse = BeanUtils.copyBean(new DeptNodeResponse(), node);

View File

@ -1,15 +1,12 @@
package io.dataease.controller.sys;
import io.dataease.plugins.common.base.domain.SysMenu;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.handler.annotation.I18n;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.MenuCreateRequest;
import io.dataease.controller.sys.request.MenuDeleteRequest;
import io.dataease.controller.sys.response.MenuNodeResponse;
import io.dataease.controller.sys.response.MenuTreeNode;
import io.dataease.plugins.common.base.domain.SysMenu;
import io.dataease.service.sys.MenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -21,6 +18,7 @@ import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@ApiIgnore
@RestController
@RequiredArgsConstructor
@ -34,61 +32,44 @@ public class SysMenuController {
@ApiOperation("查询跟节点菜单")
@I18n
@PostMapping("/childNodes/{pid}")
public List<MenuNodeResponse> childNodes(@PathVariable("pid") Long pid){
public List<MenuNodeResponse> childNodes(@PathVariable("pid") Long pid) {
List<SysMenu> nodes = menuService.nodesByPid(pid);
nodes = nodes.stream().filter(node -> !node.getHidden()).collect(Collectors.toList());
return menuService.convert(nodes);
}
@ApiOperation("搜索菜单树")
@I18n
@PostMapping("/search")
public List<MenuNodeResponse> search(@RequestBody BaseGridRequest request) {
List<SysMenu> nodes = menuService.nodesTreeByCondition(request);
List<MenuNodeResponse> nodeResponses = nodes.stream().map(node -> {
MenuNodeResponse menuNodeResponse = BeanUtils.copyBean(new MenuNodeResponse(), node);
menuNodeResponse.setHasChildren(node.getSubCount() > 0);
menuNodeResponse.setTop(node.getPid() == menuService.MENU_ROOT_PID);
return menuNodeResponse;
}).collect(Collectors.toList());
return nodeResponses;
}
@ApiOperation("新增菜单")
@PostMapping("/create")
public void create(@RequestBody MenuCreateRequest request){
public void create(@RequestBody MenuCreateRequest request) {
menuService.add(request);
}
@ApiOperation("删除菜单")
@PostMapping("/delete")
public void delete(@RequestBody MenuDeleteRequest request){
public void delete(@RequestBody MenuDeleteRequest request) {
menuService.delete(request);
}
@ApiOperation("更新菜单")
@PostMapping("/update")
public void update(@RequestBody MenuCreateRequest menu){
public void update(@RequestBody MenuCreateRequest menu) {
menuService.update(menu);
}
@PostMapping("/childMenus/{pid}")
public Set<Long> childMenus(@PathVariable Long pid){
public Set<Long> childMenus(@PathVariable Long pid) {
List<MenuNodeResponse> children = menuService.children(pid);
Set<Long> sets = children.stream().map(MenuNodeResponse::getMenuId).collect(Collectors.toSet());
sets.add(pid);
return sets;
}
@PostMapping("/nodesByMenuId/{menuId}")
public List<MenuTreeNode> nodesByMenuId(@PathVariable("menuId") Long menuId) {
return menuService.searchTree(menuId);
return menuService.searchTree(menuId);
}
}

View File

@ -1,10 +1,13 @@
package io.dataease.ext;
import io.dataease.ext.query.GridExample;
import io.dataease.controller.request.BaseTreeRequest;
import io.dataease.controller.sys.request.SimpleTreeNode;
import io.dataease.dto.SysDeptDTO;
import org.apache.ibatis.annotations.*;
import io.dataease.plugins.xpack.dept.dto.request.XpackDeptGridRequest;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.util.List;
@ -27,7 +30,7 @@ public interface ExtDeptMapper {
List<SimpleTreeNode> allNodes();
List<SimpleTreeNode> nodesByExample(GridExample example);
List<SimpleTreeNode> nodesByExample(XpackDeptGridRequest request);
List<SysDeptDTO> searchTree(BaseTreeRequest request);

View File

@ -13,8 +13,13 @@
<select id="nodesByExample" parameterType="io.dataease.ext.query.GridExample" resultMap="simpleNode">
select dept_id as id, pid from sys_dept
<include refid="io.dataease.ext.query.GridSql.gridCondition" />
select dept_id as id, pid from sys_dept where 1=1
<if test="pid != null">
and pid = #{pid}
</if>
<if test="keyword != null">
and name like concat('%', #{keyword}, '%')
</if>
</select>

View File

@ -1,23 +1,25 @@
package io.dataease.service.sys;
import io.dataease.ext.*;
import io.dataease.ext.query.GridExample;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.DeptCreateRequest;
import io.dataease.controller.sys.request.DeptDeleteRequest;
import io.dataease.controller.sys.request.DeptStatusRequest;
import io.dataease.controller.sys.request.SimpleTreeNode;
import io.dataease.controller.sys.response.DeptTreeNode;
import io.dataease.ext.ExtDeptMapper;
import io.dataease.plugins.common.base.domain.SysDept;
import io.dataease.plugins.common.base.domain.SysDeptExample;
import io.dataease.plugins.common.base.mapper.SysDeptMapper;
import io.dataease.plugins.xpack.dept.dto.request.XpackDeptGridRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
@ -31,12 +33,12 @@ public class DeptService {
@Autowired(required = false)
private ExtDeptMapper extDeptMapper;
public List<SysDept> nodesByPid(Long pid){
public List<SysDept> nodesByPid(Long pid) {
SysDeptExample example = new SysDeptExample();
SysDeptExample.Criteria criteria = example.createCriteria();
if (ObjectUtils.isEmpty(pid)){
if (ObjectUtils.isEmpty(pid)) {
criteria.andPidEqualTo(0L);
}else {
} else {
criteria.andPidEqualTo(pid);
}
example.setOrderByClause("dept_sort");
@ -44,10 +46,10 @@ public class DeptService {
}
@Transactional
public boolean add(DeptCreateRequest deptCreateRequest){
public boolean add(DeptCreateRequest deptCreateRequest) {
SysDept sysDept = BeanUtils.copyBean(new SysDept(), deptCreateRequest);
if (deptCreateRequest.isTop()){
if (deptCreateRequest.isTop()) {
sysDept.setPid(DEPT_ROOT_PID);
}
long now = System.currentTimeMillis();
@ -59,24 +61,24 @@ public class DeptService {
try {
int insert = sysDeptMapper.insert(sysDept);
Long pid;
if (!(pid = sysDept.getPid()).equals(DEPT_ROOT_PID)){
if (!(pid = sysDept.getPid()).equals(DEPT_ROOT_PID)) {
//这里需要更新上级节点SubCount
extDeptMapper.incrementalSubcount(pid);
}
if (insert == 1){
if (insert == 1) {
return true;
}
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Transactional
public int batchDelete(List<DeptDeleteRequest> requests){
public int batchDelete(List<DeptDeleteRequest> requests) {
List<Long> ids = requests.stream().map(request -> {
Long pid = request.getPid();
if (!pid.equals(DEPT_ROOT_PID)){
if (!pid.equals(DEPT_ROOT_PID)) {
extDeptMapper.decreasingSubcount(pid);
}
return request.getDeptId();
@ -85,9 +87,9 @@ public class DeptService {
}
@Transactional
public int update(DeptCreateRequest deptCreateRequest){
public int update(DeptCreateRequest deptCreateRequest) {
SysDept sysDept = BeanUtils.copyBean(new SysDept(), deptCreateRequest);
if (deptCreateRequest.isTop()){
if (deptCreateRequest.isTop()) {
sysDept.setPid(DEPT_ROOT_PID);
}
sysDept.setUpdateTime(System.currentTimeMillis());
@ -97,34 +99,34 @@ public class DeptService {
//如果PID发生了改变
//判断oldPid是否是跟节点PID nothing : parent.subcount-1
//判断newPid是否是跟节点PID nothing : parent.subcount+1
if (!sysDept.getPid().equals(dept_old.getPid())){
if (!sysDept.getPid().equals(dept_old.getPid())) {
Long oldPid = dept_old.getPid();
if (!oldPid.equals(DEPT_ROOT_PID)){
if (!oldPid.equals(DEPT_ROOT_PID)) {
extDeptMapper.decreasingSubcount(oldPid);
}
if (!sysDept.getPid().equals(DEPT_ROOT_PID)){
if (!sysDept.getPid().equals(DEPT_ROOT_PID)) {
extDeptMapper.incrementalSubcount(sysDept.getPid());
}
}
return sysDeptMapper.updateByPrimaryKeySelective(sysDept);
}
public int updateStatus(DeptStatusRequest request){
public int updateStatus(DeptStatusRequest request) {
Long deptId = request.getDeptId();
SysDept sysDept = new SysDept();
sysDept.setDeptId(deptId);
return sysDeptMapper.updateByPrimaryKeySelective(sysDept);
}
public List<SysDept> nodesTreeByCondition(BaseGridRequest request){
public List<SysDept> nodesTreeByCondition(XpackDeptGridRequest request) {
List<SimpleTreeNode> allNodes = allNodes();
List<SimpleTreeNode> targetNodes = nodeByCondition(request);
if(CollectionUtils.isEmpty(targetNodes)){
if (CollectionUtils.isEmpty(targetNodes)) {
return new ArrayList<>();
}
List<Long> ids = upTree(allNodes, targetNodes);
SysDeptExample example = new SysDeptExample();
if (CollectionUtils.isNotEmpty(ids)){
if (CollectionUtils.isNotEmpty(ids)) {
SysDeptExample.Criteria criteria = example.createCriteria();
criteria.andDeptIdIn(ids);
}
@ -132,14 +134,15 @@ public class DeptService {
return sysDeptMapper.selectByExample(example);
}
public List<DeptTreeNode> searchTree(Long deptId){
public List<DeptTreeNode> searchTree(Long deptId) {
List<SysDept> roots = nodesByPid(0L);
if (deptId.equals(DEPT_ROOT_PID)) return roots.stream().map(this::format).collect(Collectors.toList());
SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
if (roots.stream().anyMatch(node -> node.getDeptId().equals(deptId))) return roots.stream().map(this::format).collect(Collectors.toList());
if (roots.stream().anyMatch(node -> node.getDeptId().equals(deptId)))
return roots.stream().map(this::format).collect(Collectors.toList());
SysDept current = sysDept;
DeptTreeNode currentNode = format(sysDept);
while (!current.getPid().equals(DEPT_ROOT_PID)){
while (!current.getPid().equals(DEPT_ROOT_PID)) {
SysDept parent = sysDeptMapper.selectByPrimaryKey(current.getPid()); //pid上有索引 所以效率不会太差
DeptTreeNode parentNode = format(parent);
parentNode.setChildren(currentNode.toList());
@ -151,7 +154,7 @@ public class DeptService {
return roots.stream().map(node -> node.getDeptId().equals(targetRootNode.getId()) ? targetRootNode : format(node)).collect(Collectors.toList());
}
private DeptTreeNode format(SysDept sysDept){
private DeptTreeNode format(SysDept sysDept) {
DeptTreeNode deptTreeNode = new DeptTreeNode();
deptTreeNode.setId(sysDept.getDeptId());
deptTreeNode.setLabel(sysDept.getName());
@ -159,22 +162,23 @@ public class DeptService {
return deptTreeNode;
}
private List<SimpleTreeNode> allNodes(){
private List<SimpleTreeNode> allNodes() {
return extDeptMapper.allNodes();
}
private List<SimpleTreeNode> nodeByCondition(BaseGridRequest request){
GridExample gridExample = request.convertExample();
return extDeptMapper.nodesByExample(gridExample);
private List<SimpleTreeNode> nodeByCondition(XpackDeptGridRequest request) {
return extDeptMapper.nodesByExample(request);
}
/**
* 找出目标节点所在路径上的所有节点 向上找
* @param allNodes 所有节点
*
* @param allNodes 所有节点
* @param targetNodes 目标节点
* @return
*/
private List<Long> upTree(List<SimpleTreeNode> allNodes, List<SimpleTreeNode> targetNodes){
private List<Long> upTree(List<SimpleTreeNode> allNodes, List<SimpleTreeNode> targetNodes) {
final Map<Long, SimpleTreeNode> map = allNodes.stream().collect(Collectors.toMap(SimpleTreeNode::getId, node -> node));
return targetNodes.parallelStream().flatMap(targetNode -> {
//向上逐级找爹

View File

@ -1,7 +1,6 @@
package io.dataease.service.sys;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.MenuCreateRequest;
import io.dataease.controller.sys.request.MenuDeleteRequest;
import io.dataease.controller.sys.request.SimpleTreeNode;
@ -168,28 +167,10 @@ public class MenuService {
}
public List<SysMenu> nodesTreeByCondition(BaseGridRequest request) {
List<SimpleTreeNode> allNodes = allNodes();
List<SimpleTreeNode> targetNodes = nodeByCondition(request);
if (org.apache.commons.collections.CollectionUtils.isEmpty(targetNodes)) {
return new ArrayList<>();
}
List<Long> ids = upTree(allNodes, targetNodes);
SysMenuExample example = new SysMenuExample();
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(ids)) {
SysMenuExample.Criteria criteria = example.createCriteria();
criteria.andMenuIdIn(ids);
}
return sysMenuMapper.selectByExample(example);
}
public List<SimpleTreeNode> allNodes() {
return extSysMenuMapper.allNodes();
}
public List<SimpleTreeNode> nodeByCondition(BaseGridRequest request) {
return extSysMenuMapper.nodesByExample(request.convertExample());
}
/**
* 找出目标节点所在路径上的所有节点 向上找

View File

@ -53,12 +53,4 @@ export function treeByMenuId(menuId) {
})
}
export function queryCondition(data) {
return request({
url: '/api/menu/search',
method: 'post',
data
})
}
export default { addMenu, editMenu, delMenu, getMenusTree, getChild, treeByMenuId, queryCondition }
export default { addMenu, editMenu, delMenu, getMenusTree, getChild, treeByMenuId }

View File

@ -94,12 +94,7 @@ export default {
searchWithKey(index) {
this.timeMachine = setTimeout(() => {
if (index === this.changeIndex) {
const condition = {
field: 'name',
operator: 'like',
value: this.keyWord
}
this.search(condition)
this.search()
}
this.destroyTimeMachine()
}, 1500)
@ -124,25 +119,25 @@ export default {
},
//
search(condition) {
search() {
this.treeData = []
let param = {}
if (condition && condition.value) {
param = { conditions: [condition] }
if (this.keyWord) {
param = { keyword: this.keyWord }
} else {
param = { conditions: [this.defaultCondition] }
param = { pid: 0 }
}
if (!this.sharesLoad) {
this.queryShareNodeIds(() => {
this.sharesLoad = true
this.loadTreeData(param, condition)
this.loadTreeData(param)
})
} else {
this.loadTreeData(param, condition)
this.loadTreeData(param)
}
},
loadTreeData(param, condition) {
loadTreeData(param) {
loadTable(param).then(res => {
let data = res.data
data = data.map(obj => {
@ -154,7 +149,7 @@ export default {
this.setCheckExpandNodes(data)
this.expandNodeIds = []
if (condition && condition.value) {
if (this.keyWord) {
this.treeData = this.buildTree(data)
this.$nextTick(() => {
this.expandResult(this.treeData)