diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/PermissionRepository.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/PermissionRepository.java index 809b8e90bd8..8e58ba07c92 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/PermissionRepository.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/PermissionRepository.java @@ -47,6 +47,9 @@ List findByPermissionTypeInAndTargetId(Collection permission + "OR p.targetId like CONCAT(?1, '+', ?2, '+%')") List findPermissionIdsByAppIdAndNamespace(String appId, String namespaceName); + @Query("SELECT p.id from Permission p where p.targetId = CONCAT(?1, '+', ?2, '+', ?3)") + List findPermissionIdsByAppIdAndCluster(String appId, String env, String clusterName); + @Modifying @Query("UPDATE Permission SET IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000), DataChange_LastModifiedBy = ?2 WHERE Id in ?1 and IsDeleted = false") Integer batchDelete(List permissionIds, String operator); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/RoleRepository.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/RoleRepository.java index 78c4c72cbc0..6e4292500ce 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/RoleRepository.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/repository/RoleRepository.java @@ -35,6 +35,8 @@ public interface RoleRepository extends PagingAndSortingRepository { @Query("SELECT r.id from Role r where r.roleName like CONCAT('Master+', ?1) " + "OR r.roleName like CONCAT('ModifyNamespace+', ?1, '+%') " + "OR r.roleName like CONCAT('ReleaseNamespace+', ?1, '+%') " + + "OR r.roleName like CONCAT('ModifyNamespacesInCluster+', ?1, '+%') " + + "OR r.roleName like CONCAT('ReleaseNamespacesInCluster+', ?1, '+%') " + "OR r.roleName like CONCAT('ManageAppMaster+', ?1)") List findRoleIdsByAppId(String appId); @@ -44,6 +46,10 @@ public interface RoleRepository extends PagingAndSortingRepository { + "OR r.roleName like CONCAT('ReleaseNamespace+', ?1, '+', ?2, '+%')") List findRoleIdsByAppIdAndNamespace(String appId, String namespaceName); + @Query("SELECT r.id from Role r where r.roleName = CONCAT('ModifyNamespacesInCluster+', ?1, '+', ?2, '+', ?3) " + + "OR r.roleName = CONCAT('ReleaseNamespacesInCluster+', ?1, '+', ?2, '+', ?3)") + List findRoleIdsByAppIdAndCluster(String appId, String env, String clusterName); + @Modifying @Query("UPDATE Role SET IsDeleted = true, DeletedAt = ROUND(UNIX_TIMESTAMP(NOW(4))*1000), DataChange_LastModifiedBy = ?2 WHERE Id in ?1 and IsDeleted = false") Integer batchDelete(List roleIds, String operator); diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java index a01c26201b3..cb653c85440 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ClusterService.java @@ -22,6 +22,8 @@ import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.constant.TracerEventType; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; +import com.ctrip.framework.apollo.portal.service.RoleInitializationService; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.tracer.Tracer; import org.springframework.stereotype.Service; @@ -33,12 +35,14 @@ public class ClusterService { private final UserInfoHolder userInfoHolder; private final AdminServiceAPI.ClusterAPI clusterAPI; private final RoleInitializationService roleInitializationService; + private final RolePermissionService rolePermissionService; public ClusterService(final UserInfoHolder userInfoHolder, final AdminServiceAPI.ClusterAPI clusterAPI, - RoleInitializationService roleInitializationService) { + RoleInitializationService roleInitializationService, final RolePermissionService rolePermissionService) { this.userInfoHolder = userInfoHolder; this.clusterAPI = clusterAPI; this.roleInitializationService = roleInitializationService; + this.rolePermissionService = rolePermissionService; } public List findClusters(Env env, String appId) { @@ -60,7 +64,9 @@ public ClusterDTO createCluster(Env env, ClusterDTO cluster) { } public void deleteCluster(Env env, String appId, String clusterName){ - clusterAPI.delete(env, appId, clusterName, userInfoHolder.getUser().getUserId()); + String operator = userInfoHolder.getUser().getUserId(); + rolePermissionService.deleteRolePermissionsByAppIdAndCluster(appId, env.getName(), clusterName, operator); + clusterAPI.delete(env, appId, clusterName, operator); } public ClusterDTO loadCluster(String appId, Env env, String clusterName){ diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RolePermissionService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RolePermissionService.java index 538baea2aa9..3b7685a5705 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RolePermissionService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RolePermissionService.java @@ -87,4 +87,9 @@ Set assignRoleToUsers(String roleName, Set userIds, * delete permissions when delete app namespace. */ void deleteRolePermissionsByAppIdAndNamespace(String appId, String namespaceName, String operator); + + /** + * delete permissions when delete cluster. + */ + void deleteRolePermissionsByAppIdAndCluster(String appId, String env, String clusterName, String operator); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java index dfa057ef36e..b09c5bdb907 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java @@ -348,4 +348,32 @@ public void deleteRolePermissionsByAppIdAndNamespace(String appId, String namesp consumerRoleRepository.batchDeleteByRoleIds(roleIds, operator); } } + + @Transactional + @Override + public void deleteRolePermissionsByAppIdAndCluster(String appId, String env, String clusterName, String operator) { + appId = EscapeCharacter.DEFAULT.escape(appId); + List permissionIds = permissionRepository.findPermissionIdsByAppIdAndCluster(appId, env, clusterName); + + if (!permissionIds.isEmpty()) { + // 1. delete Permission + permissionRepository.batchDelete(permissionIds, operator); + + // 2. delete Role Permission + rolePermissionRepository.batchDeleteByPermissionIds(permissionIds, operator); + } + + List roleIds = roleRepository.findRoleIdsByAppIdAndCluster(appId, env, clusterName); + + if (!roleIds.isEmpty()) { + // 3. delete Role + roleRepository.batchDelete(roleIds, operator); + + // 4. delete User Role + userRoleRepository.batchDeleteByRoleIds(roleIds, operator); + + // 5. delete Consumer Role + consumerRoleRepository.batchDeleteByRoleIds(roleIds, operator); + } + } } diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/ClusterServiceTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/ClusterServiceTest.java new file mode 100644 index 00000000000..3dd5393a026 --- /dev/null +++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/ClusterServiceTest.java @@ -0,0 +1,48 @@ +package com.ctrip.framework.apollo.portal.service; + +import com.ctrip.framework.apollo.portal.environment.Env; +import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; +import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; +import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; +import com.ctrip.framework.apollo.portal.service.RoleInitializationService; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import static org.mockito.Mockito.*; + +public class ClusterServiceTest extends com.ctrip.framework.apollo.portal.AbstractUnitTest { + + @Mock + private AdminServiceAPI.ClusterAPI clusterAPI; + @Mock + private RoleInitializationService roleInitializationService; + @Mock + private RolePermissionService rolePermissionService; + @Mock + private UserInfoHolder userInfoHolder; + + @InjectMocks + private ClusterService clusterService; + + private String appId = "clusterApp"; + private String clusterName = "default"; + private Env env = Env.DEV; + + @Before + public void setUp() { + UserInfo user = new UserInfo(); + user.setUserId("operator"); + when(userInfoHolder.getUser()).thenReturn(user); + } + + @Test + public void testDeleteClusterShouldCleanupRoles() { + clusterService.deleteCluster(env, appId, clusterName); + + verify(rolePermissionService).deleteRolePermissionsByAppIdAndCluster(appId, env.getName(), clusterName, "operator"); + verify(clusterAPI).delete(env, appId, clusterName, "operator"); + } +} diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java index b9dba9404c7..3bb6fab47b3 100644 --- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java +++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java @@ -32,6 +32,7 @@ import com.ctrip.framework.apollo.portal.repository.RoleRepository; import com.ctrip.framework.apollo.portal.repository.UserRoleRepository; import com.ctrip.framework.apollo.portal.service.RolePermissionService; +import com.ctrip.framework.apollo.portal.util.RoleUtils; import com.google.common.collect.Sets; import java.util.List; import java.util.Set; @@ -320,6 +321,40 @@ public void testUserHasPermission() throws Exception { } + @Test + @Sql(scripts = "/sql/permission/RolePermissionServiceTest.deleteRolePermissionsByAppIdWithClusterRoles.sql", + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) + public void testDeleteRolePermissionsByAppIdWithClusterRoles() { + String appId = "clusterApp"; + String operator = "test"; + + rolePermissionService.deleteRolePermissionsByAppId(appId, operator); + + String modifyRoleName = RoleUtils.buildModifyNamespacesInClusterRoleName(appId, "DEV", "default"); + String releaseRoleName = RoleUtils.buildReleaseNamespacesInClusterRoleName(appId, "DEV", "default"); + + assertNull(roleRepository.findTopByRoleName(modifyRoleName)); + assertNull(roleRepository.findTopByRoleName(releaseRoleName)); + } + + @Test + @Sql(scripts = "/sql/permission/RolePermissionServiceTest.deleteRolePermissionsByAppIdWithClusterRoles.sql", + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) + @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) + public void testDeleteRolePermissionsByCluster() { + String appId = "clusterApp"; + String operator = "test"; + + rolePermissionService.deleteRolePermissionsByAppIdAndCluster(appId, "DEV", "default", operator); + + String modifyRoleName = RoleUtils.buildModifyNamespacesInClusterRoleName(appId, "DEV", "default"); + String releaseRoleName = RoleUtils.buildReleaseNamespacesInClusterRoleName(appId, "DEV", "default"); + + assertNull(roleRepository.findTopByRoleName(modifyRoleName)); + assertNull(roleRepository.findTopByRoleName(releaseRoleName)); + } + private Role assembleRole(String roleName) { Role role = new Role(); role.setRoleName(roleName); diff --git a/apollo-portal/src/test/resources/sql/permission/RolePermissionServiceTest.deleteRolePermissionsByAppIdWithClusterRoles.sql b/apollo-portal/src/test/resources/sql/permission/RolePermissionServiceTest.deleteRolePermissionsByAppIdWithClusterRoles.sql new file mode 100644 index 00000000000..1414a752c99 --- /dev/null +++ b/apollo-portal/src/test/resources/sql/permission/RolePermissionServiceTest.deleteRolePermissionsByAppIdWithClusterRoles.sql @@ -0,0 +1,11 @@ +INSERT INTO "Permission" (`Id`, `PermissionType`, `TargetId`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`) VALUES + (1500, 'ModifyNamespacesInCluster', 'clusterApp+DEV+default', 'someOperator', 'someOperator'), + (1501, 'ReleaseNamespacesInCluster', 'clusterApp+DEV+default', 'someOperator', 'someOperator'); + +INSERT INTO "Role" (`Id`, `RoleName`, `DataChange_CreatedBy`, `DataChange_LastModifiedBy`) VALUES + (1500, 'ModifyNamespacesInCluster+clusterApp+DEV+default', 'someOperator', 'someOperator'), + (1501, 'ReleaseNamespacesInCluster+clusterApp+DEV+default', 'someOperator', 'someOperator'); + +INSERT INTO "RolePermission" (`Id`, `RoleId`, `PermissionId`) VALUES + (1500, 1500, 1500), + (1501, 1501, 1501);