库函数增加修改日志记录,增加函数修改授权,展示优化
This commit is contained in:
@@ -91,6 +91,11 @@ public class DbDataSourceAuthController {
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (Objects.equals(authVo.getProcEditAuth(), 1)) {
|
||||
Long authId = authInfoMap.get(DbAuthType.PROC_EDIT.getName());
|
||||
UserAuth userAuth = this.createUserAuth(sourceId, currentUser.getUserId(), authVo.getUserId(), authId);
|
||||
userAuthList.add(userAuth);
|
||||
}
|
||||
if (userAuthList.size() <= 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -121,7 +126,6 @@ public class DbDataSourceAuthController {
|
||||
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) {
|
||||
@@ -130,6 +134,7 @@ public class DbDataSourceAuthController {
|
||||
authVo.setExecuteAuth(1);
|
||||
}
|
||||
authVo.setDescEditAuth(this.haveAuth(authNameSet, DbAuthType.DESC_EDIT));
|
||||
authVo.setProcEditAuth(this.haveAuth(authNameSet, DbAuthType.PROC_EDIT));
|
||||
authVo.setUserId(key);
|
||||
authVo.setUserName(userInfoMap.get(key));
|
||||
authVoList.add(authVo);
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.zyplayer.doc.db.framework.configuration.DatasourceUtil;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseFactoryBean;
|
||||
import com.zyplayer.doc.db.framework.db.bean.DatabaseRegistrationBean;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@@ -59,8 +60,13 @@ public class DbDatasourceController {
|
||||
public ResponseJson groups() {
|
||||
QueryWrapper<DbDatasource> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("yn", 1);
|
||||
wrapper.isNotNull("group_name");
|
||||
wrapper.select("group_name");
|
||||
wrapper.groupBy("group_name");
|
||||
List<DbDatasource> datasourceList = dbDatasourceService.list(wrapper);
|
||||
if (CollectionUtils.isEmpty(datasourceList)) {
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
Set<String> groupNameSet = datasourceList.stream().map(DbDatasource::getGroupName).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
|
||||
return DocDbResponseJson.ok(groupNameSet);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
package com.zyplayer.doc.db.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException;
|
||||
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.DbProcLog;
|
||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||
import com.zyplayer.doc.data.service.manage.DbProcLogService;
|
||||
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
||||
import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
||||
import com.zyplayer.doc.db.framework.db.dto.ProcedureDto;
|
||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||
import com.zyplayer.doc.db.framework.json.DocDbResponseJson;
|
||||
@@ -18,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -34,6 +45,8 @@ public class DbProcedureController {
|
||||
|
||||
@Resource
|
||||
DbBaseFactory dbBaseFactory;
|
||||
@Resource
|
||||
DbProcLogService dbProcLogService;
|
||||
|
||||
/**
|
||||
* 存储过程列表
|
||||
@@ -43,18 +56,19 @@ public class DbProcedureController {
|
||||
*/
|
||||
@PostMapping(value = "/list")
|
||||
public ResponseJson list(ProcedureListParam procedureParam) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
try {
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(procedureParam.getSourceId());
|
||||
procedureParam.setOffset((procedureParam.getPageNum() - 1) * procedureParam.getPageSize());
|
||||
List<ProcedureDto> procedureDtoList = dbBaseService.getProcedureList(procedureParam);
|
||||
DocDbResponseJson responseJson = DocDbResponseJson.ok(procedureDtoList);
|
||||
if (procedureParam.getPageNum() == 1) {
|
||||
responseJson.setTotal(dbBaseService.getProcedureCount(procedureParam));
|
||||
}
|
||||
return responseJson;
|
||||
} catch (Exception e) {
|
||||
// 一般是数据库的帐号没权限查存储过程
|
||||
return DocDbResponseJson.error(e.getMessage());
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(procedureParam.getSourceId());
|
||||
procedureParam.setOffset((procedureParam.getPageNum() - 1) * procedureParam.getPageSize());
|
||||
List<ProcedureDto> procedureDtoList = dbBaseService.getProcedureList(procedureParam);
|
||||
DocDbResponseJson responseJson = DocDbResponseJson.ok(procedureDtoList);
|
||||
if (procedureParam.getPageNum() == 1) {
|
||||
responseJson.setTotal(dbBaseService.getProcedureCount(procedureParam));
|
||||
}
|
||||
return responseJson;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,13 +82,14 @@ public class DbProcedureController {
|
||||
*/
|
||||
@PostMapping(value = "/detail")
|
||||
public ResponseJson detail(Long sourceId, String dbName, String typeName, String procName) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
ProcedureDto procedureDto = dbBaseService.getProcedureDetail(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok(procedureDto);
|
||||
try {
|
||||
ProcedureDto procedureDto = dbBaseService.getProcedureDetail(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok(procedureDto);
|
||||
} catch (Exception e) {
|
||||
// 一般是数据库的帐号没权限查存储过程
|
||||
return DocDbResponseJson.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,13 +103,19 @@ public class DbProcedureController {
|
||||
*/
|
||||
@PostMapping(value = "/delete")
|
||||
public ResponseJson delete(Long sourceId, String dbName, String typeName, String procName) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
|
||||
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, "删除函数操作");
|
||||
try {
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
dbBaseService.deleteProcedure(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok();
|
||||
} catch (Exception e) {
|
||||
dbProcLog.setStatus(2);
|
||||
// 一般是数据库的帐号没权限查存储过程
|
||||
return DocDbResponseJson.error(e.getMessage());
|
||||
} finally {
|
||||
dbProcLogService.save(dbProcLog);
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
dbBaseService.deleteProcedure(sourceId, dbName, typeName, procName);
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,14 +130,93 @@ public class DbProcedureController {
|
||||
*/
|
||||
@PostMapping(value = "/save")
|
||||
public ResponseJson save(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
boolean manageAuth = DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE);
|
||||
if (!manageAuth) {
|
||||
return DocDbResponseJson.warn("没有该数据源的管理权限");
|
||||
this.judgeAuth(sourceId, DbAuthType.PROC_EDIT.getName(), "没有修改该库函数的权限");
|
||||
DbProcLog dbProcLog = this.createDbProcLog(sourceId, dbName, typeName, procName, procSql);
|
||||
try {
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
ExecuteResult executeResult = dbBaseService.saveProcedure(sourceId, dbName, typeName, procName, procSql);
|
||||
if (StringUtils.isNotBlank(executeResult.getErrMsg())) {
|
||||
dbProcLog.setStatus(2);
|
||||
}
|
||||
return DocDbResponseJson.ok(executeResult);
|
||||
} catch (Exception e) {
|
||||
dbProcLog.setStatus(2);
|
||||
// 一般是数据库的帐号没权限查存储过程
|
||||
return DocDbResponseJson.error(e.getMessage());
|
||||
} finally {
|
||||
dbProcLogService.save(dbProcLog);
|
||||
}
|
||||
DbBaseService dbBaseService = dbBaseFactory.getDbBaseService(sourceId);
|
||||
ExecuteResult executeResult = dbBaseService.saveProcedure(sourceId, dbName, typeName, procName, procSql);
|
||||
return DocDbResponseJson.ok(executeResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储过程修改日志列表
|
||||
*
|
||||
* @param sourceId 数据源ID
|
||||
* @param dbName 数据库名
|
||||
* @param typeName 类型名
|
||||
* @param procName 函数名
|
||||
* @return 列表
|
||||
*/
|
||||
@PostMapping(value = "/log/list")
|
||||
public ResponseJson logList(Integer pageNum, Integer pageSize, Long sourceId, String dbName, String typeName, String procName) {
|
||||
QueryWrapper<DbProcLog> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("datasource_id", sourceId);
|
||||
wrapper.eq("proc_db", dbName);
|
||||
wrapper.eq("proc_name", procName);
|
||||
wrapper.eq("proc_type", typeName);
|
||||
wrapper.orderByDesc("id");
|
||||
wrapper.select("id", "proc_body", "create_user_name", "create_time", "status");
|
||||
IPage<DbProcLog> page = new Page<>(pageNum, pageSize, pageNum == 1);
|
||||
dbProcLogService.page(page, wrapper);
|
||||
return DocDbResponseJson.ok(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储过程修改日志详情
|
||||
*
|
||||
* @param logId 日志ID
|
||||
* @return 详情
|
||||
*/
|
||||
@PostMapping(value = "/log/detail")
|
||||
public ResponseJson logDetail(Long logId) {
|
||||
DbProcLog dbProcLog = dbProcLogService.getById(logId);
|
||||
return DocDbResponseJson.ok(dbProcLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限判断
|
||||
*
|
||||
* @author 暮光:城中城
|
||||
*/
|
||||
private void judgeAuth(Long sourceId, String authName, String noAuthInfo) {
|
||||
if (!DocUserUtil.haveAuth(DocAuthConst.DB_DATASOURCE_MANAGE)
|
||||
&& !DocUserUtil.haveCustomAuth(authName, DocAuthConst.DB + sourceId)) {
|
||||
throw new ConfirmException(noAuthInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日志对象
|
||||
* @param sourceId
|
||||
* @param dbName
|
||||
* @param typeName
|
||||
* @param procName
|
||||
* @param procSql
|
||||
* @return
|
||||
*/
|
||||
public DbProcLog createDbProcLog(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
DocUserDetails currentUser = DocUserUtil.getCurrentUser();
|
||||
DbProcLog dbProcLog = new DbProcLog();
|
||||
dbProcLog.setDatasourceId(sourceId);
|
||||
dbProcLog.setCreateTime(new Date());
|
||||
dbProcLog.setCreateUserId(currentUser.getUserId());
|
||||
dbProcLog.setCreateUserName(currentUser.getUsername());
|
||||
dbProcLog.setProcDb(dbName);
|
||||
dbProcLog.setProcName(procName);
|
||||
dbProcLog.setProcType(typeName);
|
||||
dbProcLog.setProcBody(procSql);
|
||||
dbProcLog.setStatus(1);
|
||||
return dbProcLog;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ public class UserDbAuthVo {
|
||||
private Long userId;
|
||||
private Integer executeAuth;
|
||||
private Integer descEditAuth;
|
||||
private Integer procEditAuth;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
@@ -37,4 +38,12 @@ public class UserDbAuthVo {
|
||||
public void setDescEditAuth(Integer descEditAuth) {
|
||||
this.descEditAuth = descEditAuth;
|
||||
}
|
||||
|
||||
public Integer getProcEditAuth() {
|
||||
return procEditAuth;
|
||||
}
|
||||
|
||||
public void setProcEditAuth(Integer procEditAuth) {
|
||||
this.procEditAuth = procEditAuth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ public enum DbAuthType {
|
||||
VIEW(1, "DB_VIEW_"),
|
||||
SELECT(2, "DB_SELECT_"),
|
||||
UPDATE(3, "DB_UPDATE_"),
|
||||
DESC_EDIT(3, "DB_DESC_EDIT_"),
|
||||
DESC_EDIT(4, "DB_DESC_EDIT_"),
|
||||
PROC_EDIT(5, "DB_PROC_EDIT_"),
|
||||
;
|
||||
private Integer type;
|
||||
private String name;
|
||||
|
||||
@@ -66,13 +66,13 @@ public class MysqlServiceImpl extends DbBaseService {
|
||||
// 新建的时候
|
||||
ProcedureDto procedureDetailNew = new ProcedureDto();
|
||||
if (Objects.equals(typeName, "FUNCTION")) {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + procName + "`() RETURNS integer\n" +
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + dbName + "`.`" + procName + "`() RETURNS integer\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"\tRETURN 0;\n" +
|
||||
"END;");
|
||||
} else {
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + procName + "`()\n" +
|
||||
procedureDetailNew.setBody("CREATE DEFINER = CURRENT_USER " + typeName + " `" + dbName + "`.`" + procName + "`()\n" +
|
||||
"BEGIN\n" +
|
||||
"\t#Routine body goes here...\n" +
|
||||
"END;");
|
||||
@@ -85,9 +85,10 @@ public class MysqlServiceImpl extends DbBaseService {
|
||||
// 组装好SQL
|
||||
String type = procedureDetail.getType();
|
||||
String name = procedureDetail.getName();
|
||||
String db = procedureDetail.getDb();
|
||||
String paramList = StringUtils.defaultIfBlank(procedureDetail.getParamList(), "");
|
||||
String[] definerArr = procedureDetail.getDefiner().split("@");
|
||||
String createStr = String.format("CREATE DEFINER=`%s`@`%s` %s `%s`(%s)", definerArr[0], definerArr[1], type, name, paramList);
|
||||
String createStr = String.format("CREATE DEFINER=`%s`@`%s` %s `%s`.`%s`(%s)", definerArr[0], definerArr[1], type, db, name, paramList);
|
||||
if (Objects.equals(procedureDetail.getType(), "FUNCTION")) {
|
||||
createStr += " RETURNS " + procedureDetail.getReturns();
|
||||
}
|
||||
@@ -99,7 +100,7 @@ public class MysqlServiceImpl extends DbBaseService {
|
||||
public ExecuteResult saveProcedure(Long sourceId, String dbName, String typeName, String procName, String procSql) {
|
||||
String firstLine = procSql.split("\n")[0];
|
||||
// 看函数名是否被修改了,修改会导致函数名的不确定,有认知上的成本,明确的先删再建吧
|
||||
if (!firstLine.contains(" `" + procName + "`(") && !firstLine.contains(" " + procName + "(")) {
|
||||
if (!firstLine.contains("`" + procName + "`(") && !firstLine.contains(" " + procName + "(") && !firstLine.contains("." + procName + "(")) {
|
||||
return ExecuteResult.error("在编辑页面不允许修改函数名,如需新建或修改,请到列表页删除后再新建函数", procSql);
|
||||
}
|
||||
ProcedureDto procedureDetail = this.getProcedureDetail(sourceId, dbName, typeName, procName);
|
||||
@@ -121,7 +122,7 @@ public class MysqlServiceImpl extends DbBaseService {
|
||||
executeParam.setSql(procedureDetail.getBody());
|
||||
sqlExecutor.execute(executeParam);
|
||||
} catch (Exception e1) {
|
||||
return ExecuteResult.error("执行和恢复函数均失败,请先备份您的SQL,以防丢失", procSql);
|
||||
return ExecuteResult.error("执行和恢复函数均失败,请先备份您的SQL,以防丢失\n" + e.getMessage(), procSql);
|
||||
}
|
||||
return ExecuteResult.error(e.getMessage(), procSql);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user