diff --git a/backend/framework/plugin/metersphere-platform-plugin-sdk/src/main/java/io/metersphere/plugin/platform/api/Platform.java b/backend/framework/plugin/metersphere-platform-plugin-sdk/src/main/java/io/metersphere/plugin/platform/api/Platform.java index 868e1e563b..90154560dd 100644 --- a/backend/framework/plugin/metersphere-platform-plugin-sdk/src/main/java/io/metersphere/plugin/platform/api/Platform.java +++ b/backend/framework/plugin/metersphere-platform-plugin-sdk/src/main/java/io/metersphere/plugin/platform/api/Platform.java @@ -13,4 +13,10 @@ public interface Platform extends ExtensionPoint { * 服务集成点击校验时调用 */ void validateIntegrationConfig(); + + /** + * 校验项目配置 + * 项目设置成点击校验项目 key 时调用 + */ + void validateProjectConfig(String projectConfig); } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectApplicationController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectApplicationController.java index b09e23ccb7..a8be387ae2 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectApplicationController.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectApplicationController.java @@ -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 getAll(@PathVariable String projectId) { - SessionUser user = Objects.requireNonNull(SessionUtils.getUser()); - return projectApplicationService.getAllConfigs(user, projectId); - } - - @GetMapping("/module-setting/{projectId}") @Operation(summary = "获取菜单列表") - public Map getModuleSetting(@PathVariable String projectId) { + public List 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); + } + } diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/dto/ModuleDTO.java b/backend/services/project-management/src/main/java/io/metersphere/project/dto/ModuleDTO.java new file mode 100644 index 0000000000..bd235dddac --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/dto/ModuleDTO.java @@ -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; + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectApplicationService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectApplicationService.java index 1adcc67fa4..e78235fdbc 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectApplicationService.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectApplicationService.java @@ -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 getAllConfigs(SessionUser user, String projectId) { - List 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 types = checkPermission(user); - if (CollectionUtils.isNotEmpty(types)) { - criteria.andTypeIn(types); - list = projectApplicationMapper.selectByExample(example); - } - return list; - } - - private List checkPermission(SessionUser user) { - List permissions = new ArrayList<>(); - user.getUserRolePermissions().forEach(g -> { - permissions.addAll(g.getUserRolePermissions()); - }); - List permissionIds = permissions.stream().map(UserRolePermission::getPermissionId).collect(Collectors.toList()); - - List 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 getModuleSetting(String projectId) { + public List getModuleSetting(String projectId) { String moduleSetting = extProjectMapper.getModuleSetting(projectId); Map moudleMap = new HashMap<>(); + List 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 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())); + } + } diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectApplicationControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectApplicationControllerTests.java index b15566e268..999f4ab74e 100644 --- a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectApplicationControllerTests.java +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectApplicationControllerTests.java @@ -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,12 +29,10 @@ 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) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @AutoConfigureMockMvc public class ProjectApplicationControllerTests extends BaseTest { @@ -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 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 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 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; + } } diff --git a/backend/services/project-management/src/test/resources/file/metersphere-jira-plugin-3.x.jar b/backend/services/project-management/src/test/resources/file/metersphere-jira-plugin-3.x.jar index c19d1732dc..a21de39d93 100644 Binary files a/backend/services/project-management/src/test/resources/file/metersphere-jira-plugin-3.x.jar and b/backend/services/project-management/src/test/resources/file/metersphere-jira-plugin-3.x.jar differ