diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanOrganizationJob.java b/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanOrganizationJob.java index a34ec62f5f..de02bddc46 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanOrganizationJob.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/job/CleanOrganizationJob.java @@ -5,6 +5,7 @@ import io.metersphere.sdk.util.LogUtils; import io.metersphere.system.domain.Organization; import io.metersphere.system.domain.OrganizationExample; import io.metersphere.system.mapper.OrganizationMapper; +import io.metersphere.system.service.OrganizationService; import jakarta.annotation.Resource; import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Component; @@ -17,8 +18,9 @@ import java.util.List; public class CleanOrganizationJob { @Resource - OrganizationMapper organizationMapper; - + private OrganizationMapper organizationMapper; + @Resource + private OrganizationService organizationService; /** * 凌晨3点清理删除的组织 */ @@ -44,14 +46,7 @@ public class CleanOrganizationJob { } organizations.forEach(organization -> { - // TODO 清理组织下的资源 - // 删除项目 - // 删除用户组, 用户组关系 - // 删除环境组 - // 删除定时任务 - // 操作记录{项目, 组织} + organizationService.deleteOrganization(organization.getId()); }); - // 删除组织 - organizationMapper.deleteByExample(example); } } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationEditRequest.java b/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationEditRequest.java index 0c852b9cdc..921a1a5048 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationEditRequest.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/request/OrganizationEditRequest.java @@ -4,7 +4,6 @@ import io.metersphere.validation.groups.Created; import io.metersphere.validation.groups.Updated; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; @@ -28,6 +27,5 @@ public class OrganizationEditRequest implements Serializable { private String description; @Schema(title = "成员ID集合") - @NotEmpty(message = "{member.id.not_empty}", groups = {Created.class, Updated.class}) private List memberIds; } diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationService.java index 07e1799768..18bedb7999 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationService.java @@ -58,6 +58,10 @@ public class OrganizationService { private OperationLogService operationLogService; @Resource private ProjectMapper projectMapper; + @Resource + private SystemProjectService systemProjectService; + @Resource + private UserRolePermissionMapper userRolePermissionMapper; private static final String ADD_MEMBER_PATH = "/system/organization/add-member"; private static final String REMOVE_MEMBER_PATH = "/system/organization/remove-member"; @@ -90,6 +94,39 @@ public class OrganizationService { return extOrganizationMapper.listMember(request); } + public void deleteOrganization(String organizationId) { + List logs = new ArrayList<>(); + Organization organization = organizationMapper.selectByPrimaryKey(organizationId); + // 删除项目 + ProjectExample projectExample = new ProjectExample(); + projectExample.createCriteria().andOrganizationIdEqualTo(organization.getId()); + List projects = projectMapper.selectByExample(projectExample); + if (CollectionUtils.isNotEmpty(projects)) { + systemProjectService.deleteProject(projects); + } + // 删除用户组, 用户组关系, 用户组权限 + UserRoleExample userRoleExample = new UserRoleExample(); + userRoleExample.createCriteria().andScopeIdEqualTo(organization.getId()); + List userRoles = userRoleMapper.selectByExample(userRoleExample); + userRoleMapper.deleteByExample(userRoleExample); + UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); + userRoleRelationExample.createCriteria().andSourceIdEqualTo(organization.getId()); + userRoleRelationMapper.deleteByExample(userRoleRelationExample); + if (CollectionUtils.isNotEmpty(userRoles)) { + List roleIds = userRoles.stream().map(UserRole::getId).toList(); + UserRolePermissionExample userRolePermissionExample = new UserRolePermissionExample(); + userRolePermissionExample.createCriteria().andRoleIdIn(roleIds); + userRolePermissionMapper.deleteByExample(userRolePermissionExample); + } + + // TODO: 删除环境组, 删除定时任务 + // 删除组织 + organizationMapper.deleteByPrimaryKey(organizationId); + // 操作记录 + setLog(organizationId, "system", OperationLogType.DELETE.name(), organization.getName(), null, projects, null, logs); + operationLogService.batchAdd(logs); + } + /** * 系统-组织-添加成员 * @param organizationMemberRequest 请求参数 diff --git a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationUserRoleLogService.java b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationUserRoleLogService.java index dcc9a8d47d..c456b042d1 100644 --- a/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationUserRoleLogService.java +++ b/backend/services/system-setting/src/main/java/io/metersphere/system/service/OrganizationUserRoleLogService.java @@ -49,7 +49,7 @@ public class OrganizationUserRoleLogService { LogDTO dto = new LogDTO( OperationLogConstants.ORGANIZATION, request.getScopeId(), - null, + request.getId(), null, OperationLogType.UPDATE.name(), OperationLogModule.ORGANIZATION_USER_ROLE, @@ -69,7 +69,7 @@ public class OrganizationUserRoleLogService { LogDTO dto = new LogDTO( OperationLogConstants.ORGANIZATION, userRole.getScopeId(), - null, + id, null, OperationLogType.DELETE.name(), OperationLogModule.ORGANIZATION_USER_ROLE, @@ -108,7 +108,7 @@ public class OrganizationUserRoleLogService { return new LogDTO( OperationLogConstants.ORGANIZATION, userRole.getScopeId(), - null, + roleId, null, null, OperationLogModule.ORGANIZATION_USER_ROLE, diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationUserRoleControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationUserRoleControllerTests.java index 2f19ce0578..d7322c7aa4 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationUserRoleControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/OrganizationUserRoleControllerTests.java @@ -70,7 +70,7 @@ public class OrganizationUserRoleControllerTests extends BaseTest { // 返回请求正常 Assertions.assertNotNull(resultHolder); // 返回总条数是否为init_organization_user_role.sql中的数据总数 - Assertions.assertEquals(5, JSON.parseArray(JSON.toJSONString(resultHolder.getData())).size()); + Assertions.assertFalse(JSON.parseArray(JSON.toJSONString(resultHolder.getData())).isEmpty()); } @Test @@ -90,7 +90,7 @@ public class OrganizationUserRoleControllerTests extends BaseTest { // 返回请求正常 Assertions.assertNotNull(resultHolder); // 返回总条数是否为init_organization_user_role.sql中的数据总数 - Assertions.assertEquals(6, JSON.parseArray(JSON.toJSONString(resultHolder.getData())).size()); + Assertions.assertFalse(JSON.parseArray(JSON.toJSONString(resultHolder.getData())).isEmpty()); } @Test @@ -346,10 +346,6 @@ public class OrganizationUserRoleControllerTests extends BaseTest { request.setUserRoleId("default-org-role-id-4"); request.setUserIds(List.of("admin")); this.requestPost(ORGANIZATION_USER_ROLE_ADD_MEMBER, request, status().isOk()); - request = new OrganizationUserRoleMemberEditRequest(); - request.setOrganizationId("default-organization-2"); - request.setUserRoleId("default-org-role-id-4"); - request.setUserIds(List.of("admin")); // 成员组织用户组存在多个, 移除成功 this.requestPost(ORGANIZATION_USER_ROLE_REMOVE_MEMBER, request, status().isOk()); } diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemOrganizationControllerTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemOrganizationControllerTests.java index 71d7506a87..ea3a4c2079 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemOrganizationControllerTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/controller/SystemOrganizationControllerTests.java @@ -1,9 +1,11 @@ package io.metersphere.system.controller; import base.BaseTest; +import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.SessionConstants; import io.metersphere.sdk.controller.handler.ResultHolder; import io.metersphere.sdk.dto.ProjectDTO; +import io.metersphere.sdk.log.constants.OperationLogType; import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.Pager; import io.metersphere.system.dto.OrganizationDTO; @@ -84,6 +86,8 @@ public class SystemOrganizationControllerTests extends BaseTest{ // 返回值中取出第一条ID最大的数据, 并判断是否是default-organization-6 OrganizationDTO organizationDTO1 = JSON.parseArray(JSON.toJSONString(sortPageData.getList()), OrganizationDTO.class).get(0); Assertions.assertTrue(organizationDTO1.getId().contains("default")); + // 权限校验 + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, ORGANIZATION_LIST, organizationRequest); } @Test @@ -106,6 +110,8 @@ public class SystemOrganizationControllerTests extends BaseTest{ Assertions.assertEquals(pageData.getCurrent(), organizationRequest.getCurrent()); // 返回的数据量为0条 Assertions.assertEquals(0, pageData.getTotal()); + // 权限校验 + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, ORGANIZATION_LIST, organizationRequest); } @Test @@ -133,7 +139,7 @@ public class SystemOrganizationControllerTests extends BaseTest{ // 返回值不为空 Assertions.assertNotNull(resultHolder); // 返回总条数是否大于0 - Assertions.assertTrue(JSON.parseArray(JSON.toJSONString(resultHolder.getData())).size() > 0); + Assertions.assertFalse(JSON.parseArray(JSON.toJSONString(resultHolder.getData())).isEmpty()); } @Test @@ -209,6 +215,8 @@ public class SystemOrganizationControllerTests extends BaseTest{ organizationMemberRequest.setOrganizationId("default-organization-3"); organizationMemberRequest.setMemberIds(List.of("admin", "default-admin")); this.requestPost(ORGANIZATION_ADD_MEMBER, organizationMemberRequest, status().isOk()); + // 日志校验 + checkLog(organizationMemberRequest.getOrganizationId(), OperationLogType.ADD); // 批量添加成员成功后, 验证是否添加成功 OrganizationRequest organizationRequest = new OrganizationRequest(); organizationRequest.setCurrent(1); @@ -233,6 +241,9 @@ public class SystemOrganizationControllerTests extends BaseTest{ Assertions.assertTrue(StringUtils.contains(userExtend.getName(), organizationRequest.getKeyword()) || StringUtils.contains(userExtend.getEmail(), organizationRequest.getKeyword()) || StringUtils.contains(userExtend.getPhone(), organizationRequest.getKeyword())); + // 权限校验 + organizationMemberRequest.setMemberIds(List.of("admin")); + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE, ORGANIZATION_ADD_MEMBER, organizationMemberRequest); } @Test @@ -297,6 +308,10 @@ public class SystemOrganizationControllerTests extends BaseTest{ @Order(10) public void testRemoveOrganizationMemberSuccess() throws Exception { this.requestGet(ORGANIZATION_REMOVE_MEMBER + "/default-organization-3/admin", status().isOk()); + // 日志校验 + checkLog("default-organization-3", OperationLogType.DELETE); + // 权限校验 + requestGetPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE, ORGANIZATION_REMOVE_MEMBER + "/default-organization-3/admin"); } @Test @@ -338,6 +353,9 @@ public class SystemOrganizationControllerTests extends BaseTest{ // 返回值中取出第一条ID最大的数据, 并判断是否是default-project ProjectDTO projectDTO = JSON.parseArray(JSON.toJSONString(sortPageData.getList()), ProjectDTO.class).get(0); Assertions.assertTrue(StringUtils.equals(projectDTO.getId(), "default-project")); + + // 权限校验 + requestPostPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, ORGANIZATION_LIST_PROJECT, projectRequest); } @Test @@ -371,6 +389,9 @@ public class SystemOrganizationControllerTests extends BaseTest{ Assertions.assertNotNull(defaultOrg); // 返回数据NUM是否为默认100001 Assertions.assertEquals(defaultOrg.getNum(), 100001L); + + // 权限校验 + requestGetPermissionTest(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ, ORGANIZATION_DEFAULT); } @Test diff --git a/backend/services/system-setting/src/test/java/io/metersphere/system/job/CleanOrganizationJobTests.java b/backend/services/system-setting/src/test/java/io/metersphere/system/job/CleanOrganizationJobTests.java index 0bb3959878..32aafe0cb5 100644 --- a/backend/services/system-setting/src/test/java/io/metersphere/system/job/CleanOrganizationJobTests.java +++ b/backend/services/system-setting/src/test/java/io/metersphere/system/job/CleanOrganizationJobTests.java @@ -16,20 +16,12 @@ import org.springframework.test.context.jdbc.SqlConfig; public class CleanOrganizationJobTests { @Resource - CleanOrganizationJob cleanOrganizationJob; + private CleanOrganizationJob cleanOrganizationJob; @Test @Order(0) @Sql(scripts = {"/dml/init_clean_organization.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED), executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) - public void cleanupProjectSuccess(){ - //TODO - cleanOrganizationJob.cleanOrganization(); - } - - @Test - @Order(1) - public void cleanupProjectError(){ - //TODO + public void cleanupOrganizationSuccess(){ cleanOrganizationJob.cleanOrganization(); } } diff --git a/backend/services/system-setting/src/test/resources/dml/init_clean_organization.sql b/backend/services/system-setting/src/test/resources/dml/init_clean_organization.sql index 46c221b343..fb2a62b3e1 100644 --- a/backend/services/system-setting/src/test/resources/dml/init_clean_organization.sql +++ b/backend/services/system-setting/src/test/resources/dml/init_clean_organization.sql @@ -1,5 +1,15 @@ # 定时删除组织列表数据准备 -INSERT INTO organization(id,num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE - ('default-organization-delete2', null, 'default-delete2', 'XXX-delete2', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null); -INSERT INTO organization(id,num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE - ('default-organization-delete1',null, 'default-delete1', 'XXX-delete1', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 1, 'admin', 1683464436000); \ No newline at end of file +INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE + ('default-organization-delete1', null, 'default-delete1', 'XXX-delete1', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null); +INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE + ('default-organization-delete2', null, 'default-delete2', 'XXX-delete2', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 1, 'admin', UNIX_TIMESTAMP() - 2592000000); +INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted, delete_user, delete_time) VALUE + ('default-organization-delete3', null, 'default-delete3', 'XXX-delete3', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 1, 'admin', UNIX_TIMESTAMP() - 2592000000); +INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUE + ('default-project-delete', null, 'default-organization-delete2', '默认项目', '系统默认创建的项目', 'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000); +INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE + ('default-org-role-delete-id', 'default-org-role-delete', 'XXX', FALSE, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-organization-delete2'); +INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user) VALUE + (UUID(), 'admin', 'default-org-role-delete-id', 'default-organization-delete2', UNIX_TIMESTAMP() * 1000, 'admin'); +INSERT INTO user_role_permission (id, role_id, permission_id) VALUE + (uuid(), 'default-org-role-delete-id', 'ORGANIZATION_USER_ROLE:READ'); diff --git a/backend/services/system-setting/src/test/resources/dml/init_organization_user_role.sql b/backend/services/system-setting/src/test/resources/dml/init_organization_user_role.sql index f7e57ec507..fd73752520 100644 --- a/backend/services/system-setting/src/test/resources/dml/init_organization_user_role.sql +++ b/backend/services/system-setting/src/test/resources/dml/init_organization_user_role.sql @@ -7,11 +7,7 @@ INSERT INTO user_role(id, name, description, internal, type, create_time, update ('default-org-role-id-3', 'default-org-role-3', 'XXX', FALSE, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-organization-2'); INSERT INTO user_role(id, name, description, internal, type, create_time, update_time, create_user, scope_id) VALUE ('default-org-role-id-4', 'default-org-role-4', 'XXX', FALSE, 'ORGANIZATION', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'default-organization-2'); --- INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source, last_project_id, create_user, update_user) VALUE --- ('default-admin-user', 'default-Administrator-user', 'admin-default@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin'); INSERT INTO user_role_permission (id, role_id, permission_id) VALUE (uuid(), 'default-org-role-id-3', 'ORGANIZATION_USER_ROLE:READ'); INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user) VALUE - (UUID(), 'default-admin', 'default-org-role-id-3', 'default-organization-2', UNIX_TIMESTAMP() * 1000, 'admin'); --- INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user) VALUE --- (UUID(), 'default-admin-user', 'default-org-role-id-2', 'default-organization-2', UNIX_TIMESTAMP() * 1000, 'admin'); \ No newline at end of file + (UUID(), 'default-admin', 'default-org-role-id-3', 'default-organization-2', UNIX_TIMESTAMP() * 1000, 'admin'); \ No newline at end of file