From fbe9fbab2ac9aa9e60fde0f4411e6a484a8cf1c8 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Wed, 13 Dec 2023 15:20:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95=E5=A2=9E=E5=8A=A0=E6=89=80?= =?UTF-8?q?=E5=B1=9E=E8=B5=84=E6=BA=90=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/ApiDefinitionController.java | 5 ++ .../definition/ApiTestCaseController.java | 5 ++ .../scenario/ApiScenarioController.java | 6 ++ .../scenario/ApiScenarioReportController.java | 4 ++ .../service/ApiCheckPermissionService.java | 59 +++++++++++++++++++ .../resources/i18n/commons_en_US.properties | 1 + .../resources/i18n/commons_zh_CN.properties | 1 + .../resources/i18n/commons_zh_TW.properties | 1 + 8 files changed, 82 insertions(+) create mode 100644 api-test/backend/src/main/java/io/metersphere/service/ApiCheckPermissionService.java diff --git a/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiDefinitionController.java b/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiDefinitionController.java index c97b49eb29..fbfc248181 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiDefinitionController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiDefinitionController.java @@ -31,6 +31,7 @@ import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsRequestLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.request.ResetOrderRequest; +import io.metersphere.security.CheckOwner; import io.metersphere.service.definition.ApiDefinitionService; import io.metersphere.service.definition.FunctionRunService; import jakarta.annotation.Resource; @@ -113,6 +114,7 @@ public class ApiDefinitionController { @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_API) @MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = ApiDefinitionService.class) // @SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, event = NoticeConstants.Event.UPDATE, subject = "接口定义通知") + @CheckOwner(resourceId = "#request.id", resourceType = "api_definition") public ApiDefinitionResult update(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files", required = false) List bodyFiles) { return apiDefinitionService.update(request, bodyFiles); } @@ -120,6 +122,7 @@ public class ApiDefinitionController { @GetMapping("/delete/{id}") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_API) @MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.DELETE, beforeEvent = "#msClass.getLogDetails(#id)", msClass = ApiDefinitionService.class) + @CheckOwner(resourceId = "#id", resourceType = "api_definition") public void delete(@PathVariable String id) { apiDefinitionService.delete(id); } @@ -127,6 +130,7 @@ public class ApiDefinitionController { @PostMapping("/del-ids") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_API) @MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.BATCH_DEL, beforeEvent = "#msClass.getLogDetails(#request.ids)", msClass = ApiDefinitionService.class) + @CheckOwner(resourceId = "#ids", resourceType = "api_definition") public void deleteBatch(@RequestBody List ids) { apiDefinitionService.deleteBatch(ids); } @@ -149,6 +153,7 @@ public class ApiDefinitionController { @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_API) @MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiDefinitionService.class) @SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, target = "#targetClass.getBLOBs(#ids)", targetClass = ApiDefinitionService.class, event = NoticeConstants.Event.DELETE, subject = "接口定义通知") + @CheckOwner(resourceId = "#ids", resourceType = "api_definition") public void removeToGc(@RequestBody List ids) { apiDefinitionService.removeToGc(ids); } diff --git a/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiTestCaseController.java b/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiTestCaseController.java index 1c8b5fb475..9d8472863a 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiTestCaseController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/definition/ApiTestCaseController.java @@ -18,6 +18,7 @@ import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsRequestLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.request.ResetOrderRequest; +import io.metersphere.security.CheckOwner; import io.metersphere.service.definition.ApiDefinitionExecResultService; import io.metersphere.service.definition.ApiTestCaseService; import io.metersphere.service.scenario.ApiScenarioService; @@ -126,6 +127,7 @@ public class ApiTestCaseController { @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_CASE) @MsAuditLog(module = OperLogModule.API_DEFINITION_CASE, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request)", title = "#request.name", content = "#msClass.getLogDetails(#request)", msClass = ApiTestCaseService.class) @SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, event = NoticeConstants.Event.CASE_UPDATE, subject = "接口用例通知") + @CheckOwner(resourceId = "#request.id", resourceType = "api_test_case") public ApiTestCase update(@RequestPart("request") SaveApiTestCaseRequest request, @RequestPart(value = "files", required = false) List bodyFiles) { return apiTestCaseService.update(request, bodyFiles); } @@ -140,6 +142,7 @@ public class ApiTestCaseController { @GetMapping("/delete/{id}") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_CASE) @MsAuditLog(module = OperLogModule.API_DEFINITION_CASE, type = OperLogConstants.DELETE, beforeEvent = "#msClass.getLogDetails(#id)", msClass = ApiTestCaseService.class) + @CheckOwner(resourceId = "#id", resourceType = "api_test_case") public void delete(@PathVariable String id) { apiTestCaseService.delete(id); } @@ -148,6 +151,7 @@ public class ApiTestCaseController { @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_CASE) @MsAuditLog(module = OperLogModule.API_DEFINITION_CASE, type = OperLogConstants.DELETE, beforeEvent = "#msClass.getLogDetails(#id)", msClass = ApiTestCaseService.class) @SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, event = NoticeConstants.Event.CASE_DELETE, target = "#targetClass.get(#id)", targetClass = ApiTestCaseService.class, subject = "接口用例通知") + @CheckOwner(resourceId = "#id", resourceType = "api_test_case") public void deleteToGc(@PathVariable String id) { apiTestCaseService.deleteToGc(id); } @@ -188,6 +192,7 @@ public class ApiTestCaseController { @PostMapping("/del-ids") @RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_DELETE_CASE) @MsAuditLog(module = OperLogModule.API_DEFINITION_CASE, type = OperLogConstants.BATCH_DEL, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiTestCaseService.class) + @CheckOwner(resourceId = "#ids", resourceType = "api_test_case") public void deleteBatch(@RequestBody List ids) { apiTestCaseService.deleteBatch(ids); } diff --git a/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioController.java b/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioController.java index 384df26cfe..ef3529bf36 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioController.java @@ -22,6 +22,7 @@ import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsRequestLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.request.ResetOrderRequest; +import io.metersphere.security.CheckOwner; import io.metersphere.service.ext.ExtApiTaskService; import io.metersphere.service.scenario.ApiScenarioService; import io.metersphere.task.dto.TaskRequestDTO; @@ -131,6 +132,7 @@ public class ApiScenarioController { @MsAuditLog(module = OperLogModule.API_AUTOMATION, type = OperLogConstants.UPDATE, beforeEvent = "#msClass.getLogDetails(#request.id)", title = "#request.name", content = "#msClass.getLogDetails(#request.id)", msClass = ApiScenarioService.class) @RequiresPermissions(value = {PermissionConstants.PROJECT_API_SCENARIO_READ_EDIT, PermissionConstants.PROJECT_API_SCENARIO_READ_COPY}, logical = Logical.OR) @SendNotice(taskType = NoticeConstants.TaskType.API_AUTOMATION_TASK, event = NoticeConstants.Event.UPDATE, subject = "接口自动化通知") + @CheckOwner(resourceId = "#request.id", resourceType = "api_scenario") public ApiScenario update(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "bodyFiles", required = false) List bodyFiles, @RequestPart(value = "scenarioFiles", required = false) List scenarioFiles) { return apiAutomationService.update(request, bodyFiles, scenarioFiles); } @@ -144,6 +146,7 @@ public class ApiScenarioController { @GetMapping("/delete/{id}") @MsAuditLog(module = OperLogModule.API_AUTOMATION, type = OperLogConstants.DELETE, beforeEvent = "#msClass.getLogDetails(#id)", msClass = ApiScenarioService.class) @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_DELETE) + @CheckOwner(resourceId = "#id", resourceType = "api_scenario") public void delete(@PathVariable String id) { apiAutomationService.delete(id); } @@ -152,6 +155,7 @@ public class ApiScenarioController { @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_DELETE) @MsAuditLog(module = OperLogModule.API_AUTOMATION, type = OperLogConstants.BATCH_DEL, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiScenarioService.class) @SendNotice(taskType = NoticeConstants.TaskType.API_AUTOMATION_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.getScenarioCaseByIds(#ids)", targetClass = ApiScenarioService.class, subject = "接口自动化通知") + @CheckOwner(resourceId = "#ids", resourceType = "api_scenario") public void deleteBatch(@RequestBody List ids) { apiAutomationService.deleteBatch(ids); } @@ -166,6 +170,7 @@ public class ApiScenarioController { @RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ_DELETE) @MsAuditLog(module = OperLogModule.API_AUTOMATION, type = OperLogConstants.GC, beforeEvent = "#msClass.getLogDetails(#ids)", msClass = ApiScenarioService.class) @SendNotice(taskType = NoticeConstants.TaskType.API_AUTOMATION_TASK, target = "#targetClass.getScenarioCaseByIds(#ids)", targetClass = ApiScenarioService.class, event = NoticeConstants.Event.DELETE, subject = "接口自动化通知") + @CheckOwner(resourceId = "#ids", resourceType = "api_scenario") public void removeToGc(@RequestBody List ids) { apiAutomationService.removeToGc(ids); } @@ -192,6 +197,7 @@ public class ApiScenarioController { @GetMapping("/scenario-details/{id}") @RequiresPermissions(value ={PermissionConstants.PROJECT_API_SCENARIO_READ, PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_CASE}, logical = Logical.OR) + @CheckOwner(resourceId = "#id", resourceType = "api_scenario") public ApiScenarioDTO getScenarioDefinition(@PathVariable String id) { return apiAutomationService.getNewApiScenario(id); } diff --git a/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioReportController.java b/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioReportController.java index eedb342f26..6daab3dbe3 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioReportController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/scenario/ApiScenarioReportController.java @@ -18,6 +18,7 @@ import io.metersphere.dto.PlanReportCaseDTO; import io.metersphere.dto.RequestResult; import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.notice.annotation.SendNotice; +import io.metersphere.service.ApiCheckPermissionService; import io.metersphere.service.ShareInfoService; import io.metersphere.service.scenario.ApiScenarioReportService; import jakarta.annotation.Resource; @@ -35,6 +36,8 @@ public class ApiScenarioReportController { private ApiScenarioReportService apiReportService; @Resource private ShareInfoService shareInfoService; + @Resource + private ApiCheckPermissionService apiCheckPermissionService; @GetMapping("/get/{reportId}") public ApiScenarioReportResult get(@PathVariable String reportId) { @@ -76,6 +79,7 @@ public class ApiScenarioReportController { @SendNotice(taskType = NoticeConstants.TaskType.API_REPORT_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.get(#request.id, false)", targetClass = ApiScenarioReportService.class, subject = "接口报告通知") public void delete(@RequestBody DeleteAPIReportRequest request) { + apiCheckPermissionService.checkReportOwner(request.getId(), PermissionConstants.PROJECT_API_REPORT_READ_DELETE); apiReportService.delete(request); } diff --git a/api-test/backend/src/main/java/io/metersphere/service/ApiCheckPermissionService.java b/api-test/backend/src/main/java/io/metersphere/service/ApiCheckPermissionService.java new file mode 100644 index 0000000000..fdb2daf1f8 --- /dev/null +++ b/api-test/backend/src/main/java/io/metersphere/service/ApiCheckPermissionService.java @@ -0,0 +1,59 @@ +package io.metersphere.service; + + +import io.metersphere.base.domain.ApiDefinitionExecResultWithBLOBs; +import io.metersphere.base.domain.ApiScenarioReportWithBLOBs; +import io.metersphere.base.mapper.ApiDefinitionExecResultMapper; +import io.metersphere.base.mapper.ApiScenarioReportMapper; +import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.SessionUtils; +import io.metersphere.i18n.Translator; +import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Set; + +@Service +@Transactional(rollbackFor = Exception.class) +public class ApiCheckPermissionService { + + @Resource + private ApiScenarioReportMapper apiScenarioReportMapper; + @Resource + private ApiDefinitionExecResultMapper apiDefinitionExecResultMapper; + @Resource + private BaseCheckPermissionService baseCheckPermissionService; + public void checkReportOwner(String reportId, String permissionId) { + Set projectIds = baseCheckPermissionService.getUserRelatedProjectIds(); + if (CollectionUtils.isEmpty(projectIds)) { + return; + } + ApiScenarioReportWithBLOBs scenarioReport = apiScenarioReportMapper.selectByPrimaryKey(reportId); + ApiDefinitionExecResultWithBLOBs apiReport = apiDefinitionExecResultMapper.selectByPrimaryKey(reportId); + if (scenarioReport == null) { + if (apiReport == null) { + MSException.throwException(Translator.get("check_owner_report")); + } + MSException.throwException(Translator.get("check_owner_report")); + } + if (scenarioReport != null) { + if (!projectIds.contains(scenarioReport.getProjectId())) { + MSException.throwException(Translator.get("check_owner_report")); + } + if (SessionUtils.hasPermission(null, scenarioReport.getProjectId(), permissionId)) { + MSException.throwException(Translator.get("check_owner_report")); + } + } + if (apiReport != null) { + if (!projectIds.contains(apiReport.getProjectId())) { + MSException.throwException(Translator.get("check_owner_report")); + } + if (SessionUtils.hasPermission(null, apiReport.getProjectId(), permissionId)) { + MSException.throwException(Translator.get("check_owner_report")); + } + } + } + +} diff --git a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_en_US.properties b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_en_US.properties index f19d6d836f..bded0b7dc1 100644 --- a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_en_US.properties +++ b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_en_US.properties @@ -237,6 +237,7 @@ check_owner_test=The current user does not have permission to operate this test check_owner_case=The current user does not have permission to operate this use case check_owner_plan=The current user does not have permission to operate this plan check_owner_review=The current user does not have permission to operate this review +check_owner_report=The current user does not have permission to operate this report check_owner_comment=The current user does not have permission to manipulate this comment check_owner_workspace=The current user does not have permission to operate this workspace upload_content_is_null=Imported content is empty diff --git a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_CN.properties b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_CN.properties index 8100c9f2f4..2a05e32261 100644 --- a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_CN.properties +++ b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_CN.properties @@ -236,6 +236,7 @@ check_owner_project=当前用户没有操作此项目的权限 check_owner_test=当前用户没有操作此测试的权限 check_owner_case=当前用户没有操作此用例的权限 check_owner_plan=当前用户没有操作此计划的权限 +check_owner_report=当前用户没有操作此报告的权限 check_owner_review=当前用户没有操作此评审的权限 check_owner_comment=当前用户没有操作此评论的权限 check_owner_workspace=当前用户没有操作此工作空间的权限 diff --git a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_TW.properties b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_TW.properties index 12676d3b5f..c140e10a88 100644 --- a/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_TW.properties +++ b/framework/sdk-parent/sdk/src/main/resources/i18n/commons_zh_TW.properties @@ -234,6 +234,7 @@ test_track.length_less_than=標題過長,字數必須小於 check_owner_project=當前用戶沒有操作此項目的權限 check_owner_test=當前用戶沒有操作此測試的權限 check_owner_case=當前用戶沒有操作此用例的權限 +check_owner_report=當前用戶沒有操作此報告的權限 check_owner_plan=當前用戶沒有操作此計劃的權限 check_owner_review=當前用戶沒有操作此評審的權限 check_owner_comment=當前用戶沒有操作此評論的權限