diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java index 0a0796d3c2..1b8e6e39c0 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java @@ -34,6 +34,14 @@ public class PermissionConstants { public static final String ORGANIZATION_MEMBER_DELETE = "ORGANIZATION_MEMBER:READ+DELETE"; /*------ end: ORGANIZATION_MEMBER ------*/ + /*------ start: ORGANIZATION_PROJECT ------*/ + public static final String ORGANIZATION_PROJECT_READ = "ORGANIZATION_PROJECT:READ"; + public static final String ORGANIZATION_PROJECT_READ_ADD = "ORGANIZATION_PROJECT:READ+ADD"; + public static final String ORGANIZATION_PROJECT_READ_UPDATE = "ORGANIZATION_PROJECT:READ+UPDATE"; + public static final String ORGANIZATION_PROJECT_READ_DELETE = "ORGANIZATION_PROJECT:READ+DELETE"; + public static final String ORGANIZATION_PROJECT_READ_RECOVER = "ORGANIZATION_PROJECT:READ+RECOVER"; + /*------ end: ORGANIZATION_PROJECT ------*/ + /*------ start: SYSTEM_PLUGIN ------*/ public static final String SYSTEM_PLUGIN_READ = "SYSTEM_PLUGIN_READ:READ"; public static final String SYSTEM_PLUGIN_ADD = "SYSTEM_PLUGIN_READ:READ+ADD"; diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/AddProjectRequest.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/AddProjectRequest.java index 0f17a2267e..0e5a9781b0 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/AddProjectRequest.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/dto/AddProjectRequest.java @@ -1,6 +1,7 @@ package io.metersphere.sdk.dto; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; @@ -10,6 +11,10 @@ import java.util.List; @EqualsAndHashCode(callSuper = false) public class AddProjectRequest extends ProjectBaseRequest { + @Schema(title = "项目ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + @Size(min = 1, max = 50, message = "{project.id.length_range}") + private String id; + @Schema(title = "成员数", requiredMode = Schema.RequiredMode.NOT_REQUIRED) private List userIds; } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/constants/OperationLogModule.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/constants/OperationLogModule.java index 5404922ae8..15eebb175f 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/constants/OperationLogModule.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/log/constants/OperationLogModule.java @@ -52,4 +52,5 @@ public class OperationLogModule { public static final String SYSTEM_PLUGIN = "SYSTEM_PLUGIN"; public static final String SYSTEM_PROJECT = "SYSTEM_PROJECT"; public static final String SYSTEM_PROJECT_MEMBER = "SYSTEM_PROJECT_MEMBER"; + public static final String ORGANIZATION_PROJECT = "ORGANIZATION_PROJECT"; } diff --git a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties index e6c7060fbe..a2c5039b11 100644 --- a/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/project_zh_CN.properties @@ -52,8 +52,8 @@ project_extend.project_id.not_blank=项目ID不能为空 project_extend.platform.length_range=平台长度必须在{min}-{max}之间 project_extend.platform.not_blank=平台不能为空 project.id.not_blank=ID不能为空 -project.organization_id.length_range=工作空间ID长度必须在{min}-{max}之间 -project.organization_id.not_blank=工作空间ID不能为空 +project.organization_id.length_range=组织ID长度必须在{min}-{max}之间 +project.organization_id.not_blank=组织ID不能为空 project.name.length_range=名称长度必须在{min}-{max}之间 project.name.not_blank=名称不能为空 custom_function.id.not_blank=ID不能为空 diff --git a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties index a68d385105..de057165ef 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_zh_CN.properties @@ -132,11 +132,11 @@ user_role_relation.role_id.not_blank=用户组关系用户组ID不能为空 user_role_relation.role_id.length_range=用户组关系用户组ID长度必须在{min}和{max}之间 user_role_relation.source_id.not_blank=用户组关系来源ID不能为空 user_role_relation.source_id.length_range=用户组关系来源ID长度必须在{min}和{max}之间 -organization.id.not_blank=工作空间ID不能为空 -organization.name.not_blank=工作空间名称不能为空 -organization.name.length_range=工作空间名称长度必须在{min}和{max}之间 -organization.create_user.not_blank=工作空间创建人不能为空 -organization.create_user.length_range=工作空间创建人长度必须在{min}和{max}之间 +organization.id.not_blank=组织ID不能为空 +organization.name.not_blank=组织名称不能为空 +organization.name.length_range=组织名称长度必须在{min}和{max}之间 +organization.create_user.not_blank=组织创建人不能为空 +organization.create_user.length_range=组织创建人长度必须在{min}和{max}之间 and_add_organization_admin=并添加组织管理员 organization_add_member_ids_empty=组织添加成员不能为空 organization_not_exist=组织不存在 diff --git a/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties b/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties index 05c3f9fd76..d281690771 100644 --- a/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties +++ b/backend/framework/sdk/src/main/resources/i18n/system_zh_TW.properties @@ -132,11 +132,11 @@ user_role_relation.role_id.not_blank=用戶組關係用戶組ID不能為空 user_role_relation.role_id.length_range=用戶組關係用戶組ID長度必須在{min}和{max}之間 user_role_relation.source_id.not_blank=用戶組關係來源ID不能為空 user_role_relation.source_id.length_range=用戶組關係來源ID長度必須在{min}和{max}之間 -organization.id.not_blank=工作空間ID不能為空 -organization.name.not_blank=工作空間名稱不能為空 -organization.name.length_range=工作空間名稱長度必須在{min}和{max}之間 -organization.create_user.not_blank=工作空間創建人不能為空 -organization.create_user.length_range=工作空間創建人長度必須在{min}和{max}之間 +organization.id.not_blank=組織ID不能為空 +organization.name.not_blank=組織名稱不能為空 +organization.name.length_range=組織名稱長度必須在{min}和{max}之間 +organization.create_user.not_blank=組織創建人不能為空 +organization.create_user.length_range=組織創建人長度必須在{min}和{max}之間 and_add_organization_admin=並添加組織管理員 organization_add_member_ids_empty=組織添加成員不能爲空 organization_not_exist=組織不存在 diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationProjectController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationProjectController.java new file mode 100644 index 0000000000..28d4f3615a --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/OrganizationProjectController.java @@ -0,0 +1,128 @@ +package io.metersphere.system.controller; + + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import io.metersphere.project.domain.Project; +import io.metersphere.sdk.constants.PermissionConstants; +import io.metersphere.sdk.dto.AddProjectRequest; +import io.metersphere.sdk.dto.ProjectDTO; +import io.metersphere.sdk.dto.UpdateProjectRequest; +import io.metersphere.sdk.log.annotation.Log; +import io.metersphere.sdk.log.constants.OperationLogType; +import io.metersphere.sdk.util.PageUtils; +import io.metersphere.sdk.util.Pager; +import io.metersphere.sdk.util.SessionUtils; +import io.metersphere.system.dto.UserExtend; +import io.metersphere.system.request.ProjectAddMemberBatchRequest; +import io.metersphere.system.request.ProjectAddMemberRequest; +import io.metersphere.system.request.ProjectMemberRequest; +import io.metersphere.system.request.OrganizationProjectRequest; +import io.metersphere.system.service.OrganizationProjectLogService; +import io.metersphere.system.service.OrganizationProjectService; +import io.metersphere.validation.groups.Created; +import io.metersphere.validation.groups.Updated; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.constraints.NotBlank; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@Tag(name = "系统设置-组织级项目") +@RequestMapping("/organization/project") +public class OrganizationProjectController { + @Resource + private OrganizationProjectService organizationProjectService; + + @PostMapping("/add") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_ADD) + @Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#project)", msClass = OrganizationProjectLogService.class) + @Operation(summary = "添加项目") + public Project addProject(@RequestBody @Validated({Created.class}) AddProjectRequest project) { + return organizationProjectService.add(project, SessionUtils.getUserId()); + } + + + @GetMapping("/get/{id}") + @Operation(summary = "根据ID获取项目信息") + @Parameter(name = "id", description = "项目id", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ) + public Project getProject(@PathVariable @NotBlank String id) { + return organizationProjectService.get(id); + } + + @PostMapping("/page") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ) + @Operation(summary = "获取项目列表") + public Pager> getProjectList(@Validated @RequestBody OrganizationProjectRequest request) { + Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), + StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc"); + return PageUtils.setPageInfo(page, organizationProjectService.getProjectList(request)); + } + + @PostMapping("/update") + @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#project)", msClass = OrganizationProjectLogService.class) + @Operation(summary = "更新项目信息") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE) + public Project updateProject(@RequestBody @Validated({Updated.class}) UpdateProjectRequest project) { + return organizationProjectService.update(project, SessionUtils.getUserId()); + } + + @GetMapping("/delete/{id}") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_DELETE) + @Operation(summary = "删除项目") + @Parameter(name = "id", description = "项目", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + @Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = OrganizationProjectLogService.class) + public int deleteProject(@PathVariable String id) { + return organizationProjectService.delete(id, SessionUtils.getUserId()); + } + + @GetMapping("/revoke/{id}") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_RECOVER) + @Operation(summary = "恢复项目") + @Log(type = OperationLogType.UPDATE, expression = "#msClass.recoverLog(#id)", msClass = OrganizationProjectLogService.class) + @Parameter(name = "id", description = "项目", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + public int revokeProject(@PathVariable String id) { + return organizationProjectService.revoke(id); + } + + @PostMapping("/member-list") + @RequiresPermissions(value = {PermissionConstants.ORGANIZATION_PROJECT_READ, PermissionConstants.SYSTEM_USER_READ}, logical = Logical.OR) + @Operation(summary = "获取项目下成员列表") + public Pager> getProjectMember(@Validated @RequestBody ProjectMemberRequest request) { + Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), + StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc"); + return PageUtils.setPageInfo(page, organizationProjectService.getProjectMember(request)); + } + + @PostMapping("/add-members") + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE) + @Operation(summary = "添加项目成员") + public void addProjectMember(@Validated @RequestBody ProjectAddMemberRequest request) { + ProjectAddMemberBatchRequest batchRequest = new ProjectAddMemberBatchRequest(); + batchRequest.setProjectIds(List.of(request.getProjectId())); + batchRequest.setUserIds(request.getUserIds()); + organizationProjectService.addProjectMember(batchRequest, SessionUtils.getUserId()); + } + + @GetMapping("/remove-member/{projectId}/{userId}") + @Operation(summary = "移除项目成员") + @Parameter(name = "userId", description = "用户id", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + @Parameter(name = "projectId", description = "项目id", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + @RequiresPermissions(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE) + @Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#projectId)", msClass = OrganizationProjectLogService.class) + public int removeProjectMember(@PathVariable String projectId, @PathVariable String userId) { + return organizationProjectService.removeProjectMember(projectId, userId, SessionUtils.getUserId()); + } + + +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemProjectController.java b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemProjectController.java index 1f0144192a..c87d84e3ba 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemProjectController.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/controller/SystemProjectController.java @@ -4,7 +4,6 @@ package io.metersphere.system.controller; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.project.domain.Project; -import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.dto.AddProjectRequest; import io.metersphere.sdk.dto.ProjectDTO; @@ -14,7 +13,6 @@ import io.metersphere.sdk.log.constants.OperationLogType; import io.metersphere.sdk.util.PageUtils; import io.metersphere.sdk.util.Pager; import io.metersphere.sdk.util.SessionUtils; -import io.metersphere.sdk.util.Translator; import io.metersphere.system.dto.UserExtend; import io.metersphere.system.request.ProjectAddMemberBatchRequest; import io.metersphere.system.request.ProjectAddMemberRequest; @@ -31,6 +29,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.constraints.NotBlank; import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -89,14 +88,14 @@ public class SystemProjectController { @GetMapping("/revoke/{id}") @RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_RECOVER) - @Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#id)", msClass = SystemProjectLogService.class) + @Log(type = OperationLogType.UPDATE, expression = "#msClass.recoverLog(#id)", msClass = SystemProjectLogService.class) @Parameter(name = "id", description = "项目", schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) public int revokeProject(@PathVariable String id) { return systemProjectService.revoke(id); } @PostMapping("/member-list") - @RequiresPermissions(value = {PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, PermissionConstants.SYSTEM_USER_READ}) + @RequiresPermissions(value = {PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, PermissionConstants.SYSTEM_USER_READ}, logical = Logical.OR) @Operation(summary = "获取项目下成员列表") public Pager> getProjectMember(@Validated @RequestBody ProjectMemberRequest request) { Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), @@ -111,8 +110,7 @@ public class SystemProjectController { ProjectAddMemberBatchRequest batchRequest = new ProjectAddMemberBatchRequest(); batchRequest.setProjectIds(List.of(request.getProjectId())); batchRequest.setUserIds(request.getUserIds()); - systemProjectService.addProjectMember(batchRequest, SessionUtils.getUserId(),"/system/project/add-member", - OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add")); + systemProjectService.addProjectMember(batchRequest, SessionUtils.getUserId()); } @GetMapping("/remove-member/{projectId}/{userId}") @@ -122,7 +120,7 @@ public class SystemProjectController { @RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE) @Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#projectId)", msClass = SystemProjectLogService.class) public int removeProjectMember(@PathVariable String projectId, @PathVariable String userId) { - return systemProjectService.removeProjectMember(projectId, userId); + return systemProjectService.removeProjectMember(projectId, userId, SessionUtils.getUserId()); } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanProjectJob.java b/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanProjectJob.java index 9b93f76ac6..e9a9de8e34 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanProjectJob.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanProjectJob.java @@ -6,7 +6,7 @@ import io.metersphere.project.domain.Project; import io.metersphere.project.domain.ProjectExample; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.util.LogUtils; -import io.metersphere.system.service.SystemProjectService; +import io.metersphere.system.service.CommonProjectService; import jakarta.annotation.Resource; import org.apache.shiro.util.CollectionUtils; import org.springframework.stereotype.Component; @@ -21,7 +21,7 @@ public class CleanProjectJob { @Resource private ProjectMapper projectMapper; @Resource - private SystemProjectService systemProjectService; + private CommonProjectService commonProjectService; /** * 清理状态为删除的项目 每天凌晨三点执行 @@ -44,7 +44,7 @@ public class CleanProjectJob { example.createCriteria().andDeletedEqualTo(true).andDeleteTimeLessThanOrEqualTo(timestamp); List projects = projectMapper.selectByExample(example); if (!CollectionUtils.isEmpty(projects)) { - systemProjectService.deleteProject(projects); + commonProjectService.deleteProject(projects); } } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/job/LicenseCacheJob.java b/backend/services/system-setting/src/main/java/io/metersphere/system/job/LicenseCacheJob.java deleted file mode 100644 index 3baf620c9d..0000000000 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/job/LicenseCacheJob.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.metersphere.system.job; - -import com.fit2cloud.quartz.anno.QuartzScheduled; -import io.metersphere.sdk.dto.LicenseDTO; -import io.metersphere.sdk.service.LicenseService; -import io.metersphere.sdk.util.CommonBeanFactory; -import io.metersphere.sdk.util.LogUtils; -import org.springframework.stereotype.Component; - -@Component -public class LicenseCacheJob { - - @QuartzScheduled(cron = "0 5 0 * * ?") - public void checkLicenseTask() { - LicenseService licenseService = CommonBeanFactory.getBean(LicenseService.class); - if (licenseService != null) { - LicenseDTO dto = licenseService.refreshLicense(); - LogUtils.info("刷新LICENSE状态: " + dto.getStatus()); - } - } -} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationProjectRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationProjectRequest.java new file mode 100644 index 0000000000..348d22ce7c --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationProjectRequest.java @@ -0,0 +1,19 @@ +package io.metersphere.system.request; + +import io.metersphere.sdk.dto.BasePageRequest; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class OrganizationProjectRequest extends BasePageRequest { + @Schema(title = "组织id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank(message = "{project.organization_id.not_blank}") + @Size(min = 1, max = 50, message = "{project.organization_id.length_range}") + private String organizationId; + @Schema(title = "项目ID") + private String projectId; +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/CommonProjectService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/CommonProjectService.java new file mode 100644 index 0000000000..63d874bc71 --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/CommonProjectService.java @@ -0,0 +1,404 @@ +package io.metersphere.system.service; + +import io.metersphere.project.domain.Project; +import io.metersphere.project.domain.ProjectExample; +import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.constants.HttpMethodConstants; +import io.metersphere.sdk.constants.InternalUserRole; +import io.metersphere.sdk.constants.OperationLogConstants; +import io.metersphere.sdk.constants.UserRoleType; +import io.metersphere.sdk.dto.AddProjectRequest; +import io.metersphere.sdk.dto.LogDTO; +import io.metersphere.sdk.dto.ProjectDTO; +import io.metersphere.sdk.dto.UpdateProjectRequest; +import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.invoker.ProjectServiceInvoker; +import io.metersphere.sdk.log.constants.OperationLogModule; +import io.metersphere.sdk.log.constants.OperationLogType; +import io.metersphere.sdk.log.service.OperationLogService; +import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.LogUtils; +import io.metersphere.sdk.util.Translator; +import io.metersphere.system.domain.*; +import io.metersphere.system.mapper.*; +import io.metersphere.system.request.ProjectAddMemberBatchRequest; +import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +@Transactional(rollbackFor = Exception.class) +public class CommonProjectService { + + @Resource + private ProjectMapper projectMapper; + @Resource + private UserMapper userMapper; + @Resource + private UserRoleRelationMapper userRoleRelationMapper; + @Resource + private ExtSystemProjectMapper extSystemProjectMapper; + @Resource + private OperationLogService operationLogService; + @Resource + private UserRoleMapper userRoleMapper; + @Resource + private UserRolePermissionMapper userRolePermissionMapper; + private final ProjectServiceInvoker serviceInvoker; + + @Autowired + public CommonProjectService(ProjectServiceInvoker serviceInvoker) { + this.serviceInvoker = serviceInvoker; + } + + public Project get(String id) { + return projectMapper.selectByPrimaryKey(id); + } + + /** + * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员的权限 + * @param createUser + * @param path 请求路径 + * @param module 日志记录模块 + * @return + */ + public Project add(AddProjectRequest addProjectDTO, String createUser, String path, String module) { + + Project project = new Project(); + project.setId(UUID.randomUUID().toString()); + project.setName(addProjectDTO.getName()); + project.setOrganizationId(addProjectDTO.getOrganizationId()); + checkProjectExistByName(project); + project.setCreateTime(System.currentTimeMillis()); + project.setUpdateTime(System.currentTimeMillis()); + project.setUpdateUser(createUser); + project.setCreateUser(createUser); + project.setEnable(addProjectDTO.getEnable()); + project.setDescription(addProjectDTO.getDescription()); + addProjectDTO.setId(project.getId()); + projectMapper.insertSelective(project); + ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest(); + memberRequest.setProjectIds(List.of(project.getId())); + if (CollectionUtils.isEmpty(addProjectDTO.getUserIds())) { + memberRequest.setUserIds(List.of(createUser)); + } else { + memberRequest.setUserIds(addProjectDTO.getUserIds()); + } + //添加项目管理员 创建的时候如果没有传管理员id 则默认创建者为管理员 + this.addProjectAdmin(memberRequest, createUser, path, + OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add"), module); + return project; + } + + /** + * 检查添加的人员是否存在组织中 + * + * @param + */ + public void checkOrgRoleExit(String userId, String orgId, String createUser, String userName, String path, String module) { + List logDTOList = new ArrayList<>(); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andUserIdEqualTo(userId).andSourceIdEqualTo(orgId); + if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { + UserRoleRelation memberRole = new UserRoleRelation(); + memberRole.setId(UUID.randomUUID().toString()); + memberRole.setUserId(userId); + memberRole.setRoleId(InternalUserRole.ORG_MEMBER.getValue()); + memberRole.setSourceId(orgId); + memberRole.setCreateTime(System.currentTimeMillis()); + memberRole.setCreateUser(createUser); + userRoleRelationMapper.insert(memberRole); + LogDTO logDTO = new LogDTO(orgId, orgId,memberRole.getId(), createUser, OperationLogType.ADD.name(), module,Translator.get("add") + Translator.get("organization_member") + ": " + userName); + setLog(logDTO, path, HttpMethodConstants.POST.name(), logDTOList); + } + operationLogService.batchAdd(logDTOList); + } + + private void checkProjectExistByName(Project project) { + ProjectExample example = new ProjectExample(); + example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()); + if (projectMapper.selectByExample(example).size() > 0) { + throw new MSException(Translator.get("project_name_already_exists")); + } + } + + /** + * 检查项目是否存在 + * + * @param id + */ + public void checkProjectNotExist(String id) { + if (projectMapper.selectByPrimaryKey(id) == null) { + throw new MSException(Translator.get("project_is_not_exist")); + } + } + + public List buildUserInfo(List projectList) { + projectList.forEach(projectDTO -> { + List users = extSystemProjectMapper.getProjectAdminList(projectDTO.getId()); + projectDTO.setAdminList(users); + }); + return projectList; + } + + public Project update(UpdateProjectRequest updateProjectDto, String updateUser, String path, String module) { + Project project = new Project(); + project.setId(updateProjectDto.getId()); + project.setName(updateProjectDto.getName()); + project.setDescription(updateProjectDto.getDescription()); + project.setOrganizationId(updateProjectDto.getOrganizationId()); + project.setEnable(updateProjectDto.getEnable()); + project.setUpdateUser(updateUser); + project.setCreateUser(null); + project.setCreateTime(null); + project.setUpdateTime(System.currentTimeMillis()); + checkProjectExistByName(project); + checkProjectNotExist(project.getId()); + UserRoleRelationExample example = new UserRoleRelationExample(); + example.createCriteria().andSourceIdEqualTo(project.getId()).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + List userRoleRelations = userRoleRelationMapper.selectByExample(example); + List orgUserIds = userRoleRelations.stream().map(UserRoleRelation::getUserId).toList(); + List logDTOList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(updateProjectDto.getUserIds())) { + //updateProjectDto.getUserIds() 为前端传过来的用户id 与数据库中的用户id做对比 如果数据库中的用户id不在前端传过来的用户id中 则删除 + List deleteIds = orgUserIds.stream() + .filter(item -> !updateProjectDto.getUserIds().contains(item)) + .collect(Collectors.toList()); + + List insertIds = updateProjectDto.getUserIds().stream() + .filter(item -> !orgUserIds.contains(item)) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(deleteIds)) { + UserRoleRelationExample deleteExample = new UserRoleRelationExample(); + deleteExample.createCriteria().andSourceIdEqualTo(project.getId()).andUserIdIn(deleteIds).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + userRoleRelationMapper.selectByExample(deleteExample).forEach(userRoleRelation -> { + User user = userMapper.selectByPrimaryKey(userRoleRelation.getUserId()); + LogDTO logDTO = new LogDTO(project.getId(), project.getOrganizationId(),userRoleRelation.getId(), updateUser, OperationLogType.DELETE.name(), module,Translator.get("delete") + Translator.get("project_admin") + ": " + user.getName()); + setLog(logDTO, path, HttpMethodConstants.POST.name(), logDTOList); + }); + userRoleRelationMapper.deleteByExample(deleteExample); + } + if (CollectionUtils.isNotEmpty(insertIds)) { + ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest(); + memberRequest.setProjectIds(List.of(project.getId())); + memberRequest.setUserIds(insertIds); + this.addProjectAdmin(memberRequest, updateUser, path, OperationLogType.UPDATE.name(), + HttpMethodConstants.POST.name(), Translator.get("update"), module); + } + } else { + if (CollectionUtils.isNotEmpty(orgUserIds)) { + //如果前端传过来的用户id为空 则删除项目所有管理员 + UserRoleRelationExample deleteExample = new UserRoleRelationExample(); + deleteExample.createCriteria().andSourceIdEqualTo(project.getId()).andUserIdIn(orgUserIds).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + userRoleRelationMapper.selectByExample(deleteExample).forEach(userRoleRelation -> { + User user = userMapper.selectByPrimaryKey(userRoleRelation.getUserId()); + LogDTO logDTO = new LogDTO(project.getId(), project.getOrganizationId(),userRoleRelation.getId(), updateUser, OperationLogType.DELETE.name(), module,Translator.get("delete") + Translator.get("project_admin") + ": " + user.getName()); + setLog(logDTO, path, HttpMethodConstants.POST.name() ,logDTOList); + }); + userRoleRelationMapper.deleteByExample(deleteExample); + } + } + if (CollectionUtils.isNotEmpty(logDTOList)) { + operationLogService.batchAdd(logDTOList); + } + + projectMapper.updateByPrimaryKeySelective(project); + return project; + } + + public int delete(String id, String deleteUser) { + //TODO 删除项目删除全部资源 这里的删除只是假删除 + checkProjectNotExist(id); + Project project = new Project(); + project.setId(id); + project.setDeleteUser(deleteUser); + project.setDeleted(true); + project.setDeleteTime(System.currentTimeMillis()); + return projectMapper.updateByPrimaryKeySelective(project); + } + + /** + * 添加项目管理员 + * @param request + * @param createUser 创建人 + * @param path 请求路径 + * @param type 操作类型 + * @param method 请求方法 + * @param content 操作内容 + * @param module 日志记录模块 + */ + public void addProjectAdmin(ProjectAddMemberBatchRequest request, String createUser, String path, String type, + String method, String content, String module) { + + List logDTOList = new ArrayList<>(); + List userRoleRelations = new ArrayList<>(); + request.getProjectIds().forEach(projectId -> { + checkProjectNotExist(projectId); + //判断传过来的用户id是否在组织下,如果不存在,给用户创建一个组织成员的身份 + request.getUserIds().forEach(userId -> { + User user = userMapper.selectByPrimaryKey(userId); + if (ObjectUtils.isEmpty(user)) { + throw new MSException(Translator.get("user_not_exist")); + } + Project project = projectMapper.selectByPrimaryKey(projectId); + this.checkOrgRoleExit(userId, project.getOrganizationId(), createUser, user.getName(), path, module); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) + .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue()); + if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { + UserRoleRelation adminRole = new UserRoleRelation(); + adminRole.setId(UUID.randomUUID().toString()); + adminRole.setUserId(userId); + adminRole.setRoleId(InternalUserRole.PROJECT_ADMIN.getValue()); + adminRole.setSourceId(projectId); + adminRole.setCreateTime(System.currentTimeMillis()); + adminRole.setCreateUser(createUser); + userRoleRelations.add(adminRole); + LogDTO logDTO = new LogDTO(projectId, project.getOrganizationId(), adminRole.getId(), createUser, type, module, content + Translator.get("project_admin") + ": " + user.getName()); + setLog(logDTO, path, HttpMethodConstants.POST.name(), logDTOList); + } + }); + }); + userRoleRelationMapper.batchInsert(userRoleRelations); + operationLogService.batchAdd(logDTOList); + } + + /** + * 添加项目成员 + * @param request + * @param createUser 创建人 + * @param path 请求路径 + * @param type 操作类型 + * @param method 请求方法 + * @param content 操作内容 + * @param module 日志记录模块 + */ + public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser, String path, String type, + String method, String content, String module) { + + List logDTOList = new ArrayList<>(); + List userRoleRelations = new ArrayList<>(); + request.getProjectIds().forEach(projectId -> { + checkProjectNotExist(projectId); + request.getUserIds().forEach(userId -> { + User user = userMapper.selectByPrimaryKey(userId); + if (ObjectUtils.isEmpty(user)) { + throw new MSException(Translator.get("user_not_exist")); + } + Project project = projectMapper.selectByPrimaryKey(projectId); + this.checkOrgRoleExit(userId, project.getOrganizationId(), createUser, user.getName(), path, module); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) + .andSourceIdEqualTo(projectId); + if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { + UserRoleRelation memberRole = new UserRoleRelation(); + memberRole.setId(UUID.randomUUID().toString()); + memberRole.setUserId(userId); + memberRole.setRoleId(InternalUserRole.PROJECT_MEMBER.getValue()); + memberRole.setSourceId(projectId); + memberRole.setCreateTime(System.currentTimeMillis()); + memberRole.setCreateUser(createUser); + userRoleRelations.add(memberRole); + LogDTO logDTO = new LogDTO(projectId, project.getOrganizationId(),memberRole.getId(), createUser, type, module, content + Translator.get("project_member") + ": " + user.getName()); + setLog(logDTO , path, HttpMethodConstants.POST.name(), logDTOList); + } + }); + }); + userRoleRelationMapper.batchInsert(userRoleRelations); + operationLogService.batchAdd(logDTOList); + } + + public int removeProjectMember(String projectId, String userId,String createUser, String module, String path) { + checkProjectNotExist(projectId); + User user = userMapper.selectByPrimaryKey(userId); + if (user == null) { + throw new MSException(Translator.get("user_not_exist")); + } + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) + .andSourceIdEqualTo(projectId); + if (StringUtils.equals(projectId, user.getLastProjectId())) { + user.setLastProjectId(StringUtils.EMPTY); + userMapper.updateByPrimaryKeySelective(user); + } + List logDTOList = new ArrayList<>(); + userRoleRelationMapper.selectByExample(userRoleRelationExample).forEach(userRoleRelation -> { + LogDTO logDTO = new LogDTO(projectId, projectMapper.selectByPrimaryKey(projectId).getOrganizationId(),userRoleRelation.getId(), createUser, OperationLogType.DELETE.name(), module,Translator.get("delete") + Translator.get("project_member") + ": " + user.getName()); + setLog(logDTO,path,HttpMethodConstants.GET.name(), logDTOList); + }); + operationLogService.batchAdd(logDTOList); + return userRoleRelationMapper.deleteByExample(userRoleRelationExample); + } + + public int revoke(String id) { + checkProjectNotExist(id); + Project project = new Project(); + project.setId(id); + project.setDeleted(false); + project.setDeleteTime(null); + project.setDeleteUser(null); + return projectMapper.updateByPrimaryKeySelective(project); + } + + /** + * 删除项目 一般是定时任务会触发 + * @param projects + */ + public void deleteProject(List projects) { + // 删除项目 + List logDTOList = new ArrayList<>(); + projects.forEach(project -> { + serviceInvoker.invokeServices(project.getId()); + LogUtils.info("send delete_project message, project id: " + project.getId()); + + deleteProjectUserGroup(project.getId()); + // delete project + projectMapper.deleteByPrimaryKey(project.getId()); + LogDTO logDTO = new LogDTO(OperationLogConstants.SYSTEM, project.getOrganizationId(),project.getId(), StringUtils.EMPTY, OperationLogType.DELETE.name(), OperationLogModule.SYSTEM_PROJECT,Translator.get("delete") + Translator.get("project") + ": " + project.getName()); + setLog(logDTO, StringUtils.EMPTY,StringUtils.EMPTY, logDTOList); + }); + operationLogService.batchAdd(logDTOList); + } + + /** + * 删除自定义用户组和权限关系表、项目和用户关系数据 + * @param projectId + */ + private void deleteProjectUserGroup(String projectId) { + UserRoleRelationExample userGroupExample = new UserRoleRelationExample(); + userGroupExample.createCriteria().andSourceIdEqualTo(projectId); + userRoleRelationMapper.deleteByExample(userGroupExample); + UserRoleExample userRoleExample = new UserRoleExample(); + userRoleExample.createCriteria().andScopeIdEqualTo(projectId).andTypeEqualTo(UserRoleType.PROJECT.name()); + List roles = userRoleMapper.selectByExample(userRoleExample); + if (CollectionUtils.isNotEmpty(roles)) { + List roleIds = roles.stream().map(UserRole::getId).collect(Collectors.toList()); + UserRolePermissionExample userRolePermissionExample = new UserRolePermissionExample(); + userRolePermissionExample.createCriteria().andRoleIdIn(roleIds); + userRolePermissionMapper.deleteByExample(userRolePermissionExample); + userRoleMapper.deleteByExample(userRoleExample); + } + } + + /** + * + * @param path 请求路径 + * @param method 请求方法 + * @param logDTOList 日志集合 + */ + private void setLog(LogDTO dto, String path, String method, List logDTOList) { + dto.setPath(path); + dto.setMethod(method); + dto.setOriginalValue(JSON.toJSONBytes(StringUtils.EMPTY)); + logDTOList.add(dto); + } +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectLogService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectLogService.java new file mode 100644 index 0000000000..01f35f4269 --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectLogService.java @@ -0,0 +1,109 @@ +package io.metersphere.system.service; + +import io.metersphere.project.domain.Project; +import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.dto.AddProjectRequest; +import io.metersphere.sdk.dto.LogDTO; +import io.metersphere.sdk.dto.UpdateProjectRequest; +import io.metersphere.sdk.log.constants.OperationLogModule; +import io.metersphere.sdk.log.constants.OperationLogType; +import io.metersphere.sdk.util.JSON; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(rollbackFor = Exception.class) +public class OrganizationProjectLogService { + + @Resource + private ProjectMapper projectMapper; + + /** + * 添加接口日志 + * + * @return + */ + public LogDTO addLog(AddProjectRequest project) { + LogDTO dto = new LogDTO( + project.getId(), + project.getOrganizationId(), + null, + null, + OperationLogType.ADD.name(), + OperationLogModule.ORGANIZATION_PROJECT, + project.getName()); + + dto.setOriginalValue(JSON.toJSONBytes(project)); + return dto; + } + + /** + * @param request + * @return + */ + public LogDTO updateLog(UpdateProjectRequest request) { + Project project = projectMapper.selectByPrimaryKey(request.getId()); + if (project != null) { + LogDTO dto = new LogDTO( + project.getId(), + project.getOrganizationId(), + project.getId(), + project.getCreateUser(), + OperationLogType.UPDATE.name(), + OperationLogModule.ORGANIZATION_PROJECT, + project.getName()); + + dto.setOriginalValue(JSON.toJSONBytes(project)); + return dto; + } + return null; + } + + + /** + * 删除接口日志 + * + * @param id + * @return + */ + public LogDTO deleteLog(String id) { + Project project = projectMapper.selectByPrimaryKey(id); + if (project != null) { + LogDTO dto = new LogDTO( + project.getId(), + project.getOrganizationId(), + id, + project.getCreateUser(), + OperationLogType.DELETE.name(), + OperationLogModule.ORGANIZATION_PROJECT, + project.getName()); + + dto.setOriginalValue(JSON.toJSONBytes(project)); + return dto; + } + return null; + } + + /** + * 恢复项目 + * @param id 接口请求参数 + * @return 日志详情 + */ + public LogDTO recoverLog(String id) { + Project project = projectMapper.selectByPrimaryKey(id); + if (project != null) { + LogDTO dto = new LogDTO( + project.getId(), + project.getOrganizationId(), + id, + null, + OperationLogType.RECOVER.name(), + OperationLogModule.ORGANIZATION_PROJECT, + project.getName()); + dto.setOriginalValue(JSON.toJSONBytes(project)); + return dto; + } + return null; + } +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectService.java new file mode 100644 index 0000000000..5ee05184c2 --- /dev/null +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationProjectService.java @@ -0,0 +1,97 @@ +package io.metersphere.system.service; + +import io.metersphere.project.domain.Project; +import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.constants.HttpMethodConstants; +import io.metersphere.sdk.dto.AddProjectRequest; +import io.metersphere.sdk.dto.ProjectDTO; +import io.metersphere.sdk.dto.UpdateProjectRequest; +import io.metersphere.sdk.log.constants.OperationLogModule; +import io.metersphere.sdk.log.constants.OperationLogType; +import io.metersphere.sdk.util.BeanUtils; +import io.metersphere.sdk.util.Translator; +import io.metersphere.system.dto.UserExtend; +import io.metersphere.system.mapper.ExtSystemProjectMapper; +import io.metersphere.system.request.OrganizationProjectRequest; +import io.metersphere.system.request.ProjectAddMemberBatchRequest; +import io.metersphere.system.request.ProjectMemberRequest; +import io.metersphere.system.request.ProjectRequest; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(rollbackFor = Exception.class) +public class OrganizationProjectService { + + @Resource + private ProjectMapper projectMapper; + @Resource + private ExtSystemProjectMapper extSystemProjectMapper; + @Resource + private CommonProjectService commonProjectService; + + + private final static String PREFIX = "/organization-project"; + private final static String ADD_PROJECT = PREFIX + "/add"; + private final static String UPDATE_PROJECT = PREFIX + "/update"; + private final static String REMOVE_PROJECT_MEMBER = PREFIX + "/remove-member/"; + private final static String ADD_MEMBER = PREFIX + "/add-member"; + + public Project get(String id) { + return projectMapper.selectByPrimaryKey(id); + } + + /** + * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员的权限 + * @return + */ + public Project add(AddProjectRequest addProjectDTO, String createUser) { + Project project = commonProjectService.add(addProjectDTO, createUser, ADD_PROJECT, OperationLogModule.SYSTEM_PROJECT); + return project; + } + + public List getProjectList(OrganizationProjectRequest request) { + ProjectRequest projectRequest = new ProjectRequest(); + BeanUtils.copyBean(projectRequest, request); + List projectList = extSystemProjectMapper.getProjectList(projectRequest); + return commonProjectService.buildUserInfo(projectList); + } + + public Project update(UpdateProjectRequest updateProjectDto, String updateUser) { + Project project = commonProjectService.update(updateProjectDto, updateUser, UPDATE_PROJECT, OperationLogModule.SYSTEM_PROJECT); + return project; + } + + public int delete(String id, String deleteUser) { + return commonProjectService.delete(id, deleteUser); + } + + public List getProjectMember(ProjectMemberRequest request) { + commonProjectService.checkProjectNotExist(request.getProjectId()); + List projectMemberList = extSystemProjectMapper.getProjectMemberList(request); + return projectMemberList; + } + + /*** + * 添加项目成员 + * @param request + * @param createUser + */ + public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser) { + commonProjectService.addProjectMember(request, createUser, ADD_MEMBER, + OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add"), OperationLogModule.SYSTEM_PROJECT); + } + + public int removeProjectMember(String projectId, String userId, String createUser) { + return commonProjectService.removeProjectMember(projectId, userId, createUser,OperationLogModule.SYSTEM_PROJECT, StringUtils.join(REMOVE_PROJECT_MEMBER,projectId, "/", userId)); + } + + public int revoke(String id) { + return commonProjectService.revoke(id); + } + +} diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectLogService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectLogService.java index 7d924e5f6e..8006b9f98f 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectLogService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectLogService.java @@ -2,7 +2,6 @@ package io.metersphere.system.service; import io.metersphere.project.domain.Project; import io.metersphere.project.mapper.ProjectMapper; -import io.metersphere.sdk.constants.OperationLogConstants; import io.metersphere.sdk.dto.AddProjectRequest; import io.metersphere.sdk.dto.LogDTO; import io.metersphere.sdk.dto.UpdateProjectRequest; @@ -27,8 +26,8 @@ public class SystemProjectLogService { */ public LogDTO addLog(AddProjectRequest project) { LogDTO dto = new LogDTO( - OperationLogConstants.SYSTEM, - OperationLogConstants.SYSTEM, + project.getId(), + project.getOrganizationId(), null, null, OperationLogType.ADD.name(), @@ -47,31 +46,13 @@ public class SystemProjectLogService { Project project = projectMapper.selectByPrimaryKey(request.getId()); if (project != null) { LogDTO dto = new LogDTO( - OperationLogConstants.SYSTEM, - OperationLogConstants.SYSTEM, + project.getId(), + project.getOrganizationId(), project.getId(), project.getCreateUser(), OperationLogType.UPDATE.name(), OperationLogModule.SYSTEM_PROJECT, - "编辑全局用户组对应的权限配置"); - - dto.setOriginalValue(JSON.toJSONBytes(project)); - return dto; - } - return null; - } - - public LogDTO updateLog(String id) { - Project project = projectMapper.selectByPrimaryKey(id); - if (project != null) { - LogDTO dto = new LogDTO( - OperationLogConstants.SYSTEM, - OperationLogConstants.SYSTEM, - project.getId(), - project.getCreateUser(), - OperationLogType.RECOVER.name(), - OperationLogModule.SYSTEM_PROJECT, - "编辑全局用户组对应的权限配置"); + project.getName()); dto.setOriginalValue(JSON.toJSONBytes(project)); return dto; @@ -90,8 +71,8 @@ public class SystemProjectLogService { Project project = projectMapper.selectByPrimaryKey(id); if (project != null) { LogDTO dto = new LogDTO( - OperationLogConstants.SYSTEM, - OperationLogConstants.SYSTEM, + project.getId(), + project.getOrganizationId(), id, project.getCreateUser(), OperationLogType.DELETE.name(), @@ -103,4 +84,26 @@ public class SystemProjectLogService { } return null; } + + /** + * 恢复项目 + * @param id 接口请求参数 + * @return 日志详情 + */ + public LogDTO recoverLog(String id) { + Project project = projectMapper.selectByPrimaryKey(id); + if (project != null) { + LogDTO dto = new LogDTO( + project.getId(), + project.getOrganizationId(), + id, + null, + OperationLogType.RECOVER.name(), + OperationLogModule.SYSTEM_PROJECT, + project.getName()); + dto.setOriginalValue(JSON.toJSONBytes(project)); + return dto; + } + return null; + } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectService.java index 0b55f41fce..8549a77b60 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/SystemProjectService.java @@ -1,47 +1,26 @@ package io.metersphere.system.service; import io.metersphere.project.domain.Project; -import io.metersphere.project.domain.ProjectExample; import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.sdk.constants.HttpMethodConstants; -import io.metersphere.sdk.constants.InternalUserRole; -import io.metersphere.sdk.constants.OperationLogConstants; import io.metersphere.sdk.dto.AddProjectRequest; -import io.metersphere.sdk.dto.LogDTO; import io.metersphere.sdk.dto.ProjectDTO; import io.metersphere.sdk.dto.UpdateProjectRequest; -import io.metersphere.sdk.exception.MSException; -import io.metersphere.sdk.invoker.ProjectServiceInvoker; import io.metersphere.sdk.log.constants.OperationLogModule; import io.metersphere.sdk.log.constants.OperationLogType; -import io.metersphere.sdk.log.service.OperationLogService; -import io.metersphere.sdk.util.JSON; -import io.metersphere.sdk.util.LogUtils; import io.metersphere.sdk.util.Translator; -import io.metersphere.system.domain.User; -import io.metersphere.system.domain.UserRoleRelation; -import io.metersphere.system.domain.UserRoleRelationExample; import io.metersphere.system.dto.OrganizationProjectOptionsDTO; import io.metersphere.system.dto.UserExtend; import io.metersphere.system.mapper.ExtSystemProjectMapper; -import io.metersphere.system.mapper.UserMapper; -import io.metersphere.system.mapper.UserRoleRelationMapper; import io.metersphere.system.request.ProjectAddMemberBatchRequest; import io.metersphere.system.request.ProjectMemberRequest; import io.metersphere.system.request.ProjectRequest; import jakarta.annotation.Resource; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.ibatis.session.SqlSessionFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) @@ -50,331 +29,73 @@ public class SystemProjectService { @Resource private ProjectMapper projectMapper; @Resource - private UserMapper userMapper; - @Resource - private UserRoleRelationMapper userRoleRelationMapper; - @Resource private ExtSystemProjectMapper extSystemProjectMapper; @Resource - private OperationLogService operationLogService; - - private final ProjectServiceInvoker serviceInvoker; - @Resource - private SqlSessionFactory sqlSessionFactory; + private CommonProjectService commonProjectService; private final static String PREFIX = "/system/project"; private final static String ADD_PROJECT = PREFIX + "/add"; private final static String UPDATE_PROJECT = PREFIX + "/update"; private final static String REMOVE_PROJECT_MEMBER = PREFIX + "/remove-member/"; - - @Autowired - public SystemProjectService(ProjectServiceInvoker serviceInvoker) { - this.serviceInvoker = serviceInvoker; - } + private final static String ADD_MEMBER = PREFIX + "/add-member"; public Project get(String id) { return projectMapper.selectByPrimaryKey(id); } /** - * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员和成员的权限 + * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员的权限 * @return */ public Project add(AddProjectRequest addProjectDTO, String createUser) { - - Project project = new Project(); - project.setId(UUID.randomUUID().toString()); - project.setName(addProjectDTO.getName()); - project.setOrganizationId(addProjectDTO.getOrganizationId()); - checkProjectExistByName(project); - project.setCreateTime(System.currentTimeMillis()); - project.setUpdateTime(System.currentTimeMillis()); - project.setUpdateUser(createUser); - project.setCreateUser(createUser); - project.setEnable(addProjectDTO.getEnable()); - project.setDescription(addProjectDTO.getDescription()); - projectMapper.insertSelective(project); - ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest(); - memberRequest.setProjectIds(List.of(project.getId())); - if (CollectionUtils.isEmpty(addProjectDTO.getUserIds())) { - memberRequest.setUserIds(List.of(createUser)); - } else { - memberRequest.setUserIds(addProjectDTO.getUserIds()); - } - //添加项目管理员 创建的时候如果没有传管理员id 则默认创建者为管理员 - this.addProjectAdmin(memberRequest, createUser, ADD_PROJECT, OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add")); + Project project = commonProjectService.add(addProjectDTO, createUser, ADD_PROJECT, OperationLogModule.SYSTEM_PROJECT); return project; } - public void checkOrgRoleExit(String userId, String orgId, String createUser, String userName) { - List logDTOList = new ArrayList<>(); - UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); - userRoleRelationExample.createCriteria().andUserIdEqualTo(userId).andSourceIdEqualTo(orgId); - if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { - UserRoleRelation memberRole = new UserRoleRelation(); - memberRole.setId(UUID.randomUUID().toString()); - memberRole.setUserId(userId); - memberRole.setRoleId(InternalUserRole.ORG_MEMBER.getValue()); - memberRole.setSourceId(orgId); - memberRole.setCreateTime(System.currentTimeMillis()); - memberRole.setCreateUser(createUser); - userRoleRelationMapper.insert(memberRole); - } - setLog(orgId, "null", Translator.get("add") + Translator.get("organization_member") + ": " + userName, createUser, "", OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), logDTOList); - operationLogService.batchAdd(logDTOList); - } - - private void checkProjectExistByName(Project project) { - ProjectExample example = new ProjectExample(); - example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()); - if (projectMapper.selectByExample(example).size() > 0) { - throw new MSException(Translator.get("project_name_already_exists")); - } - } - - /** - * 检查项目是否存在 - * - * @param id - */ - private void checkProjectNotExist(String id) { - if (projectMapper.selectByPrimaryKey(id) == null) { - throw new MSException(Translator.get("project_is_not_exist")); - } - } - public List getProjectList(ProjectRequest request) { List projectList = extSystemProjectMapper.getProjectList(request); - return buildUserInfo(projectList); - } - - public List buildUserInfo(List projectList) { - projectList.forEach(projectDTO -> { - List users = extSystemProjectMapper.getProjectAdminList(projectDTO.getId()); - projectDTO.setAdminList(users); - }); - return projectList; + return commonProjectService.buildUserInfo(projectList); } public Project update(UpdateProjectRequest updateProjectDto, String updateUser) { - Project project = new Project(); - project.setId(updateProjectDto.getId()); - project.setName(updateProjectDto.getName()); - project.setDescription(updateProjectDto.getDescription()); - project.setOrganizationId(updateProjectDto.getOrganizationId()); - project.setEnable(updateProjectDto.getEnable()); - project.setUpdateUser(updateUser); - project.setCreateUser(null); - project.setCreateTime(null); - project.setUpdateTime(System.currentTimeMillis()); - checkProjectExistByName(project); - checkProjectNotExist(project.getId()); - UserRoleRelationExample example = new UserRoleRelationExample(); - example.createCriteria().andSourceIdEqualTo(project.getId()).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); - List userRoleRelations = userRoleRelationMapper.selectByExample(example); - List orgUserIds = userRoleRelations.stream().map(UserRoleRelation::getUserId).toList(); - if (CollectionUtils.isNotEmpty(updateProjectDto.getUserIds())) { - //updateProjectDto.getUserIds() 为前端传过来的用户id 与数据库中的用户id做对比 如果数据库中的用户id不在前端传过来的用户id中 则删除 - List deleteIds = orgUserIds.stream() - .filter(item -> !updateProjectDto.getUserIds().contains(item)) - .collect(Collectors.toList()); - - List insertIds = updateProjectDto.getUserIds().stream() - .filter(item -> !orgUserIds.contains(item)) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(deleteIds)) { - UserRoleRelationExample deleteExample = new UserRoleRelationExample(); - deleteExample.createCriteria().andSourceIdEqualTo(project.getId()).andUserIdIn(deleteIds).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); - userRoleRelationMapper.deleteByExample(deleteExample); - } - if (CollectionUtils.isNotEmpty(insertIds)) { - ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest(); - memberRequest.setProjectIds(List.of(project.getId())); - memberRequest.setUserIds(insertIds); - this.addProjectAdmin(memberRequest, updateUser, UPDATE_PROJECT, OperationLogType.UPDATE.name(), - HttpMethodConstants.POST.name(), Translator.get("update")); - } - } else { - if (CollectionUtils.isNotEmpty(orgUserIds)) { - //如果前端传过来的用户id为空 则删除项目所有管理员 - UserRoleRelationExample deleteExample = new UserRoleRelationExample(); - deleteExample.createCriteria().andSourceIdEqualTo(project.getId()).andUserIdIn(orgUserIds).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); - userRoleRelationMapper.deleteByExample(deleteExample); - } - } - - projectMapper.updateByPrimaryKeySelective(project); + Project project = commonProjectService.update(updateProjectDto, updateUser, UPDATE_PROJECT, OperationLogModule.SYSTEM_PROJECT); return project; } public int delete(String id, String deleteUser) { - //TODO 删除项目删除全部资源 这里的删除只是假删除 - checkProjectNotExist(id); - Project project = new Project(); - project.setId(id); - project.setDeleteUser(deleteUser); - project.setDeleted(true); - project.setDeleteTime(System.currentTimeMillis()); - return projectMapper.updateByPrimaryKeySelective(project); + return commonProjectService.delete(id, deleteUser); } public List getProjectMember(ProjectMemberRequest request) { + commonProjectService.checkProjectNotExist(request.getProjectId()); List projectMemberList = extSystemProjectMapper.getProjectMemberList(request); return projectMemberList; } - /** - * 添加项目管理员 - * - * @param request - * @param createUser - * @param path - * @param type - * @param method - * @param content - */ - public void addProjectAdmin(ProjectAddMemberBatchRequest request, String createUser, String path, String type, - String method, String content) { - - List logDTOList = new ArrayList<>(); - List userRoleRelations = new ArrayList<>(); - request.getProjectIds().forEach(projectId -> { - checkProjectNotExist(projectId); - //判断传过来的用户id是否在组织下,如果不存在,给用户创建一个组织成员的身份 - request.getUserIds().forEach(userId -> { - User user = userMapper.selectByPrimaryKey(userId); - if (ObjectUtils.isEmpty(user)) { - throw new MSException(Translator.get("user_not_exist")); - } - this.checkOrgRoleExit(userId, projectMapper.selectByPrimaryKey(projectId).getOrganizationId(), createUser, user.getName()); - UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); - userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) - .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue()); - if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { - UserRoleRelation adminRole = new UserRoleRelation(); - adminRole.setId(UUID.randomUUID().toString()); - adminRole.setUserId(userId); - adminRole.setRoleId(InternalUserRole.PROJECT_ADMIN.getValue()); - adminRole.setSourceId(projectId); - adminRole.setCreateTime(System.currentTimeMillis()); - adminRole.setCreateUser(createUser); - userRoleRelations.add(adminRole); - setLog(projectId, path, content + Translator.get("project_admin") + ": " + user.getName(), createUser, "", type, method, logDTOList); - } - }); - }); - userRoleRelationMapper.batchInsert(userRoleRelations); - operationLogService.batchAdd(logDTOList); - } - /*** * 添加项目成员 * @param request * @param createUser - * @param path 请求路径 - * @param type 操作类型 - * @param method 请求方法 - * @param content 操作内容 */ - public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser, String path, String type, - String method, String content) { - - List logDTOList = new ArrayList<>(); - List userRoleRelations = new ArrayList<>(); - request.getProjectIds().forEach(projectId -> { - checkProjectNotExist(projectId); - request.getUserIds().forEach(userId -> { - User user = userMapper.selectByPrimaryKey(userId); - if (ObjectUtils.isEmpty(user)) { - throw new MSException(Translator.get("user_not_exist")); - } - this.checkOrgRoleExit(userId, projectMapper.selectByPrimaryKey(projectId).getOrganizationId(), createUser, user.getName()); - UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); - userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) - .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue()); - if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { - UserRoleRelation memberRole = new UserRoleRelation(); - memberRole.setId(UUID.randomUUID().toString()); - memberRole.setUserId(userId); - memberRole.setRoleId(InternalUserRole.PROJECT_MEMBER.getValue()); - memberRole.setSourceId(projectId); - memberRole.setCreateTime(System.currentTimeMillis()); - memberRole.setCreateUser(createUser); - userRoleRelations.add(memberRole); - setLog(projectId, path, content + Translator.get("project_member") + ": " + user.getName(), createUser, "", type, method, logDTOList); - } - }); - }); - userRoleRelationMapper.batchInsert(userRoleRelations); - operationLogService.batchAdd(logDTOList); + public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser) { + commonProjectService.addProjectMember(request, createUser, ADD_MEMBER, + OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add"), OperationLogModule.SYSTEM_PROJECT); } - public int removeProjectMember(String projectId, String userId) { - UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); - userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) - .andSourceIdEqualTo(projectId); - User user = userMapper.selectByPrimaryKey(userId); - if (StringUtils.equals(projectId, user.getLastProjectId())) { - user.setLastProjectId(StringUtils.EMPTY); - userMapper.updateByPrimaryKeySelective(user); - } - List logDTOList = new ArrayList<>(); - setLog(projectId, REMOVE_PROJECT_MEMBER + "/" + projectId + "/" + userId, - Translator.get("delete") + Translator.get("project_member") + ": " + user.getName(), - userId, "", OperationLogType.DELETE.name(), HttpMethodConstants.GET.name(), logDTOList); - operationLogService.batchAdd(logDTOList); - return userRoleRelationMapper.deleteByExample(userRoleRelationExample); + public int removeProjectMember(String projectId, String userId, String createUser) { + return commonProjectService.removeProjectMember(projectId, userId, createUser,OperationLogModule.SYSTEM_PROJECT, StringUtils.join(REMOVE_PROJECT_MEMBER,projectId, "/", userId)); } public int revoke(String id) { - checkProjectNotExist(id); - Project project = new Project(); - project.setId(id); - project.setDeleted(false); - project.setDeleteTime(null); - project.setDeleteUser(null); - return projectMapper.updateByPrimaryKeySelective(project); + return commonProjectService.revoke(id); } public void deleteProject(List projects) { - // 删除项目 - List logDTOList = new ArrayList<>(); - projects.forEach(project -> { - serviceInvoker.invokeServices(project.getId()); - LogUtils.info("send delete_project message, project id: " + project.getId()); - //删除项目关联的自定义组织 - deleteProjectUserGroup(project.getId()); - // delete project - projectMapper.deleteByPrimaryKey(project.getId()); - setLog(project.getId(), "null", Translator.get("delete") + Translator.get("project") + ": " + project.getName(), - OperationLogConstants.SYSTEM, OperationLogConstants.SYSTEM, OperationLogType.DELETE.name(), "", logDTOList); - }); - operationLogService.batchAdd(logDTOList); + commonProjectService.deleteProject(projects); } - private void deleteProjectUserGroup(String projectId) { - UserRoleRelationExample userGroupExample = new UserRoleRelationExample(); - userGroupExample.createCriteria().andSourceIdEqualTo(projectId); - userRoleRelationMapper.deleteByExample(userGroupExample); - } public List getProjectOptions() { return extSystemProjectMapper.selectProjectOptions(); } - - private static void setLog(String projectId, String path, String content, String userId, Object originalValue, - String type, String method, List logDTOList) { - LogDTO dto = new LogDTO( - OperationLogConstants.SYSTEM, - OperationLogConstants.SYSTEM, - projectId, - userId, - type, - OperationLogModule.SYSTEM_PROJECT, - content); - dto.setPath(path); - dto.setMethod(method); - dto.setOriginalValue(JSON.toJSONBytes(originalValue)); - logDTOList.add(dto); - } } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationProjectControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationProjectControllerTests.java new file mode 100644 index 0000000000..f84eb051b3 --- /dev/null +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationProjectControllerTests.java @@ -0,0 +1,588 @@ +package io.metersphere.system.controller; + +import io.metersphere.project.domain.Project; +import io.metersphere.project.domain.ProjectExample; +import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.base.BaseTest; +import io.metersphere.sdk.constants.InternalUserRole; +import io.metersphere.sdk.constants.PermissionConstants; +import io.metersphere.sdk.constants.SessionConstants; +import io.metersphere.sdk.controller.handler.ResultHolder; +import io.metersphere.sdk.dto.AddProjectRequest; +import io.metersphere.sdk.dto.ProjectDTO; +import io.metersphere.sdk.dto.UpdateProjectRequest; +import io.metersphere.sdk.log.constants.OperationLogType; +import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.Pager; +import io.metersphere.system.domain.UserRoleRelation; +import io.metersphere.system.domain.UserRoleRelationExample; +import io.metersphere.system.dto.OrganizationDTO; +import io.metersphere.system.dto.UserExtend; +import io.metersphere.system.mapper.UserRoleRelationMapper; +import io.metersphere.system.request.OrganizationProjectRequest; +import io.metersphere.system.request.ProjectAddMemberRequest; +import io.metersphere.system.request.ProjectMemberRequest; +import io.metersphere.system.service.OrganizationService; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; +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.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultMatcher; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +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; + +@SpringBootTest +@AutoConfigureMockMvc +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class OrganizationProjectControllerTests extends BaseTest { + + @Resource + private MockMvc mockMvc; + + private final static String prefix = "/organization/project"; + private final static String addProject = prefix + "/add"; + private final static String updateProject = prefix + "/update"; + private final static String deleteProject = prefix + "/delete/"; + private final static String revokeProject = prefix + "/revoke/"; + private final static String getProject = prefix + "/get/"; + private final static String getProjectList = prefix + "/page"; + private final static String getProjectMemberList = prefix + "/member-list"; + private final static String addProjectMember = prefix + "/add-members"; + private final static String removeProjectMember = prefix + "/remove-member/"; + private static final ResultMatcher BAD_REQUEST_MATCHER = status().isBadRequest(); + private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError(); + + private static String projectId; + + @Resource + private ProjectMapper projectMapper; + @Resource + private UserRoleRelationMapper userRoleRelationMapper; + @Resource + private OrganizationService organizationService; + + private OrganizationDTO getDefault() { + return organizationService.getDefault(); + } + + private void requestPost(String url, Object param, ResultMatcher resultMatcher) throws Exception { + mockMvc.perform(MockMvcRequestBuilders.post(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .content(JSON.toJSONString(param)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(resultMatcher).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)); + } + + private MvcResult responsePost(String url, Object param) throws Exception { + return mockMvc.perform(MockMvcRequestBuilders.post(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .content(JSON.toJSONString(param)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); + } + + private MvcResult responseGet(String url) throws Exception { + return mockMvc.perform(MockMvcRequestBuilders.get(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); + } + private void responseGet(String url, ResultMatcher resultMatcher) throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get(url) + .header(SessionConstants.HEADER_TOKEN, sessionId) + .header(SessionConstants.CSRF_TOKEN, csrfToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(resultMatcher).andDo(print()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); + } + + public static T parseObjectFromMvcResult(MvcResult mvcResult, Class parseClass) { + try { + String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); + //返回请求正常 + Assertions.assertNotNull(resultHolder); + return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), parseClass); + } catch (Exception ignore) { + } + return null; + } + public static void compareProjectDTO(Project currentProject, Project result) { + Assertions.assertNotNull(currentProject); + Assertions.assertNotNull(result); + //判断ID是否一样 + Assertions.assertTrue(StringUtils.equals(currentProject.getId(), result.getId())); + //判断名称是否一样 + Assertions.assertTrue(StringUtils.equals(currentProject.getName(), result.getName())); + //判断组织是否一样 + Assertions.assertTrue(StringUtils.equals(currentProject.getOrganizationId(), result.getOrganizationId())); + //判断描述是否一样 + Assertions.assertTrue(StringUtils.equals(currentProject.getDescription(), result.getDescription())); + //判断是否启用 + Assertions.assertTrue(currentProject.getEnable() == result.getEnable()); + + } + + public AddProjectRequest generatorAdd(String organizationId, String name, String description, boolean enable, List userIds) { + AddProjectRequest addProjectDTO = new AddProjectRequest(); + addProjectDTO.setOrganizationId(organizationId); + addProjectDTO.setName(name); + addProjectDTO.setDescription(description); + addProjectDTO.setEnable(enable); + addProjectDTO.setUserIds(userIds); + return addProjectDTO; + } + public UpdateProjectRequest generatorUpdate(String organizationId, + String projectId, + String name, + String description, + boolean enable, + List userIds) { + UpdateProjectRequest updateProjectDTO = new UpdateProjectRequest(); + updateProjectDTO.setOrganizationId(organizationId); + updateProjectDTO.setId(projectId); + updateProjectDTO.setName(name); + updateProjectDTO.setDescription(description); + updateProjectDTO.setEnable(enable); + updateProjectDTO.setUserIds(userIds); + return updateProjectDTO; + } + @Test + @Order(1) + /** + * 测试添加项目成功的情况 + */ + public void testAddProjectSuccess() throws Exception { + AddProjectRequest project = this.generatorAdd("organizationId","organization-name", "description", true, List.of("admin")); + MvcResult mvcResult = this.responsePost(addProject, project); + Project result = this.parseObjectFromMvcResult(mvcResult, Project.class); + ProjectExample projectExample = new ProjectExample(); + projectExample.createCriteria().andOrganizationIdEqualTo(project.getOrganizationId()).andNameEqualTo(project.getName()); + List projects = projectMapper.selectByExample(projectExample); + projectId = result.getId(); + // 校验日志 + checkLog(projectId, OperationLogType.ADD); + + this.compareProjectDTO(projects.get(0), result); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + List userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin")), true); + userRoleRelationExample.createCriteria().andSourceIdEqualTo("organizationId").andRoleIdEqualTo(InternalUserRole.ORG_MEMBER.getValue()); + userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin")), true); + projectId = result.getId(); + // 校验日志 + checkLog(projectId, OperationLogType.ADD); + + //userId为空的时候 + project = this.generatorAdd("organizationId","organization-userIdIsNull", "description", true, new ArrayList<>()); + mvcResult = this.responsePost(addProject, project); + result = this.parseObjectFromMvcResult(mvcResult, Project.class); + projectExample = new ProjectExample(); + projectExample.createCriteria().andOrganizationIdEqualTo(project.getOrganizationId()).andNameEqualTo(project.getName()); + projects = projectMapper.selectByExample(projectExample); + projectId = result.getId(); + // 校验日志 + checkLog(projectId, OperationLogType.ADD); + + this.compareProjectDTO(projects.get(0), result); + userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin")), true); + userRoleRelationExample.createCriteria().andSourceIdEqualTo("organizationId").andRoleIdEqualTo(InternalUserRole.ORG_MEMBER.getValue()); + userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin")), true); + + project.setName("organization-testAddProjectSuccess1"); + project.setOrganizationId(getDefault().getId()); + // @@校验权限 + requestPostPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_ADD, addProject, project); + } + + @Test + @Order(2) + /** + * 测试添加项目失败的用例 + */ + public void testAddProjectError() throws Exception { + AddProjectRequest project = this.generatorAdd("organizationId","organization-nameError", "description", true, List.of("admin")); + this.responsePost(addProject, project); + //项目名称存在 500 + project = this.generatorAdd("organizationId","organization-nameError", "description", true, List.of("admin")); + this.requestPost(addProject, project, ERROR_REQUEST_MATCHER); + //参数组织Id为空 + project = this.generatorAdd(null, null, null, true, List.of("admin")); + this.requestPost(addProject, project, BAD_REQUEST_MATCHER); + //项目名称为空 + project = this.generatorAdd("organizationId", null, null, true, List.of("admin")); + this.requestPost(addProject, project, BAD_REQUEST_MATCHER); + //项目成员在系统中不存在 + project = this.generatorAdd("organizationId", "name", null, true, List.of("admin", "admin1", "admin3")); + this.requestPost(addProject, project, ERROR_REQUEST_MATCHER); + + } + @Test + @Order(3) + public void testGetProject() throws Exception { + AddProjectRequest project = this.generatorAdd("organizationId","organization-getName", "description", true, List.of("admin")); + MvcResult mvcResult = this.responsePost(addProject, project); + Project result = this.parseObjectFromMvcResult(mvcResult, Project.class); + projectId = result.getId(); + mvcResult = this.responseGet(getProject + projectId); + Project getProjects = this.parseObjectFromMvcResult(mvcResult, Project.class); + Assertions.assertTrue(StringUtils.equals(getProjects.getId(), projectId)); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ, getProject + projectId); + } + @Test + @Order(4) + public void testGetProjectError() throws Exception { + //项目不存在 + MvcResult mvcResult = this.responseGet(getProject + "111111"); + String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8); + ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class); + Assertions.assertNull(resultHolder.getData()); + } + + @Test + @Order(5) + public void testGetProjectList() throws Exception { + OrganizationProjectRequest projectRequest = new OrganizationProjectRequest(); + projectRequest.setCurrent(1); + projectRequest.setPageSize(10); + projectRequest.setOrganizationId(getDefault().getId()); + MvcResult mvcResult = this.responsePost(getProjectList, projectRequest); + Pager returnPager = parseObjectFromMvcResult(mvcResult, Pager.class); + //返回值不为空 + Assertions.assertNotNull(returnPager); + //返回值的页码和当前页码相同 + Assertions.assertEquals(returnPager.getCurrent(), projectRequest.getCurrent()); + //返回的数据量不超过规定要返回的数据量相同 + Assertions.assertTrue(((List) returnPager.getList()).size() <= projectRequest.getPageSize()); + projectRequest.setSort(new HashMap<>() {{ + put("createTime", "desc"); + }}); + mvcResult = this.responsePost(getProjectList, projectRequest); + returnPager = parseObjectFromMvcResult(mvcResult, Pager.class); + //第一个数据的createTime是最大的 + List projectDTOS = JSON.parseArray(JSON.toJSONString(returnPager.getList()), ProjectDTO.class); + long firstCreateTime = projectDTOS.get(0).getCreateTime(); + for (ProjectDTO projectDTO : projectDTOS) { + Assertions.assertFalse(projectDTO.getCreateTime() > firstCreateTime); + } + projectRequest.setFilter(new HashMap<>() {{ + put("createUser", List.of("test")); + }}); + mvcResult = this.responsePost(getProjectList, projectRequest); + returnPager = parseObjectFromMvcResult(mvcResult, Pager.class); + //返回的数据中的createUser是admin或者admin1 + projectDTOS = JSON.parseArray(JSON.toJSONString(returnPager.getList()), ProjectDTO.class); + //拿到所有的createUser + List createUsers = projectDTOS.stream().map(ProjectDTO::getCreateUser).collect(Collectors.toList()); + Assertions.assertTrue(List.of("test").containsAll(createUsers)); + // @@校验权限 + requestPostPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ, getProjectList, projectRequest); + } + + @Test + @Order(6) + public void testPageError() throws Exception { + //当前页码不大于0 + OrganizationProjectRequest projectRequest = new OrganizationProjectRequest(); + projectRequest.setPageSize(5); + projectRequest.setOrganizationId("organizationId"); + this.requestPost(getProjectList, projectRequest, BAD_REQUEST_MATCHER); + //当前页数不大于5 + projectRequest = new OrganizationProjectRequest(); + projectRequest.setCurrent(1); + projectRequest.setOrganizationId("organizationId"); + this.requestPost(getProjectList, projectRequest, BAD_REQUEST_MATCHER); + //当前页数大于100 + projectRequest = new OrganizationProjectRequest(); + projectRequest.setCurrent(1); + projectRequest.setPageSize(101); + projectRequest.setOrganizationId("organizationId"); + this.requestPost(getProjectList, projectRequest, BAD_REQUEST_MATCHER); + //排序字段不合法 + projectRequest = new OrganizationProjectRequest(); + projectRequest.setCurrent(1); + projectRequest.setPageSize(5); + projectRequest.setOrganizationId("organizationId"); + projectRequest.setSort(new HashMap<>() {{ + put("SELECT * FROM user", "asc"); + }}); + this.requestPost(getProjectList, projectRequest, BAD_REQUEST_MATCHER); + //组织id为空 + projectRequest = new OrganizationProjectRequest(); + projectRequest.setCurrent(1); + projectRequest.setPageSize(5); + this.requestPost(getProjectList, projectRequest, BAD_REQUEST_MATCHER); + } + + @Test + @Order(7) + public void testUpdateProject() throws Exception { + UpdateProjectRequest project = this.generatorUpdate("organizationId", projectId,"organization-TestName", "Edit name", true, List.of("admin", "admin1")); + MvcResult mvcResult = this.responsePost(updateProject, project); + Project result = this.parseObjectFromMvcResult(mvcResult, Project.class); + Project currentProject = projectMapper.selectByPrimaryKey(project.getId()); + this.compareProjectDTO(currentProject, result); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + List userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin", "admin1")), true); + userRoleRelationExample.createCriteria().andSourceIdEqualTo("organizationId").andRoleIdEqualTo(InternalUserRole.ORG_MEMBER.getValue()); + userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(List.of("admin", "admin1")), true); + + // 校验日志 + checkLog(projectId, OperationLogType.ADD); + //用户id为空 + project = this.generatorUpdate("organizationId", projectId, "organization-TestNameUserIdIsNull", "Edit name", true, new ArrayList<>()); + mvcResult = this.responsePost(updateProject, project); + result = this.parseObjectFromMvcResult(mvcResult, Project.class); + currentProject = projectMapper.selectByPrimaryKey(project.getId()); + this.compareProjectDTO(currentProject, result); + userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); + userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + //断言userRoleRelations是空的 + Assertions.assertTrue(userRoleRelations.isEmpty()); + // @@校验权限 + project.setName("organization-TestName2"); + project.setOrganizationId(getDefault().getId()); + requestPostPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE, updateProject, project); + // 校验日志 + checkLog(projectId, OperationLogType.UPDATE); + } + + @Test + @Order(8) + public void testUpdateProjectError() throws Exception { + //项目名称存在 500 + UpdateProjectRequest project = this.generatorUpdate(getDefault().getId(), "projectId1","organization-TestName2", "description", true, List.of("admin")); + this.requestPost(updateProject, project, ERROR_REQUEST_MATCHER); + //参数组织Id为空 + project = this.generatorUpdate(null, "projectId",null, null, true , List.of("admin")); + this.requestPost(updateProject, project, BAD_REQUEST_MATCHER); + //项目Id为空 + project = this.generatorUpdate("organizationId", null,null, null, true, List.of("admin")); + this.requestPost(updateProject, project, BAD_REQUEST_MATCHER); + //项目名称为空 + project = this.generatorUpdate("organizationId", "projectId",null, null, true, List.of("admin")); + this.requestPost(updateProject, project, BAD_REQUEST_MATCHER); + //项目不存在 + project = this.generatorUpdate("organizationId", "1111","123", null, true, List.of("admin")); + this.requestPost(updateProject, project, ERROR_REQUEST_MATCHER); + + } + + @Test + @Order(9) + public void testDeleteProject() throws Exception { + MvcResult mvcResult = this.responseGet(deleteProject + projectId); + int count = parseObjectFromMvcResult(mvcResult, Integer.class); + Project currentProject = projectMapper.selectByPrimaryKey(projectId); + Assertions.assertEquals(currentProject.getDeleted(), true); + Assertions.assertTrue(currentProject.getId().equals(projectId)); + Assertions.assertTrue(count == 1); + // 校验日志 + checkLog(projectId, OperationLogType.DELETE); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_DELETE, deleteProject + projectId); + } + + @Test + @Order(10) + public void testDeleteProjectError() throws Exception { + String id = "1111"; + this.responseGet(deleteProject + id, ERROR_REQUEST_MATCHER); + } + + @Test + @Order(11) + public void revokeSuccess() throws Exception { + MvcResult mvcResult = this.responseGet(revokeProject + projectId); + int count = parseObjectFromMvcResult(mvcResult, Integer.class); + Project currentProject = projectMapper.selectByPrimaryKey(projectId); + Assertions.assertEquals(currentProject.getDeleted(), false); + Assertions.assertTrue(currentProject.getId().equals(projectId)); + Assertions.assertTrue(count == 1); + // 校验日志 + checkLog(projectId, OperationLogType.RECOVER); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_RECOVER, revokeProject + projectId); + } + + @Test + @Order(12) + public void testRevokeProjectError() throws Exception { + String id = "1111"; + this.responseGet(revokeProject + id, ERROR_REQUEST_MATCHER); + } + + @Test + @Order(13) + public void testAddProjectMember() throws Exception{ + ProjectAddMemberRequest projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId(projectId); + List userIds = List.of("admin1", "admin2"); + projectAddMemberRequest.setUserIds(userIds); + this.requestPost(addProjectMember, projectAddMemberRequest, status().isOk()); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue()); + List userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds), true); + Assertions.assertTrue(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds)); + userRoleRelations.forEach(item ->{ + try { + checkLog(item.getId(), OperationLogType.ADD); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + // @@校验权限 + requestPostPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE, addProjectMember, projectAddMemberRequest); + } + + @Test + @Order(14) + public void testAddProjectMemberError() throws Exception{ + //项目Id为空 + ProjectAddMemberRequest projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId(null); + this.requestPost(addProjectMember, projectAddMemberRequest, BAD_REQUEST_MATCHER); + //用户Id为空 + projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId("projectId"); + this.requestPost(addProjectMember, projectAddMemberRequest, BAD_REQUEST_MATCHER); + //用户Id不存在 + projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId("projectId"); + projectAddMemberRequest.setUserIds(List.of("admin3")); + this.requestPost(addProjectMember, projectAddMemberRequest, ERROR_REQUEST_MATCHER); + //项目id不存在 + projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId("projectId111"); + projectAddMemberRequest.setUserIds(List.of("admin1")); + this.requestPost(addProjectMember, projectAddMemberRequest, ERROR_REQUEST_MATCHER); + } + + @Test + @Order(15) + public void testGetMemberSuccess() throws Exception { + ProjectMemberRequest memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + memberRequest.setPageSize(5); + memberRequest.setProjectId(projectId); + MvcResult mvcResult = this.responsePost(getProjectMemberList, memberRequest); + Pager returnPager = parseObjectFromMvcResult(mvcResult, Pager.class); + //返回值不为空 + Assertions.assertNotNull(returnPager); + //返回值的页码和当前页码相同 + Assertions.assertEquals(returnPager.getCurrent(), memberRequest.getCurrent()); + //返回的数据量不超过规定要返回的数据量相同 + Assertions.assertTrue(((List) returnPager.getList()).size() <= memberRequest.getPageSize()); + memberRequest.setSort(new HashMap<>() {{ + put("createTime", "desc"); + }}); + mvcResult = this.responsePost(getProjectMemberList, memberRequest); + returnPager = parseObjectFromMvcResult(mvcResult, Pager.class); + //第一个数据的createTime是最大的 + List userExtends = JSON.parseArray(JSON.toJSONString(returnPager.getList()), UserExtend.class); + long firstCreateTime = userExtends.get(0).getCreateTime(); + for (UserExtend userExtend : userExtends) { + Assertions.assertFalse(userExtend.getCreateTime() > firstCreateTime); + } + // @@校验权限 + requestPostPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ, getProjectMemberList, memberRequest); + } + + @Test + @Order(16) + public void testGetMemberError() throws Exception { + //当前页码不大于0 + ProjectMemberRequest memberRequest = new ProjectMemberRequest(); + memberRequest.setPageSize(5); + this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + //当前页数不大于5 + memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + //当前页数大于100 + memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + memberRequest.setPageSize(101); + this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + //项目Id为空 + memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + memberRequest.setPageSize(5); + this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + //排序字段不合法 + memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + memberRequest.setPageSize(5); + memberRequest.setProjectId("projectId1"); + memberRequest.setSort(new HashMap<>() {{ + put("SELECT * FROM user", "asc"); + }}); + this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + } + + @Test + @Order(17) + public void testRemoveProjectMember() throws Exception{ + String userId = "admin1"; + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(projectId).andUserIdEqualTo(userId); + List userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); + MvcResult mvcResult = this.responseGet(removeProjectMember + projectId + "/" + userId); + int count = parseObjectFromMvcResult(mvcResult, Integer.class); + Assertions.assertTrue(count == userRoleRelations.size()); + // 校验日志 + checkLog(userRoleRelations.get(0).getId(), OperationLogType.DELETE); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.ORGANIZATION_PROJECT_READ_UPDATE, removeProjectMember + projectId + "/" + userId); + } + + @Test + @Order(18) + public void testRemoveProjectMemberError() throws Exception{ + String userId = "admin1"; + MvcResult mvcResult = this.responseGet(removeProjectMember + projectId + "/" + userId); + int count = parseObjectFromMvcResult(mvcResult, Integer.class); + Assertions.assertTrue(count == 0); + + //用户Id不存在 + projectId = "projectId1"; + userId = "admin34"; + this.responseGet(removeProjectMember + projectId + "/" + userId, ERROR_REQUEST_MATCHER); + //项目id不存在 + projectId = "projectId111"; + userId = "admin1"; + this.responseGet(removeProjectMember + projectId + "/" + userId, ERROR_REQUEST_MATCHER); + } + +} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java index dc70ccfd27..7e11e35943 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemProjectControllerTests.java @@ -232,7 +232,7 @@ public class SystemProjectControllerTests extends BaseTest { project = this.generatorAdd("organizationId", null, null, true, List.of("admin")); this.requestPost(addProject, project, BAD_REQUEST_MATCHER); //项目成员在系统中不存在 - project = this.generatorAdd("organizationId", "name", null, true, List.of("admin", "admin1", "admin2")); + project = this.generatorAdd("organizationId", "name", null, true, List.of("admin", "admin1", "admin3")); this.requestPost(addProject, project, ERROR_REQUEST_MATCHER); } @@ -432,6 +432,8 @@ public class SystemProjectControllerTests extends BaseTest { List userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds), true); Assertions.assertTrue(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds)); + // @@校验权限 + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE, addProjectMember, projectAddMemberRequest); } @Test @@ -450,6 +452,11 @@ public class SystemProjectControllerTests extends BaseTest { projectAddMemberRequest.setProjectId("projectId"); projectAddMemberRequest.setUserIds(List.of("admin3")); this.requestPost(addProjectMember, projectAddMemberRequest, ERROR_REQUEST_MATCHER); + //项目id不存在 + projectAddMemberRequest = new ProjectAddMemberRequest(); + projectAddMemberRequest.setProjectId("projectId111"); + projectAddMemberRequest.setUserIds(List.of("admin1")); + this.requestPost(addProjectMember, projectAddMemberRequest, ERROR_REQUEST_MATCHER); } @Test @@ -478,6 +485,9 @@ public class SystemProjectControllerTests extends BaseTest { for (UserExtend userExtend : userExtends) { Assertions.assertFalse(userExtend.getCreateTime() > firstCreateTime); } + // @@校验权限 + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, getProjectMemberList, memberRequest); + } @Test @@ -501,6 +511,12 @@ public class SystemProjectControllerTests extends BaseTest { memberRequest.setCurrent(1); memberRequest.setPageSize(5); this.requestPost(getProjectMemberList, memberRequest, BAD_REQUEST_MATCHER); + //项目Id不存在 + memberRequest = new ProjectMemberRequest(); + memberRequest.setCurrent(1); + memberRequest.setPageSize(5); + memberRequest.setProjectId("projectId111"); + this.requestPost(getProjectMemberList, memberRequest, ERROR_REQUEST_MATCHER); //排序字段不合法 memberRequest = new ProjectMemberRequest(); memberRequest.setCurrent(1); @@ -523,6 +539,8 @@ public class SystemProjectControllerTests extends BaseTest { MvcResult mvcResult = this.responseGet(removeProjectMember + projectId + "/" + userId); int count = parseObjectFromMvcResult(mvcResult, Integer.class); Assertions.assertTrue(count == userRoleRelations.size()); + // @@校验权限 + requestGetPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE, removeProjectMember + projectId + "/" + userId); } @Test @@ -533,6 +551,15 @@ public class SystemProjectControllerTests extends BaseTest { MvcResult mvcResult = this.responseGet(removeProjectMember + projectId + "/" + userId); int count = parseObjectFromMvcResult(mvcResult, Integer.class); Assertions.assertTrue(count == 0); + + //用户Id不存在 + projectId = "projectId1"; + userId = "admin34"; + this.responseGet(removeProjectMember + projectId + "/" + userId, ERROR_REQUEST_MATCHER); + //项目id不存在 + projectId = "projectId111"; + userId = "admin1"; + this.responseGet(removeProjectMember + projectId + "/" + userId, ERROR_REQUEST_MATCHER); } } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/job/LicenseCacheTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/job/LicenseCacheTests.java deleted file mode 100644 index fab7da7231..0000000000 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/job/LicenseCacheTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.metersphere.system.job; - -import io.metersphere.sdk.base.BaseTest; -import jakarta.annotation.Resource; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -@AutoConfigureMockMvc -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class LicenseCacheTests extends BaseTest { - @Resource - private LicenseCacheJob licenseCacheJob; - - - @Test - public void cleanupProject() throws Exception{ - //TODO - licenseCacheJob.checkLicenseTask(); - } -} diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/service/LicenseServiceImpl.java b/backend/services/system-setting/src/test/java/io/metersphere/system/service/LicenseServiceImpl.java deleted file mode 100644 index 1185e3bffb..0000000000 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/service/LicenseServiceImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.metersphere.system.service; - -import io.metersphere.sdk.dto.LicenseDTO; -import io.metersphere.sdk.service.LicenseService; -import org.springframework.stereotype.Service; - -@Service -public class LicenseServiceImpl implements LicenseService { - - public synchronized LicenseDTO refreshLicense() { - LicenseDTO licenseDTO = new LicenseDTO(); - return licenseDTO; - } - - @Override - public LicenseDTO validate() { - LicenseDTO licenseDTO = new LicenseDTO(); - return licenseDTO; - } - - @Override - public LicenseDTO addLicense(String licenseCode) { - LicenseDTO licenseDTO = new LicenseDTO(); - return licenseDTO; - } - - -} diff --git a/backend/services/system-setting/src/test/resources/dml/init_clean_project.sql b/backend/services/system-setting/src/test/resources/dml/init_clean_project.sql index 47c347b916..657f1b36af 100644 --- a/backend/services/system-setting/src/test/resources/dml/init_clean_project.sql +++ b/backend/services/system-setting/src/test/resources/dml/init_clean_project.sql @@ -1,3 +1,9 @@ # 插入测试数据 INSERT INTO `project` VALUES ('projectId1', null, '3a5b1bd3-05e5-11ee-ad96-0242ac1e0a02', '默认项目2', '系统默认创建的项目', 1686219258000, 1686219258000, 'admin', 1683464436000, 1, NULL, true); INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time, delete_time,deleted) VALUES ('projectId6', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目6', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000, 1683464436000 , 1); +INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE + ('default-pro-role-delete-id', 'default-pro-role-delete', 'XXX', FALSE, 'PROJECT', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'projectId6'); +INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user) VALUE + (UUID(), 'admin', 'default-pro-role-delete-id', 'projectId6', UNIX_TIMESTAMP() * 1000, 'admin'); +INSERT INTO user_role_permission (id, role_id, permission_id) VALUE + (uuid(), 'default-pro-role-delete-id', 'ORGANIZATION_USER_ROLE:READ');