sql执行器开发,增加权限
This commit is contained in:
@@ -8,7 +8,6 @@ import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.core.util.ThreadLocalUtil;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.service.manage.UserAuthService;
|
||||
import com.zyplayer.doc.data.utils.BeanUtil;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
@@ -19,7 +18,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLEncoder;
|
||||
@@ -29,9 +27,6 @@ import java.util.Map;
|
||||
@Component
|
||||
public class AuthAspect {
|
||||
|
||||
@Resource
|
||||
private UserAuthService userAuthService;
|
||||
|
||||
@Around(value = "@annotation(com.zyplayer.doc.core.annotation.AuthMan) || @within(com.zyplayer.doc.core.annotation.AuthMan)")
|
||||
public Object authController(ProceedingJoinPoint pjp) throws Throwable {
|
||||
AuthMan authMan = BeanUtil.getAnnotation(pjp, AuthMan.class);
|
||||
|
||||
@@ -15,8 +15,8 @@ public class DocUserUtil {
|
||||
DocUserUtil.ACCESS_TOKEN.set(accessToken);
|
||||
}
|
||||
|
||||
public static boolean havePageAuth(String authName, Long pageId) {
|
||||
return haveAuth(authName + pageId);
|
||||
public static boolean haveCustomAuth(String authName, String suffix) {
|
||||
return haveAuth(authName + suffix);
|
||||
}
|
||||
|
||||
public static boolean haveAuth(String... authNames) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.zyplayer.doc.data.repository.support.consts;
|
||||
|
||||
public class DocAuthConst {
|
||||
public static final String DB = "DB_";
|
||||
public static final String WIKI = "WIKI_";
|
||||
|
||||
public static final String DB_DATASOURCE_MANAGE = "DB_DATASOURCE_MANAGE";
|
||||
}
|
||||
@@ -5,12 +5,19 @@ import cn.hutool.core.util.ZipUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.DbDatasourceService;
|
||||
import com.zyplayer.doc.data.service.manage.UserAuthService;
|
||||
import com.zyplayer.doc.db.controller.vo.DatabaseExportVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo.TableInfoVo;
|
||||
import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean.DatabaseProduct;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
@@ -19,6 +26,7 @@ import com.zyplayer.doc.db.framework.db.mapper.base.BaseMapper;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.mysql.MysqlMapper;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -46,11 +54,27 @@ public class DatabaseDocController {
|
||||
DatabaseRegistrationBean databaseRegistrationBean;
|
||||
@Resource
|
||||
DbDatasourceService dbDatasourceService;
|
||||
@Resource
|
||||
UserAuthService userAuthService;
|
||||
|
||||
@PostMapping(value = "/getDataSourceList")
|
||||
public ResponseJson getDataSourceList() {
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("yn", 1);
|
||||
// 没管理权限只返回有权限的数据源
|
||||
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)) {
|
||||
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
|
||||
updateWrapper.likeRight("auth_custom_suffix", DocAuthConst.DB);
|
||||
updateWrapper.eq("del_flag", 0);
|
||||
updateWrapper.eq("user_id", currentUser.getUserId());
|
||||
List<UserAuth> userAuthList = userAuthService.list(updateWrapper);
|
||||
if (userAuthList == null || userAuthList.isEmpty()) {
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
List<Long> userAuthDbIds = userAuthList.stream().map(val -> NumberUtils.toLong(val.getAuthCustomSuffix().replace(DocAuthConst.DB, ""))).collect(Collectors.toList());
|
||||
wrapper.in("id", userAuthDbIds);
|
||||
}
|
||||
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
|
||||
List<DatabaseFactoryBean> dataSourceList = datasourceList.stream().map(val -> {
|
||||
DatabaseFactoryBean bean = new DatabaseFactoryBean();
|
||||
@@ -63,26 +87,23 @@ public class DatabaseDocController {
|
||||
|
||||
@PostMapping(value = "/getDatabaseList")
|
||||
public ResponseJson getDatabaseList(Long sourceId) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
List<DatabaseInfoDto> dbNameDtoList = baseMapper.getDatabaseList();
|
||||
return DocDbResponseJson.ok(dbNameDtoList);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableList")
|
||||
public ResponseJson getTableList(Long sourceId, String dbName) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
List<TableInfoDto> dbTableList = baseMapper.getTableList(dbName);
|
||||
return DocDbResponseJson.ok(dbTableList);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableColumnList")
|
||||
public ResponseJson getTableColumnList(Long sourceId, String dbName, String tableName) {
|
||||
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE) && !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
|
||||
return DocDbResponseJson.warn("没有查看该库表信息的权限");
|
||||
}
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getFactoryById(sourceId);
|
||||
if (databaseFactoryBean == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
@@ -93,20 +114,14 @@ public class DatabaseDocController {
|
||||
|
||||
@PostMapping(value = "/getTableColumnDescList")
|
||||
public ResponseJson getTableColumnDescList(Long sourceId, String tableName) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
List<TableColumnDescDto> columnDescDto = baseMapper.getTableColumnDescList(tableName);
|
||||
return DocDbResponseJson.ok(columnDescDto);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/getTableAndColumnBySearch")
|
||||
public ResponseJson getTableAndColumnBySearch(Long sourceId, String dbName, String searchText) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
if (StringUtils.isBlank(searchText)) {
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
@@ -117,26 +132,23 @@ public class DatabaseDocController {
|
||||
|
||||
@PostMapping(value = "/getTableDescList")
|
||||
public ResponseJson getTableDescList(Long sourceId, String tableName) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
List<TableDescDto> columnDescDto = baseMapper.getTableDescList(tableName);
|
||||
return DocDbResponseJson.ok(columnDescDto);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updateTableDesc")
|
||||
public ResponseJson updateTableDesc(Long sourceId, String dbName, String tableName, String newDesc) {
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
BaseMapper baseMapper = this.getBaseMapper(sourceId);
|
||||
baseMapper.updateTableDesc(dbName, tableName, newDesc);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updateTableColumnDesc")
|
||||
public ResponseJson updateTableColumnDesc(Long sourceId, String dbName, String tableName, String columnName, String newDesc) {
|
||||
if (!DocUserUtil.haveCustomAuth(DbAuthType.DESC_EDIT.getName(), DocAuthConst.DB + sourceId)) {
|
||||
return DocDbResponseJson.warn("没有修改该表字段注释的权限");
|
||||
}
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapper(sourceId);
|
||||
if (baseMapper == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
@@ -163,6 +175,9 @@ public class DatabaseDocController {
|
||||
|
||||
@GetMapping(value = "/exportDatabase")
|
||||
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames) {
|
||||
if (!DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
|
||||
return DocDbResponseJson.warn("没有查看该库表信息的权限");
|
||||
}
|
||||
if (StringUtils.isBlank(tableNames)) {
|
||||
return DocDbResponseJson.warn("请选择需要导出的表");
|
||||
}
|
||||
@@ -232,6 +247,18 @@ public class DatabaseDocController {
|
||||
return tableColumnVo;
|
||||
}
|
||||
|
||||
private BaseMapper getBaseMapper(Long sourceId) {
|
||||
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
|
||||
&& !DocUserUtil.haveCustomAuth(DbAuthType.VIEW.getName(), DocAuthConst.DB + sourceId)) {
|
||||
throw new ConfirmException("没有查看该库表信息的权限");
|
||||
}
|
||||
BaseMapper baseMapper = databaseRegistrationBean.getBaseMapperById(sourceId);
|
||||
if (baseMapper == null) {
|
||||
throw new ConfirmException("未找到对应的数据库连接");
|
||||
}
|
||||
return baseMapper;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//File zipFile = ZipUtil.zip("d:/aaa");
|
||||
File zipFile = new File("d:/111.zip");
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.AuthInfo;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.UserAuth;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.AuthInfoService;
|
||||
import com.zyplayer.doc.data.service.manage.UserAuthService;
|
||||
import com.zyplayer.doc.data.service.manage.UserInfoService;
|
||||
import com.zyplayer.doc.db.controller.vo.UserDbAuthVo;
|
||||
import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 数据库权限控制器
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
@RestController
|
||||
@AuthMan("DB_DATASOURCE_MANAGE")
|
||||
@RequestMapping("/zyplayer-doc-db/auth")
|
||||
public class DbDataSourceAuthController {
|
||||
private static Logger logger = LoggerFactory.getLogger(DbDataSourceAuthController.class);
|
||||
|
||||
@Resource
|
||||
UserInfoService userInfoService;
|
||||
@Resource
|
||||
UserAuthService userAuthService;
|
||||
@Resource
|
||||
AuthInfoService authInfoService;
|
||||
|
||||
@PostMapping("/assign")
|
||||
public ResponseJson<Object> assign(Long sourceId, String authList) {
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
List<String> authNameList = Stream.of(DbAuthType.values()).map(DbAuthType::getName).collect(Collectors.toList());
|
||||
QueryWrapper<AuthInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.in("auth_name", authNameList);
|
||||
Collection<AuthInfo> authInfoList = authInfoService.list(queryWrapper);
|
||||
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
|
||||
|
||||
// 先删除所有用户的权限
|
||||
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
|
||||
updateWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
|
||||
updateWrapper.eq("del_flag", 0);
|
||||
userAuthService.remove(updateWrapper);
|
||||
|
||||
List<UserDbAuthVo> authVoList = JSON.parseArray(authList, UserDbAuthVo.class);
|
||||
for (UserDbAuthVo authVo : authVoList) {
|
||||
List<UserAuth> userAuthList = new LinkedList<>();
|
||||
Integer executeAuth = Optional.ofNullable(authVo.getExecuteAuth()).orElse(0);
|
||||
if (executeAuth <= 0) {
|
||||
Long authId = authInfoMap.get(DbAuthType.NO_AUTH.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (executeAuth >= 1) {
|
||||
Long authId = authInfoMap.get(DbAuthType.VIEW.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (executeAuth >= 2) {
|
||||
Long authId = authInfoMap.get(DbAuthType.SELECT.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (executeAuth >= 3) {
|
||||
Long authId = authInfoMap.get(DbAuthType.UPDATE.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (Objects.equals(authVo.getDescEditAuth(), 1)) {
|
||||
Long authId = authInfoMap.get(DbAuthType.DESC_EDIT.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (userAuthList.size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
// 保存权限,重新登录后可用,后期可以考虑在这里直接修改缓存里的用户权限
|
||||
userAuthService.saveBatch(userAuthList);
|
||||
}
|
||||
return DocResponseJson.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/list")
|
||||
public ResponseJson<Object> list(Long sourceId) {
|
||||
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("auth_custom_suffix", DocAuthConst.DB + sourceId);
|
||||
queryWrapper.eq("del_flag", 0);
|
||||
List<UserAuth> authList = userAuthService.list(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(authList)) {
|
||||
return DocResponseJson.ok();
|
||||
}
|
||||
// 权限ID对应的权限名
|
||||
Collection<AuthInfo> authInfoList = authInfoService.listByIds(authList.stream().map(UserAuth::getAuthId).collect(Collectors.toList()));
|
||||
Map<Long, String> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getId, AuthInfo::getAuthName));
|
||||
// 查询用户信息
|
||||
Map<Long, List<UserAuth>> userAuthGroup = authList.stream().collect(Collectors.groupingBy(UserAuth::getUserId));
|
||||
Collection<UserInfo> userInfos = userInfoService.listByIds(userAuthGroup.keySet());
|
||||
Map<Long, String> userInfoMap = userInfos.stream().collect(Collectors.toMap(UserInfo::getId, UserInfo::getUserName));
|
||||
List<UserDbAuthVo> authVoList = new LinkedList<>();
|
||||
// 组装结果集
|
||||
userAuthGroup.forEach((key, value) -> {
|
||||
Set<String> authNameSet = value.stream().map(auth -> authInfoMap.get(auth.getAuthId())).collect(Collectors.toSet());
|
||||
UserDbAuthVo authVo = new UserDbAuthVo();
|
||||
authVo.setExecuteAuth(0);
|
||||
if (this.haveAuth(authNameSet, DbAuthType.UPDATE) == 1) {
|
||||
authVo.setExecuteAuth(3);
|
||||
} else if (this.haveAuth(authNameSet, DbAuthType.SELECT) == 1) {
|
||||
authVo.setExecuteAuth(2);
|
||||
} else if (this.haveAuth(authNameSet, DbAuthType.VIEW) == 1) {
|
||||
authVo.setExecuteAuth(1);
|
||||
}
|
||||
authVo.setDescEditAuth(this.haveAuth(authNameSet, DbAuthType.DESC_EDIT));
|
||||
authVo.setUserId(key);
|
||||
authVo.setUserName(userInfoMap.get(key));
|
||||
authVoList.add(authVo);
|
||||
});
|
||||
return DocResponseJson.ok(authVoList);
|
||||
}
|
||||
|
||||
private Integer haveAuth(Set<String> authNameSet, DbAuthType dbAuthType) {
|
||||
return authNameSet.contains(dbAuthType.getName()) ? 1 : 0;
|
||||
}
|
||||
|
||||
private UserAuth createUserAuth(Long sourceId, Long loginUserId, Long userId, Long authId) {
|
||||
UserAuth userAuth = new UserAuth();
|
||||
userAuth.setAuthCustomSuffix(DocAuthConst.DB + sourceId);
|
||||
userAuth.setCreationTime(new Date());
|
||||
userAuth.setCreateUid(loginUserId);
|
||||
userAuth.setDelFlag(0);
|
||||
userAuth.setUserId(userId);
|
||||
userAuth.setAuthId(authId);
|
||||
return userAuth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import java.util.*;
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年6月29日
|
||||
*/
|
||||
@AuthMan("DB_DATASOURCE_MANAGE")
|
||||
@RestController
|
||||
@AuthMan("DB_DATASOURCE_MANAGE")
|
||||
@RequestMapping("/zyplayer-doc-db/datasource")
|
||||
public class DbDatasourceController {
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
@@ -13,10 +12,12 @@ import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbFavorite;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
|
||||
import com.zyplayer.doc.data.repository.manage.mapper.DbFavoriteMapper;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.DbFavoriteService;
|
||||
import com.zyplayer.doc.data.service.manage.DbHistoryService;
|
||||
import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -54,9 +55,16 @@ public class DbSqlExecutorController {
|
||||
if (StringUtils.isBlank(sql)) {
|
||||
return DocDbResponseJson.warn("执行的SQL不能为空");
|
||||
}
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
boolean select = DocUserUtil.haveCustomAuth(DbAuthType.SELECT.getName(), DocAuthConst.DB + sourceId);
|
||||
boolean update = DocUserUtil.haveCustomAuth(DbAuthType.UPDATE.getName(), DocAuthConst.DB + sourceId);
|
||||
if (!manageAuth && !select && !update) {
|
||||
return DocDbResponseJson.warn("没有该数据源的执行权限");
|
||||
}
|
||||
try {
|
||||
Map<String, Object> paramMap = JSON.parseObject(params);
|
||||
ExecuteResult executeResult = sqlExecutor.execute(sourceId, executeId, sql, paramMap);
|
||||
ExecuteType executeType = (!manageAuth && select) ? ExecuteType.SELECT : ExecuteType.ALL;
|
||||
ExecuteResult executeResult = sqlExecutor.execute(sourceId, executeId, executeType, sql, paramMap);
|
||||
SerializeConfig mapping = new SerializeConfig();
|
||||
mapping.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
||||
mapping.put(Timestamp.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.zyplayer.doc.db.controller.vo;
|
||||
|
||||
public class UserDbAuthVo {
|
||||
private String userName;
|
||||
private Long userId;
|
||||
private Integer executeAuth;
|
||||
private Integer descEditAuth;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getExecuteAuth() {
|
||||
return executeAuth;
|
||||
}
|
||||
|
||||
public void setExecuteAuth(Integer executeAuth) {
|
||||
this.executeAuth = executeAuth;
|
||||
}
|
||||
|
||||
public Integer getDescEditAuth() {
|
||||
return descEditAuth;
|
||||
}
|
||||
|
||||
public void setDescEditAuth(Integer descEditAuth) {
|
||||
this.descEditAuth = descEditAuth;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
package com.zyplayer.doc.db.framework.configuration;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbDatasource;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.interceptor.SqlLogInterceptor;
|
||||
import org.apache.ibatis.plugin.Interceptor;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.util.Properties;
|
||||
|
||||
public class DatasourceUtil {
|
||||
private static SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
|
||||
@@ -19,24 +18,22 @@ public class DatasourceUtil {
|
||||
public static DatabaseFactoryBean createDatabaseFactoryBean(DbDatasource dbDatasource){
|
||||
try {
|
||||
// 数据源配置
|
||||
Properties xaProperties = new Properties();
|
||||
xaProperties.setProperty("driverClassName", dbDatasource.getDriverClassName());
|
||||
xaProperties.setProperty("url", dbDatasource.getSourceUrl());
|
||||
xaProperties.setProperty("username", dbDatasource.getSourceName());
|
||||
xaProperties.setProperty("password", dbDatasource.getSourcePassword());
|
||||
xaProperties.setProperty("maxActive", "500");
|
||||
xaProperties.setProperty("breakAfterAcquireFailure", "true");
|
||||
xaProperties.setProperty("testOnBorrow", "true");
|
||||
xaProperties.setProperty("testWhileIdle", "true");
|
||||
xaProperties.setProperty("validationQuery", "select 'x'");
|
||||
// 数据源
|
||||
AtomikosDataSourceBean dataSource = new AtomikosDataSourceBean();
|
||||
dataSource.setXaProperties(xaProperties);
|
||||
dataSource.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
|
||||
dataSource.setUniqueResourceName("zyplayer-doc-db" + dbDatasource.getId());
|
||||
dataSource.setMaxPoolSize(500);
|
||||
dataSource.setMinPoolSize(1);
|
||||
dataSource.setMaxLifetime(60);
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(dbDatasource.getDriverClassName());
|
||||
dataSource.setUrl(dbDatasource.getSourceUrl());
|
||||
dataSource.setUsername(dbDatasource.getSourceName());
|
||||
dataSource.setPassword(dbDatasource.getSourcePassword());
|
||||
dataSource.setInitialSize(2);
|
||||
dataSource.setMinIdle(2);
|
||||
dataSource.setMaxActive(50);
|
||||
dataSource.setTestWhileIdle(true);
|
||||
dataSource.setTestOnBorrow(false);
|
||||
dataSource.setTestOnReturn(false);
|
||||
dataSource.setValidationQuery("select 1");
|
||||
dataSource.setMaxWait(3000);
|
||||
dataSource.setTimeBetweenEvictionRunsMillis(60000);
|
||||
dataSource.setMinEvictableIdleTimeMillis(3600000);
|
||||
dataSource.setName("zyplayer-doc-db" + dbDatasource.getId());
|
||||
// 描述连接信息的对象
|
||||
DatabaseFactoryBean databaseFactoryBean = new DatabaseFactoryBean();
|
||||
DatabaseMetaData metaData = dataSource.getConnection().getMetaData();
|
||||
@@ -44,7 +41,7 @@ public class DatasourceUtil {
|
||||
Resource[] resources = null;
|
||||
String dbUrl = metaData.getURL();
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||
if (productName.indexOf("mysql") >= 0) {
|
||||
if (productName.contains("mysql")) {
|
||||
// jdbc:mysql://192.168.0.1:3306/user_info?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&autoReconnect=true
|
||||
String[] urlParamArr = dbUrl.split("\\?");
|
||||
String[] urlDbNameArr = urlParamArr[0].split("/");
|
||||
@@ -54,7 +51,7 @@ public class DatasourceUtil {
|
||||
}
|
||||
databaseFactoryBean.setDatabaseProduct(DatabaseFactoryBean.DatabaseProduct.MYSQL);
|
||||
resources = resolver.getResources("classpath:com/zyplayer/doc/db/framework/db/mapper/mysql/*.xml");
|
||||
} else if (productName.indexOf("sql server") >= 0) {
|
||||
} else if (productName.contains("sql server")) {
|
||||
// jdbc:jtds:sqlserver://192.168.0.1:33434;socketTimeout=60;DatabaseName=user_info;
|
||||
String[] urlParamArr = dbUrl.split(";");
|
||||
String[] urlDbNameArr = urlParamArr[0].split("/");
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.zyplayer.doc.db.framework.consts;
|
||||
|
||||
public enum DbAuthType {
|
||||
NO_AUTH(0, "DB_NO_AUTH_"),
|
||||
VIEW(1, "DB_VIEW_"),
|
||||
SELECT(2, "DB_SELECT_"),
|
||||
UPDATE(3, "DB_UPDATE_"),
|
||||
DESC_EDIT(3, "DB_DESC_EDIT_"),
|
||||
;
|
||||
private Integer type;
|
||||
private String name;
|
||||
|
||||
DbAuthType(Integer type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.zyplayer.doc.db.framework.db.bean;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
|
||||
|
||||
/**
|
||||
* 描述连接信息的对象
|
||||
@@ -10,7 +10,7 @@ import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
|
||||
*/
|
||||
public class DatabaseFactoryBean {
|
||||
private Long id;
|
||||
private AtomikosDataSourceBean dataSource;
|
||||
private DruidDataSource dataSource;
|
||||
private SqlSessionTemplate sqlSessionTemplate;
|
||||
private String url;
|
||||
private String host;
|
||||
@@ -38,11 +38,11 @@ public class DatabaseFactoryBean {
|
||||
MYSQL, SQLSERVER
|
||||
}
|
||||
|
||||
public AtomikosDataSourceBean getDataSource() {
|
||||
public DruidDataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public void setDataSource(AtomikosDataSourceBean dataSource) {
|
||||
public void setDataSource(DruidDataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.zyplayer.doc.db.framework.db.mapper.base;
|
||||
|
||||
public enum ExecuteType {
|
||||
ALL, SELECT,
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package com.zyplayer.doc.db.framework.db.mapper.base;
|
||||
|
||||
import com.alibaba.druid.pool.DruidPooledConnection;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbFavorite;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.DbHistory;
|
||||
import com.zyplayer.doc.data.service.manage.DbFavoriteService;
|
||||
import com.zyplayer.doc.data.service.manage.DbHistoryService;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
@@ -20,11 +16,13 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.util.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@@ -64,9 +62,9 @@ public class SqlExecutor {
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
public ExecuteResult execute(Long datasourceId, String executeId, String sql, Map<String, Object> paramMap) {
|
||||
public ExecuteResult execute(Long datasourceId, String executeId, ExecuteType executeType, String sql, Map<String, Object> paramMap) {
|
||||
DatabaseFactoryBean factoryBean = databaseRegistrationBean.getFactoryById(datasourceId);
|
||||
return this.execute(factoryBean, executeId, sql, paramMap, null);
|
||||
return this.execute(factoryBean, executeId, executeType, sql, paramMap, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,19 +72,11 @@ public class SqlExecutor {
|
||||
* @author 暮光:城中城
|
||||
* @since 2019年8月18日
|
||||
*/
|
||||
public ExecuteResult execute(DatabaseFactoryBean factoryBean, String executeId, String sql, Map<String, Object> paramMap, ResultHandler handler) {
|
||||
public ExecuteResult execute(DatabaseFactoryBean factoryBean, String executeId, ExecuteType executeType, String sql, Map<String, Object> paramMap, ResultHandler handler) {
|
||||
if (factoryBean == null) {
|
||||
return new ExecuteResult();
|
||||
}
|
||||
// 组装参数
|
||||
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
|
||||
Object o = paramMap.get(content);
|
||||
return (o == null) ? null : String.valueOf(o);
|
||||
});
|
||||
sql = parser.parse(sql);
|
||||
SqlSourceBuilder sqlSourceBuilder = new SqlSourceBuilder(new MybatisConfiguration());
|
||||
StaticSqlSource parse = (StaticSqlSource) sqlSourceBuilder.parse(sql, Object.class, paramMap);
|
||||
BoundSql boundSql = parse.getBoundSql(new Object());
|
||||
BoundSql boundSql = getBoundSql(sql, paramMap);
|
||||
sql = boundSql.getSql();
|
||||
String sqlStr = SqlLogUtil.getSqlString(paramMap, boundSql);
|
||||
logger.info("sql ==> {}", sqlStr);
|
||||
@@ -95,16 +85,23 @@ public class SqlExecutor {
|
||||
|
||||
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
||||
PreparedStatement preparedStatement = null;
|
||||
DruidPooledConnection connection = null;
|
||||
// 执行查询
|
||||
try {
|
||||
Connection connection = factoryBean.getDataSource().getConnection();
|
||||
connection = factoryBean.getDataSource().getConnection();
|
||||
preparedStatement = connection.prepareStatement(sql);
|
||||
// 设置当前的PreparedStatement
|
||||
statementMap.put(executeId, preparedStatement);
|
||||
for (int i = 0; i < parameterMappings.size(); i++) {
|
||||
preparedStatement.setObject(i + 1, paramMap.get(parameterMappings.get(i).getProperty()));
|
||||
}
|
||||
preparedStatement.execute();
|
||||
// 限制下最大数量
|
||||
preparedStatement.setMaxRows(1000);
|
||||
if (ExecuteType.SELECT.equals(executeType)) {
|
||||
preparedStatement.executeQuery();
|
||||
} else {
|
||||
preparedStatement.execute();
|
||||
}
|
||||
// 查询的结果集
|
||||
ResultSet resultSet = preparedStatement.getResultSet();
|
||||
List<Map<String, Object>> resultList = new LinkedList<>();
|
||||
@@ -137,6 +134,25 @@ public class SqlExecutor {
|
||||
} catch (Exception e) {
|
||||
logger.error("关闭Statement失败");
|
||||
}
|
||||
try {
|
||||
if (connection != null && !connection.isClosed()) {
|
||||
connection.recycle();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("回收connection失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BoundSql getBoundSql(String sql, Map<String, Object> paramMap){
|
||||
// 组装参数
|
||||
GenericTokenParser parser = new GenericTokenParser("${", "}", content -> {
|
||||
Object o = paramMap.get(content);
|
||||
return (o == null) ? null : String.valueOf(o);
|
||||
});
|
||||
sql = parser.parse(sql);
|
||||
SqlSourceBuilder sqlSourceBuilder = new SqlSourceBuilder(new MybatisConfiguration());
|
||||
StaticSqlSource parse = (StaticSqlSource) sqlSourceBuilder.parse(sql, Object.class, paramMap);
|
||||
return parse.getBoundSql(new Object());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,u){for(var i,a,f,l=0,s=[];l<t.length;l++)a=t[l],o[a]&&s.push(o[a][0]),o[a]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(r&&r(t,c,u);s.length;)s.shift()();if(u)for(l=0;l<u.length;l++)f=n(n.s=u[l]);return f};var t={},o={2:0};n.e=function(e){function r(){i.onerror=i.onload=null,clearTimeout(a);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var u=document.getElementsByTagName("head")[0],i=document.createElement("script");i.type="text/javascript",i.charset="utf-8",i.async=!0,i.timeout=12e4,n.nc&&i.setAttribute("nonce",n.nc),i.src=n.p+""+e+".js?"+{0:"ec42ff08cce82ffb09c1",1:"0a0403eb1820498dc9bc"}[e];var a=setTimeout(r,12e4);return i.onerror=i.onload=r,u.appendChild(i),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=doc-db-manifest.js.map?039e0b16a238c62908d2
|
||||
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var u,i,f,l=0,s=[];l<t.length;l++)i=t[l],o[i]&&s.push(o[i][0]),o[i]=0;for(u in c)Object.prototype.hasOwnProperty.call(c,u)&&(e[u]=c[u]);for(r&&r(t,c,a);s.length;)s.shift()();if(a)for(l=0;l<a.length;l++)f=n(n.s=a[l]);return f};var t={},o={2:0};n.e=function(e){function r(){u.onerror=u.onload=null,clearTimeout(i);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var a=document.getElementsByTagName("head")[0],u=document.createElement("script");u.type="text/javascript",u.charset="utf-8",u.async=!0,u.timeout=12e4,n.nc&&u.setAttribute("nonce",n.nc),u.src=n.p+""+e+".js?"+{0:"84aaa1f845500c1f32eb",1:"0a0403eb1820498dc9bc"}[e];var i=setTimeout(r,12e4);return u.onerror=u.onload=r,a.appendChild(u),c},n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=doc-db-manifest.js.map?fdc840871c16aef2ccfc
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript" src="doc-db-manifest.js?039e0b16a238c62908d2"></script><script type="text/javascript" src="doc-db-vendor.js?0a0403eb1820498dc9bc"></script><script type="text/javascript" src="doc-db-index.js?ec42ff08cce82ffb09c1"></script></body>
|
||||
<script type="text/javascript" src="doc-db-manifest.js?fdc840871c16aef2ccfc"></script><script type="text/javascript" src="doc-db-vendor.js?0a0403eb1820498dc9bc"></script><script type="text/javascript" src="doc-db-index.js?84aaa1f845500c1f32eb"></script></body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
@@ -28,6 +28,14 @@ CREATE TABLE `db_history` (
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
|
||||
|
||||
INSERT INTO `auth_info`(`auth_name`, `auth_desc`, `can_edit`, `create_uid`, `creation_time`, `auth_type`)
|
||||
VALUES ( 'DB_VIEW_', '数据源查看权', 0, 1, '2019-08-18 23:25:17', 0);
|
||||
INSERT INTO `auth_info`(`auth_name`, `auth_desc`, `can_edit`, `create_uid`, `creation_time`, `auth_type`)
|
||||
VALUES ( 'DB_SELECT_', '数据源查询权', 0, 1, '2019-08-18 23:25:17', 0);
|
||||
INSERT INTO `auth_info`(`auth_name`, `auth_desc`, `can_edit`, `create_uid`, `creation_time`, `auth_type`)
|
||||
VALUES ( 'DB_UPDATE_', '数据源增删改查权', 0, 1, '2019-08-18 23:25:17', 0);
|
||||
INSERT INTO `auth_info`(`auth_name`, `auth_desc`, `can_edit`, `create_uid`, `creation_time`, `auth_type`)
|
||||
VALUES ( 'DB_DESC_EDIT_', '表字段注释修改权', 0, 1, '2019-08-18 23:25:17', 0);
|
||||
|
||||
|
||||
-- ------------------------全新的库:------------------------
|
||||
|
||||
@@ -2,6 +2,7 @@ var URL = {
|
||||
userLogin: '/login',
|
||||
userLogout: '/logout',
|
||||
getSelfUserInfo: '/user/info/selfInfo',
|
||||
getUserBaseInfo: '/zyplayer-doc-wiki/common/user/base',
|
||||
|
||||
datasourceList: '/zyplayer-doc-db/doc-db/getDataSourceList',
|
||||
databaseList: '/zyplayer-doc-db/doc-db/getDatabaseList',
|
||||
@@ -20,6 +21,9 @@ var URL = {
|
||||
favoriteList: '/zyplayer-doc-db/executor/favorite/list',
|
||||
historyList: '/zyplayer-doc-db/executor/history/list',
|
||||
|
||||
assignDbUserAuth: '/zyplayer-doc-db/auth/assign',
|
||||
dbUserAuthList: '/zyplayer-doc-db/auth/list',
|
||||
|
||||
systemUpgradeInfo: '/system/info/upgrade',
|
||||
};
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
<el-table-column prop="sourceUrl" label="数据源URL"></el-table-column>
|
||||
<el-table-column prop="sourceName" label="账号"></el-table-column>
|
||||
<el-table-column prop="sourcePassword" label="密码"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<el-table-column label="操作" width="220">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-on:click="editDatasource(scope.row)" type="primary" size="small">修改</el-button>
|
||||
<el-button v-on:click="deleteDatasource(scope.row)" type="danger" size="small">删除</el-button>
|
||||
<el-button v-on:click="editDatasource(scope.row)" type="primary" size="mini">修改</el-button>
|
||||
<el-button v-on:click="editDbAuth(scope.row)" type="success" size="mini">权限</el-button>
|
||||
<el-button v-on:click="deleteDatasource(scope.row)" type="danger" size="mini">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -55,6 +56,37 @@
|
||||
<el-button v-on:click="datasourceDialogVisible=false" plain>取消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!--人员权限弹窗-->
|
||||
<el-dialog title="权限编辑" :visible.sync="dbSourceAuthDialogVisible" width="900px">
|
||||
<el-row>
|
||||
<el-select v-model="dbSourceAuthNewUser" filterable remote reserve-keyword
|
||||
placeholder="请输入名字、邮箱、账号搜索用户" :remote-method="getSearchUserList"
|
||||
:loading="dbSourceAuthUserLoading" style="width: 750px;">
|
||||
<el-option v-for="item in searchUserList" :key="item.id" :label="item.userName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button v-on:click="addDbSourceAuthUser">添加</el-button>
|
||||
</el-row>
|
||||
<el-table :data="dbSourceAuthUserList" border style="width: 100%; margin: 10px 0;">
|
||||
<el-table-column prop="userName" label="用户" width="150"></el-table-column>
|
||||
<el-table-column label="权限">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="scope.row.executeAuth" :label="0">无权限</el-radio>
|
||||
<el-radio v-model="scope.row.executeAuth" :label="1">库表查看权</el-radio>
|
||||
<el-radio v-model="scope.row.executeAuth" :label="2">数据查询权</el-radio>
|
||||
<el-radio v-model="scope.row.executeAuth" :label="3">所有权限</el-radio>
|
||||
<el-checkbox :true-label="1" :false-label="0" v-model="scope.row.descEditAuth">表字段注释修改权</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" type="danger" plain v-on:click="deleteUserDbSourceAuth(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-button type="primary" v-on:click="saveUserDbSourceAuth">保存配置</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -72,6 +104,12 @@
|
||||
datasourceList: [],
|
||||
newDatasource: {},
|
||||
urlPlaceholder: "数据源URL",
|
||||
|
||||
dbSourceAuthDialogVisible: false,
|
||||
dbSourceAuthUserList: [],
|
||||
dbSourceAuthUserLoading: false,
|
||||
searchUserList: [],
|
||||
dbSourceAuthNewUser: "",
|
||||
};
|
||||
},
|
||||
mounted: function () {
|
||||
@@ -79,6 +117,64 @@
|
||||
this.getDatasourceList();
|
||||
},
|
||||
methods: {
|
||||
editDbAuth(row) {
|
||||
this.newDatasource = JSON.parse(JSON.stringify(row));
|
||||
app.dbSourceAuthNewUser = [];
|
||||
app.dbSourceAuthUserList = [];
|
||||
app.dbSourceAuthDialogVisible = true;
|
||||
var param = {sourceId: app.newDatasource.id};
|
||||
this.common.post(this.apilist1.dbUserAuthList, param, function (json) {
|
||||
app.dbSourceAuthUserList = json.data || [];
|
||||
app.dbSourceAuthDialogVisible = true;
|
||||
});
|
||||
},
|
||||
saveUserDbSourceAuth() {
|
||||
var param = {sourceId: app.newDatasource.id, authList: JSON.stringify(app.dbSourceAuthUserList)};
|
||||
this.common.post(this.apilist1.assignDbUserAuth, param, function (json) {
|
||||
toast.success("保存成功!");
|
||||
});
|
||||
},
|
||||
deleteUserDbSourceAuth(row) {
|
||||
var dbSourceAuthUserList = [];
|
||||
for (var i = 0; i < this.dbSourceAuthUserList.length; i++) {
|
||||
var item = this.dbSourceAuthUserList[i];
|
||||
if (item.userId != row.userId) {
|
||||
dbSourceAuthUserList.push(this.dbSourceAuthUserList[i]);
|
||||
}
|
||||
}
|
||||
this.dbSourceAuthUserList = dbSourceAuthUserList;
|
||||
},
|
||||
addDbSourceAuthUser() {
|
||||
if (this.dbSourceAuthNewUser.length <= 0) {
|
||||
toast.warn("请先选择用户");
|
||||
return;
|
||||
}
|
||||
var userName = "";
|
||||
for (var i = 0; i < this.searchUserList.length; i++) {
|
||||
if (this.dbSourceAuthNewUser == this.searchUserList[i].id) {
|
||||
userName = this.searchUserList[i].userName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.dbSourceAuthUserList.push({
|
||||
userName: userName,
|
||||
userId: this.dbSourceAuthNewUser,
|
||||
executeAuth: 0,
|
||||
descEditAuth: 0,
|
||||
});
|
||||
this.dbSourceAuthNewUser = "";
|
||||
},
|
||||
getSearchUserList(query) {
|
||||
if (query == '') {
|
||||
return;
|
||||
}
|
||||
this.dbSourceAuthUserLoading = true;
|
||||
var param = {search: query};
|
||||
this.common.post(this.apilist1.getUserBaseInfo, param, function (json) {
|
||||
app.searchUserList = json.data || [];
|
||||
app.dbSourceAuthUserLoading = false;
|
||||
});
|
||||
},
|
||||
addDatasource() {
|
||||
this.datasourceDialogVisible = true;
|
||||
this.newDatasource = {name: "", driverClassName: "", sourceUrl: "", sourceName: "", sourcePassword: ""};
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div v-if="scope.row.inEdit == 1" @keyup.enter="saveColumnDescription(scope.row)">
|
||||
<el-input v-model="scope.row.newDesc" placeholder="输入字段注释" v-on:blur="saveColumnDescription(scope.row)"></el-input>
|
||||
</div>
|
||||
<div v-else class="description" v-on:click="descBoxClick(scope.row)">{{scope.row.description}}</div>
|
||||
<div v-else class="description" v-on:click="descBoxClick(scope.row)">{{scope.row.description||' '}}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
@@ -4,9 +4,9 @@ import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.UserInfo;
|
||||
@@ -14,6 +14,7 @@ import com.zyplayer.doc.data.repository.manage.entity.WikiPage;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.WikiPageFile;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.WikiSpace;
|
||||
import com.zyplayer.doc.data.repository.manage.mapper.WikiPageFileMapper;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.UserInfoService;
|
||||
import com.zyplayer.doc.data.service.manage.WikiPageFileService;
|
||||
import com.zyplayer.doc.data.service.manage.WikiPageService;
|
||||
@@ -100,7 +101,7 @@ public class WikiCommonController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限
|
||||
if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.PAGE_FILE_UPLOAD.getName(), pageId);
|
||||
boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.PAGE_FILE_UPLOAD.getName(), DocAuthConst.WIKI + pageId);
|
||||
if (!pageAuth) {
|
||||
return DocResponseJson.warn("您没有修改该文章附件的权限!");
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ package com.zyplayer.doc.wiki.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.*;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.*;
|
||||
import com.zyplayer.doc.wiki.controller.vo.UserPageAuthVo;
|
||||
import com.zyplayer.doc.wiki.framework.consts.SpaceType;
|
||||
@@ -64,7 +65,7 @@ public class WikiPageAuthController {
|
||||
return DocResponseJson.warn("只有个人空间才可以编辑权限");
|
||||
}
|
||||
if (!Objects.equals(currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
if (!DocUserUtil.havePageAuth(WikiAuthType.PAGE_AUTH_MANAGE.getName(), pageId)) {
|
||||
if (!DocUserUtil.haveCustomAuth(WikiAuthType.PAGE_AUTH_MANAGE.getName(), DocAuthConst.WIKI + pageId)) {
|
||||
return DocResponseJson.warn("您不是创建人或没有权限修改");
|
||||
}
|
||||
}
|
||||
@@ -75,12 +76,10 @@ public class WikiPageAuthController {
|
||||
Map<String, Long> authInfoMap = authInfoList.stream().collect(Collectors.toMap(AuthInfo::getAuthName, AuthInfo::getId));
|
||||
|
||||
// 先删除页面的所有用户的权限
|
||||
UserAuth userAuthDel = new UserAuth();
|
||||
userAuthDel.setDelFlag(1);
|
||||
QueryWrapper<UserAuth> updateWrapper = new QueryWrapper<>();
|
||||
updateWrapper.eq("auth_custom_suffix", pageId);
|
||||
updateWrapper.eq("auth_custom_suffix", DocAuthConst.WIKI + pageId);
|
||||
updateWrapper.eq("del_flag", 0);
|
||||
userAuthService.update(userAuthDel, updateWrapper);
|
||||
userAuthService.remove(updateWrapper);
|
||||
|
||||
List<UserPageAuthVo> authVoList = JSON.parseArray(authList, UserPageAuthVo.class);
|
||||
for (UserPageAuthVo authVo : authVoList) {
|
||||
@@ -130,12 +129,12 @@ public class WikiPageAuthController {
|
||||
WikiPage wikiPageSel = wikiPageService.getById(pageId);
|
||||
WikiSpace wikiSpaceSel = wikiSpaceService.getById(wikiPageSel.getSpaceId());
|
||||
if (!Objects.equals(currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
if (!DocUserUtil.havePageAuth(WikiAuthType.PAGE_AUTH_MANAGE.getName(), pageId)) {
|
||||
if (!DocUserUtil.haveCustomAuth(WikiAuthType.PAGE_AUTH_MANAGE.getName(), DocAuthConst.WIKI + pageId)) {
|
||||
return DocResponseJson.warn("您没有权限管理该页面的权限");
|
||||
}
|
||||
}
|
||||
QueryWrapper<UserAuth> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("auth_custom_suffix", pageId);
|
||||
queryWrapper.eq("auth_custom_suffix", DocAuthConst.WIKI + pageId);
|
||||
queryWrapper.eq("del_flag", 0);
|
||||
List<UserAuth> authList = userAuthService.list(queryWrapper);
|
||||
if (CollectionUtils.isEmpty(authList)) {
|
||||
@@ -172,7 +171,7 @@ public class WikiPageAuthController {
|
||||
|
||||
private UserAuth createUserAuth(Long pageId, Long loginUserId, Long userId, Long authId){
|
||||
UserAuth userAuth = new UserAuth();
|
||||
userAuth.setAuthCustomSuffix(String.valueOf(pageId));
|
||||
userAuth.setAuthCustomSuffix(DocAuthConst.WIKI + pageId);
|
||||
userAuth.setCreationTime(new Date());
|
||||
userAuth.setCreateUid(loginUserId);
|
||||
userAuth.setDelFlag(0);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class WikiPageCommentController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限,感觉评论没必要加权限,先去掉
|
||||
// if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
// boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.COMMENT_PAGE.getName(), pageId);
|
||||
// boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.COMMENT_PAGE.getName(), pageId);
|
||||
// if (!pageAuth) {
|
||||
// return DocResponseJson.warn("您没有评论该文章的权限!");
|
||||
// }
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.zyplayer.doc.data.repository.manage.mapper.WikiPageContentMapper;
|
||||
import com.zyplayer.doc.data.repository.manage.mapper.WikiPageMapper;
|
||||
import com.zyplayer.doc.data.repository.manage.param.SearchByEsParam;
|
||||
import com.zyplayer.doc.data.repository.manage.vo.SpaceNewsVo;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.elasticsearch.entity.EsWikiPage;
|
||||
import com.zyplayer.doc.data.service.elasticsearch.service.EsWikiPageService;
|
||||
import com.zyplayer.doc.data.service.elasticsearch.support.EsPage;
|
||||
@@ -157,7 +158,7 @@ public class WikiPageController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限
|
||||
if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.EDIT_PAGE.getName(), id);
|
||||
boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.EDIT_PAGE.getName(), DocAuthConst.WIKI + id);
|
||||
if (!pageAuth) {
|
||||
return DocResponseJson.warn("您没有修改该文章的权限!");
|
||||
}
|
||||
@@ -186,7 +187,7 @@ public class WikiPageController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限
|
||||
if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.DELETE_PAGE.getName(), pageId);
|
||||
boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.DELETE_PAGE.getName(), DocAuthConst.WIKI + pageId);
|
||||
if (!pageAuth) {
|
||||
return DocResponseJson.warn("您没有删除该文章的权限!");
|
||||
}
|
||||
@@ -228,7 +229,7 @@ public class WikiPageController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限
|
||||
if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.EDIT_PAGE.getName(), pageId);
|
||||
boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.EDIT_PAGE.getName(), DocAuthConst.WIKI + pageId);
|
||||
if (!pageAuth) {
|
||||
return DocResponseJson.warn("您没有修改该文章的权限!");
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package com.zyplayer.doc.wiki.controller;
|
||||
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.core.json.DocResponseJson;
|
||||
import com.zyplayer.doc.core.json.ResponseJson;
|
||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||
import com.zyplayer.doc.data.config.security.DocUserDetails;
|
||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.WikiPage;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.WikiPageFile;
|
||||
import com.zyplayer.doc.data.repository.manage.entity.WikiSpace;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.WikiPageFileService;
|
||||
import com.zyplayer.doc.data.service.manage.WikiPageService;
|
||||
import com.zyplayer.doc.data.service.manage.WikiSpaceService;
|
||||
@@ -75,7 +76,7 @@ public class WikiPageFileController {
|
||||
}
|
||||
// 空间不是自己的,也没有权限
|
||||
if (SpaceType.isOthersPersonal(wikiSpaceSel.getType(), currentUser.getUserId(), wikiSpaceSel.getCreateUserId())) {
|
||||
boolean pageAuth = DocUserUtil.havePageAuth(WikiAuthType.PAGE_FILE_UPLOAD.getName(), pageId);
|
||||
boolean pageAuth = DocUserUtil.haveCustomAuth(WikiAuthType.PAGE_FILE_UPLOAD.getName(), DocAuthConst.WIKI + pageId);
|
||||
if (!pageAuth) {
|
||||
return DocResponseJson.warn("您没有修改该文章附件的权限!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user