Przeglądaj źródła

feat: 支持 desc show select sql的结果展示,支持batch执行sql,支持执行sql前鉴权

370774330@qq.com 5 lat temu
rodzic
commit
ddc4f62d2e

+ 3 - 2
web/src/main/java/cn/seecoder/web/controller/sql/SqlController.java

@@ -1,5 +1,6 @@
 package cn.seecoder.web.controller.sql;
 
+import cn.seecoder.common.exceptions.AccessDeniedException;
 import cn.seecoder.web.model.vo.Response;
 import cn.seecoder.web.model.vo.sql.SqlExecVO;
 import cn.seecoder.web.service.sql.SqlService;
@@ -35,7 +36,7 @@ public class SqlController {
     @ApiOperation(value = "执行sql", httpMethod = "POST")
     @PostMapping("/exec")
     @ApiImplicitParam(name = "projectCreateVO",dataType = "object", paramType = "body")
-    public Response<String> exec(@RequestBody SqlExecVO sqlExecVO) {
-        return Response.buildSuccess(sqlService.execute(sqlExecVO.getUrl(), sqlExecVO.getDb(),sqlExecVO.getUsername(),sqlExecVO.getPassword(),sqlExecVO.getSql()));
+    public Response<String> exec(@RequestBody SqlExecVO sqlExecVO) throws AccessDeniedException {
+        return Response.buildSuccess(sqlService.execute(sqlExecVO.getDeploymentId(), sqlExecVO.getDb(),sqlExecVO.getUsername(),sqlExecVO.getPassword(),sqlExecVO.getSql()));
     }
 }

+ 3 - 0
web/src/main/java/cn/seecoder/web/dao/pipeline/DeploymentMapper.java

@@ -22,6 +22,9 @@ public interface DeploymentMapper {
     @UpdateProvider(type= GeneralInsertUpdateSqlProvider.class, method="updateById")
     int update(DeploymentPO deploymentPO);
 
+    @Select("select * from deployment where id = #{id}")
+    DeploymentPO selectById(Integer id);
+
     @Select("select * from deployment where pipeline_id = #{pipelineId}")
     DeploymentPO selectByPipelineId(Integer pipelineId);
 

+ 2 - 2
web/src/main/java/cn/seecoder/web/model/vo/sql/SqlExecVO.java

@@ -9,8 +9,8 @@ import lombok.Data;
 @ApiModel("SQL执行表达")
 public class SqlExecVO {
 
-    @ApiModelProperty("数据库url,例子: 192.123.13.11")
-    String url;
+    @ApiModelProperty("部署实例id")
+    Integer deploymentId;
 
     @ApiModelProperty("连接的db名称, 默认为空")
     String db = "";

+ 44 - 4
web/src/main/java/cn/seecoder/web/service/impl/sql/SqlServiceImpl.java

@@ -1,11 +1,18 @@
 package cn.seecoder.web.service.impl.sql;
 
+import cn.seecoder.common.exceptions.AccessDeniedException;
+import cn.seecoder.web.dao.pipeline.DeploymentMapper;
+import cn.seecoder.web.dao.pipeline.PipelineMapper;
+import cn.seecoder.web.model.po.pipeline.DeploymentPO;
 import cn.seecoder.web.service.sql.SqlService;
+import cn.seecoder.web.service.user.UserService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.sql.*;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
@@ -17,18 +24,51 @@ public class SqlServiceImpl implements SqlService {
 
     private static final String DB_URL_SUFFIX = "?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false";
 
+    private final DeploymentMapper deploymentMapper;
+
+    private final PipelineMapper pipelineMapper;
+
+    @Autowired
+    public SqlServiceImpl(DeploymentMapper deploymentMapper, PipelineMapper pipelineMapper) {
+        this.deploymentMapper = deploymentMapper;
+        this.pipelineMapper = pipelineMapper;
+    }
+
     @Override
-    public String execute(String url, String db,String username, String password, String sql) {
+    public String execute(Integer deploymentId, String db,String username, String password, String sql) throws AccessDeniedException {
+
+        sql = sql.trim();
+        if (sql.endsWith(";")){
+            sql = sql.substring(0,sql.length()-1);
+        }
+
+        DeploymentPO deployment = deploymentMapper.selectById(deploymentId);
+        UserService.projectAuthentication(pipelineMapper.selectById(deployment.getPipelineId()).getProjectId());
+        String url = deploymentMapper.selectById(deploymentId).getAccessUrl();
+
         String dbUrl = DB_URL_PREFIX + url + "/" + db + DB_URL_SUFFIX;
         try(Connection conn = DriverManager.getConnection(dbUrl, username, password);
             Statement stmt = conn.createStatement();
         ) {
-            //只有select语句需要解析 resultset
-            if ("select".equals(sql.trim().substring(0,6).toLowerCase(Locale.ROOT))){
+            //select query desc走query 其他走update
+            String prefix = sql.substring(0, sql.indexOf(" ")).toLowerCase(Locale.ROOT);
+
+            if ("select".equals(prefix) || "show".equals(prefix) || "desc".equals(prefix)){
                 ResultSet rs = stmt.executeQuery(sql);
                 return "Boolean\n"+ convertResultSet2List(rs);
             } else {
-                return "Boolean\n";
+                //batch执行,注意;不要用于
+                if (sql.contains(";")){
+                    String[] batches = sql.split(";");
+                    for (String tmp : batches){
+                        stmt.addBatch(tmp);
+                    }
+                    int[] res = stmt.executeBatch();
+                    return "Boolean\nAffected :"+ Arrays.toString(res);
+                } else {
+                    int i = stmt.executeUpdate(sql);
+                    return "Boolean\nAffected :"+i;
+                }
             }
 
         } catch (SQLException e) {

+ 2 - 1
web/src/main/java/cn/seecoder/web/service/sql/SqlService.java

@@ -1,9 +1,10 @@
 package cn.seecoder.web.service.sql;
 
 
+import cn.seecoder.common.exceptions.AccessDeniedException;
 
 public interface SqlService {
 
-    String execute(String url, String db, String username, String password,String sql);
+    String execute(Integer deploymentId, String db, String username, String password,String sql) throws AccessDeniedException;
 
 }

+ 20 - 10
web/src/main/java/cn/seecoder/web/service/user/UserService.java

@@ -1,14 +1,19 @@
 package cn.seecoder.web.service.user;
 
 
-import cn.seecoder.web.model.po.user.UserPO;
-import cn.seecoder.web.model.vo.user.GitlabUserCreateVO;
-import com.nju.edu.gitlab.SeecoderGitlabApi;
-import org.springframework.security.core.context.SecurityContextHolder;
 import cn.seecoder.common.exceptions.AccessDeniedException;
 import cn.seecoder.common.exceptions.ServiceException;
 import cn.seecoder.common.util.SpringUtil;
+import cn.seecoder.web.model.po.user.UserPO;
+import cn.seecoder.web.model.vo.user.GitlabUserCreateVO;
 import cn.seecoder.web.model.vo.user.UserVO;
+import com.nju.edu.gitlab.SeecoderGitlabApi;
+import com.nju.edu.gitlab.SeecoderGitlabException;
+import com.nju.edu.gitlab.vo.ProjectVO;
+import org.apache.http.HttpStatus;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import java.util.List;
 
 public interface UserService {
 
@@ -30,13 +35,18 @@ public interface UserService {
      * todo 所有涉及项目、用户的功能都必须查看此用户有无此项目的权限
      *  但是gitlab那边接口没测所以没有办法
      */
-    static void projectAuthentication(Integer projectId) throws AccessDeniedException {
+    static void projectAuthentication(Integer projectId) throws ServiceException {
         UserPO userPO = UserService.loginUser();
-        //todo gitlab获取
         SeecoderGitlabApi seecoderGitlabApi = SpringUtil.getBean(SeecoderGitlabApi.class);
-        //List<ProjectPO> projectPOS = SpringUtil.getBean(ProjectMapper.class).listProjectsByUserId(userPO.getId());
-//        if (projectPOS.stream().noneMatch(project -> project.getId()==projectId)){
-//            throw new AccessDeniedException("您没有操作此项目的权限");
-//        }
+        try {
+            List<ProjectVO> projects = seecoderGitlabApi.getAllProjectsByUserId(userPO.getId());
+            if (projects.stream().noneMatch(project -> project.getProjectId()==projectId)){
+                throw new AccessDeniedException("您没有操作此项目的权限");
+            }
+        } catch (SeecoderGitlabException e) {
+            e.printStackTrace();
+            throw new ServiceException(HttpStatus.SC_SERVICE_UNAVAILABLE, e);
+        }
+
     }
 }