refactor(项目管理): 菜单管理配置平台插件,插件key校验
This commit is contained in:
parent
91c6687b5d
commit
e36278861f
|
@ -13,4 +13,10 @@ public interface Platform extends ExtensionPoint {
|
|||
* 服务集成点击校验时调用
|
||||
*/
|
||||
void validateIntegrationConfig();
|
||||
|
||||
/**
|
||||
* 校验项目配置
|
||||
* 项目设置成点击校验项目 key 时调用
|
||||
*/
|
||||
void validateProjectConfig(String projectConfig);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.dto.ModuleDTO;
|
||||
import io.metersphere.project.request.ProjectApplicationRequest;
|
||||
import io.metersphere.project.service.ProjectApplicationService;
|
||||
import io.metersphere.project.service.ProjectService;
|
||||
|
@ -8,7 +9,6 @@ import io.metersphere.sdk.constants.ModuleType;
|
|||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.dto.OptionDTO;
|
||||
import io.metersphere.sdk.dto.SessionUser;
|
||||
import io.metersphere.system.domain.User;
|
||||
import io.metersphere.system.log.annotation.Log;
|
||||
import io.metersphere.system.log.constants.OperationLogType;
|
||||
|
@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.*;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
|
@ -280,22 +279,17 @@ public class ProjectApplicationController {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* ==========全部==========
|
||||
*/
|
||||
|
||||
@GetMapping("/all/{projectId}")
|
||||
@Operation(summary = "全部-获取配置")
|
||||
public List<ProjectApplication> getAll(@PathVariable String projectId) {
|
||||
SessionUser user = Objects.requireNonNull(SessionUtils.getUser());
|
||||
return projectApplicationService.getAllConfigs(user, projectId);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/module-setting/{projectId}")
|
||||
@Operation(summary = "获取菜单列表")
|
||||
public Map<String, Boolean> getModuleSetting(@PathVariable String projectId) {
|
||||
public List<ModuleDTO> getModuleSetting(@PathVariable String projectId) {
|
||||
return projectApplicationService.getModuleSetting(projectId);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/validate/{pluginId}")
|
||||
@Operation(summary = "插件key校验")
|
||||
public void validateProjectConfig(@PathVariable("pluginId") String pluginId, @RequestBody Map configs) {
|
||||
projectApplicationService.validateProjectConfig(pluginId, configs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.metersphere.project.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class ModuleDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "模块", allowableValues = {"WORKSTATION", "TEST_PLAN", "UI", "PERFORMANCE_TEST", "API", "CASE", "ISSUE"})
|
||||
private String module;
|
||||
|
||||
@Schema(description = "是否启用", allowableValues = {"true", "false"})
|
||||
private Boolean moduleEnable;
|
||||
|
||||
public ModuleDTO(String module, Boolean moduleEnable) {
|
||||
this.module = module;
|
||||
this.moduleEnable = moduleEnable;
|
||||
}
|
||||
}
|
|
@ -1,18 +1,22 @@
|
|||
package io.metersphere.project.service;
|
||||
|
||||
import io.metersphere.plugin.platform.api.AbstractPlatformPlugin;
|
||||
import io.metersphere.plugin.platform.api.Platform;
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.domain.ProjectApplicationExample;
|
||||
import io.metersphere.project.dto.ModuleDTO;
|
||||
import io.metersphere.project.job.CleanUpReportJob;
|
||||
import io.metersphere.project.job.IssueSyncJob;
|
||||
import io.metersphere.project.mapper.ExtProjectMapper;
|
||||
import io.metersphere.project.mapper.ExtProjectUserRoleMapper;
|
||||
import io.metersphere.project.mapper.ProjectApplicationMapper;
|
||||
import io.metersphere.project.request.ProjectApplicationRequest;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
import io.metersphere.sdk.constants.OperationLogConstants;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.ScheduleType;
|
||||
import io.metersphere.sdk.dto.LogDTO;
|
||||
import io.metersphere.sdk.dto.OptionDTO;
|
||||
import io.metersphere.sdk.dto.SessionUser;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.domain.*;
|
||||
import io.metersphere.system.log.constants.OperationLogModule;
|
||||
|
@ -21,6 +25,7 @@ import io.metersphere.system.mapper.ExtPluginMapper;
|
|||
import io.metersphere.system.mapper.PluginMapper;
|
||||
import io.metersphere.system.mapper.ServiceIntegrationMapper;
|
||||
import io.metersphere.system.sechedule.ScheduleService;
|
||||
import io.metersphere.system.service.PlatformPluginService;
|
||||
import io.metersphere.system.service.PluginLoadService;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
import io.metersphere.system.utils.SessionUtils;
|
||||
|
@ -34,6 +39,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class ProjectApplicationService {
|
||||
|
@ -60,6 +67,9 @@ public class ProjectApplicationService {
|
|||
@Resource
|
||||
private ExtProjectMapper extProjectMapper;
|
||||
|
||||
@Resource
|
||||
private PlatformPluginService platformPluginService;
|
||||
|
||||
/**
|
||||
* 更新配置信息
|
||||
*
|
||||
|
@ -194,73 +204,6 @@ public class ProjectApplicationService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有配置信息
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public List<ProjectApplication> getAllConfigs(SessionUser user, String projectId) {
|
||||
List<ProjectApplication> list = new ArrayList<>();
|
||||
Boolean flag = checkAdmin(user);
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
ProjectApplicationExample.Criteria criteria = example.createCriteria();
|
||||
criteria.andProjectIdEqualTo(projectId);
|
||||
if (flag) {
|
||||
list = projectApplicationMapper.selectByExample(example);
|
||||
}
|
||||
List<String> types = checkPermission(user);
|
||||
if (CollectionUtils.isNotEmpty(types)) {
|
||||
criteria.andTypeIn(types);
|
||||
list = projectApplicationMapper.selectByExample(example);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> checkPermission(SessionUser user) {
|
||||
List<UserRolePermission> permissions = new ArrayList<>();
|
||||
user.getUserRolePermissions().forEach(g -> {
|
||||
permissions.addAll(g.getUserRolePermissions());
|
||||
});
|
||||
List<String> permissionIds = permissions.stream().map(UserRolePermission::getPermissionId).collect(Collectors.toList());
|
||||
|
||||
List<String> types = new ArrayList<>();
|
||||
permissionIds.forEach(permissionId -> {
|
||||
switch (permissionId) {
|
||||
case PermissionConstants.PROJECT_APPLICATION_WORKSTATION_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.WORKSTATION.values()).stream().map(ProjectApplicationType.WORKSTATION::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_TEST_PLAN_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.TEST_PLAN.values()).stream().map(ProjectApplicationType.TEST_PLAN::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_ISSUE_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.ISSUE.values()).stream().map(ProjectApplicationType.ISSUE::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_CASE_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.CASE.values()).stream().map(ProjectApplicationType.CASE::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_API_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.API.values()).stream().map(ProjectApplicationType.API::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_UI_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.UI.values()).stream().map(ProjectApplicationType.UI::name).collect(Collectors.toList()));
|
||||
case PermissionConstants.PROJECT_APPLICATION_PERFORMANCE_TEST_READ ->
|
||||
types.addAll(Arrays.asList(ProjectApplicationType.PERFORMANCE_TEST.values()).stream().map(ProjectApplicationType.PERFORMANCE_TEST::name).collect(Collectors.toList()));
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
});
|
||||
return types;
|
||||
}
|
||||
|
||||
private Boolean checkAdmin(SessionUser user) {
|
||||
long count = user.getUserRoles()
|
||||
.stream()
|
||||
.filter(g -> StringUtils.equalsIgnoreCase(g.getId(), InternalUserRole.ADMIN.getValue()))
|
||||
.count();
|
||||
|
||||
if (count > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 同步缺陷配置
|
||||
*
|
||||
|
@ -449,6 +392,7 @@ public class ProjectApplicationService {
|
|||
|
||||
/**
|
||||
* 关联需求配置 日志
|
||||
*
|
||||
* @param projectId
|
||||
* @param configs
|
||||
* @return
|
||||
|
@ -469,16 +413,16 @@ public class ProjectApplicationService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
*
|
||||
* @param projectId
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Boolean> getModuleSetting(String projectId) {
|
||||
public List<ModuleDTO> getModuleSetting(String projectId) {
|
||||
String moduleSetting = extProjectMapper.getModuleSetting(projectId);
|
||||
Map<String, Boolean> moudleMap = new HashMap<>();
|
||||
List<ModuleDTO> moduleDTOList = new ArrayList<>();
|
||||
if (StringUtils.isNotEmpty(moduleSetting)) {
|
||||
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||
JSON.parseArray(moduleSetting).forEach(module -> {
|
||||
|
@ -491,8 +435,9 @@ public class ProjectApplicationService {
|
|||
moudleMap.put(String.valueOf(module), Boolean.TRUE);
|
||||
}
|
||||
});
|
||||
moduleDTOList = moudleMap.entrySet().stream().map(entry -> new ModuleDTO(entry.getKey(), entry.getValue())).collect(Collectors.toList());
|
||||
}
|
||||
return moudleMap;
|
||||
return moduleDTOList;
|
||||
}
|
||||
|
||||
|
||||
|
@ -534,4 +479,27 @@ public class ProjectApplicationService {
|
|||
}
|
||||
return collect;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验插件key
|
||||
*
|
||||
* @param pluginId
|
||||
* @param configs
|
||||
*/
|
||||
public void validateProjectConfig(String pluginId, Map configs) {
|
||||
Platform platform = this.getPlatform(pluginId);
|
||||
platform.validateProjectConfig(JSON.toJSONString(configs));
|
||||
}
|
||||
|
||||
private Platform getPlatform(String pluginId) {
|
||||
ServiceIntegrationExample example = new ServiceIntegrationExample();
|
||||
example.createCriteria().andPluginIdEqualTo(pluginId);
|
||||
List<ServiceIntegration> serviceIntegrations = serviceIntegrationMapper.selectByExampleWithBLOBs(example);
|
||||
if (CollectionUtils.isEmpty(serviceIntegrations)) {
|
||||
throw new MSException(NOT_FOUND);
|
||||
}
|
||||
return platformPluginService.getPlatform(pluginId, serviceIntegrations.get(0).getOrganizationId(), new String(serviceIntegrations.get(0).getConfiguration()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,27 @@
|
|||
package io.metersphere.project.controller;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import io.metersphere.project.controller.param.ProjectApplicationDefinition;
|
||||
import io.metersphere.project.controller.param.ProjectApplicationRequestDefinition;
|
||||
import io.metersphere.project.domain.ProjectApplication;
|
||||
import io.metersphere.project.request.ProjectApplicationRequest;
|
||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||
import io.metersphere.sdk.constants.SessionConstants;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import io.metersphere.system.domain.Plugin;
|
||||
import io.metersphere.system.request.PluginUpdateRequest;
|
||||
import io.metersphere.system.request.ServiceIntegrationUpdateRequest;
|
||||
import io.metersphere.system.service.PluginService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -30,9 +29,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.*;
|
||||
|
||||
import static io.metersphere.sdk.constants.InternalUserRole.ADMIN;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
|
@ -462,57 +459,6 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 全部
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static final String GET_ALL_URL = "/project/application/all";
|
||||
|
||||
@Test
|
||||
@Order(33)
|
||||
public void testGetAll() throws Exception {
|
||||
this.loginTest();
|
||||
this.requestGetTest();
|
||||
this.requestGetWithOkAndReturn(GET_ALL_URL + "/" + PROJECT_ID);
|
||||
this.adminlogin();
|
||||
this.requestGetWithOkAndReturn(GET_ALL_URL + "/" + PROJECT_ID);
|
||||
|
||||
}
|
||||
|
||||
private void adminlogin() throws Exception {
|
||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
|
||||
.content("{\"username\":\"admin\",\"password\":\"metersphere\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andReturn();
|
||||
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
|
||||
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
|
||||
}
|
||||
|
||||
private void requestGetTest() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.get(GET_ALL_URL + "/" + PROJECT_ID)
|
||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
||||
.header(SessionConstants.CSRF_TOKEN, csrfToken))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(print());
|
||||
}
|
||||
|
||||
|
||||
public void loginTest() throws Exception {
|
||||
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
|
||||
.content("{\"username\":\"wx-test\",\"password\":\"metersphere\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andReturn();
|
||||
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
|
||||
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
|
||||
}
|
||||
|
||||
|
||||
public Plugin addPlugin() throws Exception {
|
||||
PluginUpdateRequest request = new PluginUpdateRequest();
|
||||
File jarFile = new File(
|
||||
|
@ -571,6 +517,9 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
|||
ResultHolder updateResultHolder = JSON.parseObject(updateData, ResultHolder.class);
|
||||
// 返回请求正常
|
||||
Assertions.assertNotNull(updateResultHolder);
|
||||
|
||||
congifs.remove("CRON_EXPRESSION");
|
||||
this.requestPostWithOkAndReturn(UPDATE_ISSUE_CONFIG_URL + "/default-project-2", congifs);
|
||||
}
|
||||
|
||||
private Map<String, String> mockTeseData() {
|
||||
|
@ -602,6 +551,7 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
|||
@Test
|
||||
@Order(36)
|
||||
public void testGetModuleSetting() throws Exception {
|
||||
this.requestGetWithOkAndReturn(GET_MODULE_SETTING_URL + "/100001100002");
|
||||
MvcResult mvcResult = this.requestGetWithOkAndReturn(GET_MODULE_SETTING_URL + "/100001100001");
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
|
@ -622,8 +572,6 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static final String UPDATE_CASE_RELATED_CONFIG_URL = "/project/application/update/case/related";
|
||||
public static final String GET_CASE_RELATED_CONFIG_INFO_URL = "/project/application/case/related/info";
|
||||
|
||||
|
@ -669,4 +617,43 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
|||
// 返回请求正常
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
}
|
||||
|
||||
|
||||
public static final String CHECK_PROJECT_KEY_URL = "/project/application/validate";
|
||||
|
||||
@Test
|
||||
@Order(39)
|
||||
public void testCheckProjectKey() throws Exception {
|
||||
Map<String, String> configs = new HashMap<>();
|
||||
configs.put("jiraKey", "Test");
|
||||
configs.put("jiraIssueTypeId", "10086");
|
||||
configs.put("jiraStoryTypeId", "10010");
|
||||
assertErrorCode(this.requestPost(CHECK_PROJECT_KEY_URL + "/" + plugin.getId(), configs), NOT_FOUND);
|
||||
JiraIntegrationConfig integrationConfig = new JiraIntegrationConfig();
|
||||
Map<String, Object> integrationConfigMap = JSON.parseMap(JSON.toJSONString(integrationConfig));
|
||||
ServiceIntegrationUpdateRequest request = new ServiceIntegrationUpdateRequest();
|
||||
request.setEnable(true);
|
||||
request.setPluginId(plugin.getId());
|
||||
request.setConfiguration(integrationConfigMap);
|
||||
request.setOrganizationId("100001100001");
|
||||
this.requestPostWithOkAndReturn("/service/integration/add", request);
|
||||
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(CHECK_PROJECT_KEY_URL + "/" + plugin.getId(), configs);
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
// 返回请求正常
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class JiraIntegrationConfig {
|
||||
private String account;
|
||||
private String password;
|
||||
private String token;
|
||||
private String authType;
|
||||
private String address;
|
||||
private String version;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue