diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java index 830606206e9afe07ac696201b957388dfae8070d..f4eb7de16b969fb55244f5075ee16a8b3022b795 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/RoleInitializationService.java @@ -1,120 +1,9 @@ package com.ctrip.framework.apollo.portal.service; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - import com.ctrip.framework.apollo.common.entity.App; -import com.ctrip.framework.apollo.core.ConfigConsts; -import com.ctrip.framework.apollo.portal.constant.PermissionType; -import com.ctrip.framework.apollo.portal.constant.RoleType; -import com.ctrip.framework.apollo.portal.entity.po.Permission; -import com.ctrip.framework.apollo.portal.entity.po.Role; -import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; -import com.ctrip.framework.apollo.portal.util.RoleUtils; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Set; - -@Service -public class RoleInitializationService { - - @Autowired - private UserInfoHolder userInfoHolder; - @Autowired - private RolePermissionService rolePermissionService; - - @Transactional - public void initAppRoles(App app) { - String appId = app.getAppId(); - - String appMasterRoleName = RoleUtils.buildAppMasterRoleName(appId); - - //has created before - if (rolePermissionService.findRoleByRoleName(appMasterRoleName) != null) { - return; - } - String operator = userInfoHolder.getUser().getUserId(); - //create app permissions - createAppMasterRole(appId); - - //assign master role to user - rolePermissionService - .assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), Sets.newHashSet(app.getOwnerName()), - operator); - - initNamespaceRoles(appId, ConfigConsts.NAMESPACE_APPLICATION); - - //assign modify、release namespace role to user - rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, ConfigConsts.NAMESPACE_APPLICATION, RoleType.MODIFY_NAMESPACE), - Sets.newHashSet(operator), operator); - rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, ConfigConsts.NAMESPACE_APPLICATION, RoleType.RELEASE_NAMESPACE), - Sets.newHashSet(operator), operator); - - } - - @Transactional - public void initNamespaceRoles(String appId, String namespaceName) { - - String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName); - if (rolePermissionService.findRoleByRoleName(modifyNamespaceRoleName) == null) { - createDefaultNamespaceRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE, - RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName)); - } - - String releaseNamespaceRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName); - if (rolePermissionService.findRoleByRoleName(releaseNamespaceRoleName) == null) { - createDefaultNamespaceRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE, - RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName)); - } - } - - private void createAppMasterRole(String appId) { - Set appPermissions = - FluentIterable.from(Lists.newArrayList( - PermissionType.CREATE_CLUSTER, PermissionType.CREATE_NAMESPACE, PermissionType.ASSIGN_ROLE)) - .transform(permissionType -> createPermission(appId, permissionType)).toSet(); - Set createdAppPermissions = rolePermissionService.createPermissions(appPermissions); - Set - appPermissionIds = - FluentIterable.from(createdAppPermissions).transform(permission -> permission.getId()).toSet(); - - //create app master role - Role appMasterRole = createRole(RoleUtils.buildAppMasterRoleName(appId)); - - rolePermissionService.createRoleWithPermissions(appMasterRole, appPermissionIds); - } - - private Permission createPermission(String targetId, String permissionType) { - Permission permission = new Permission(); - permission.setPermissionType(permissionType); - permission.setTargetId(targetId); - String userId = userInfoHolder.getUser().getUserId(); - permission.setDataChangeCreatedBy(userId); - permission.setDataChangeLastModifiedBy(userId); - return permission; - } - - private Role createRole(String roleName) { - Role role = new Role(); - role.setRoleName(roleName); - String operator = userInfoHolder.getUser().getUserId(); - role.setDataChangeCreatedBy(operator); - role.setDataChangeLastModifiedBy(operator); - return role; - } - - private void createDefaultNamespaceRole(String appId, String namespaceName, String permissionType, String roleName) { - Permission permission = - createPermission(RoleUtils.buildNamespaceTargetId(appId, namespaceName), permissionType); - Permission createdPermission = rolePermissionService.createPermission(permission); +public interface RoleInitializationService { + public void initAppRoles(App app); - Role role = createRole(roleName); - rolePermissionService - .createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId())); - } + public void initNamespaceRoles(String appId, String namespaceName); } 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 0b2da4a9875073a92eeca71f6c9d276649d98712..e9ca345a1c123dc7637bd6acebbaf867e228eea6 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 @@ -1,231 +1,59 @@ package com.ctrip.framework.apollo.portal.service; -import com.google.common.base.Preconditions; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; - -import com.ctrip.framework.apollo.portal.component.config.PortalConfig; +import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.Permission; import com.ctrip.framework.apollo.portal.entity.po.Role; -import com.ctrip.framework.apollo.portal.entity.po.RolePermission; -import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; -import com.ctrip.framework.apollo.portal.entity.po.UserRole; -import com.ctrip.framework.apollo.portal.repository.PermissionRepository; -import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository; -import com.ctrip.framework.apollo.portal.repository.RoleRepository; -import com.ctrip.framework.apollo.portal.repository.UserRoleRepository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.List; import java.util.Set; /** * @author Jason Song(song_s@ctrip.com) */ -@Service -public class RolePermissionService { - - @Autowired - private RoleRepository roleRepository; - @Autowired - private RolePermissionRepository rolePermissionRepository; - @Autowired - private UserRoleRepository userRoleRepository; - @Autowired - private PermissionRepository permissionRepository; - @Autowired - private PortalConfig portalConfig; - +public interface RolePermissionService { /** * Create role with permissions, note that role name should be unique */ - @Transactional - public Role createRoleWithPermissions(Role role, Set permissionIds) { - Role current = findRoleByRoleName(role.getRoleName()); - Preconditions.checkState(current == null, "Role %s already exists!", role.getRoleName()); - - Role createdRole = roleRepository.save(role); - - if (!CollectionUtils.isEmpty(permissionIds)) { - Iterable rolePermissions = FluentIterable.from(permissionIds).transform( - permissionId -> { - RolePermission rolePermission = new RolePermission(); - rolePermission.setRoleId(createdRole.getId()); - rolePermission.setPermissionId(permissionId); - rolePermission.setDataChangeCreatedBy(createdRole.getDataChangeCreatedBy()); - rolePermission.setDataChangeLastModifiedBy(createdRole.getDataChangeLastModifiedBy()); - return rolePermission; - }); - rolePermissionRepository.save(rolePermissions); - } - - return createdRole; - } + public Role createRoleWithPermissions(Role role, Set permissionIds); /** * Assign role to users * * @return the users assigned roles */ - @Transactional public Set assignRoleToUsers(String roleName, Set userIds, - String operatorUserId) { - Role role = findRoleByRoleName(roleName); - Preconditions.checkState(role != null, "Role %s doesn't exist!", roleName); - - List existedUserRoles = - userRoleRepository.findByUserIdInAndRoleId(userIds, role.getId()); - Set existedUserIds = - FluentIterable.from(existedUserRoles).transform(userRole -> userRole.getUserId()).toSet(); - - Set toAssignUserIds = Sets.difference(userIds, existedUserIds); - - Iterable toCreate = FluentIterable.from(toAssignUserIds).transform(userId -> { - UserRole userRole = new UserRole(); - userRole.setRoleId(role.getId()); - userRole.setUserId(userId); - userRole.setDataChangeCreatedBy(operatorUserId); - userRole.setDataChangeLastModifiedBy(operatorUserId); - return userRole; - }); - - userRoleRepository.save(toCreate); - return toAssignUserIds; - } + String operatorUserId); /** * Remove role from users */ - @Transactional - public void removeRoleFromUsers(String roleName, Set userIds, String operatorUserId) { - Role role = findRoleByRoleName(roleName); - Preconditions.checkState(role != null, "Role %s doesn't exist!", roleName); - - List existedUserRoles = - userRoleRepository.findByUserIdInAndRoleId(userIds, role.getId()); - - for (UserRole userRole : existedUserRoles) { - userRole.setDeleted(true); - userRole.setDataChangeLastModifiedTime(new Date()); - userRole.setDataChangeLastModifiedBy(operatorUserId); - } - - userRoleRepository.save(existedUserRoles); - } + public void removeRoleFromUsers(String roleName, Set userIds, String operatorUserId); /** * Query users with role */ - public Set queryUsersWithRole(String roleName) { - Role role = findRoleByRoleName(roleName); - - if (role == null) { - return Collections.emptySet(); - } - - List userRoles = userRoleRepository.findByRoleId(role.getId()); - - Set users = FluentIterable.from(userRoles).transform(userRole -> { - UserInfo userInfo = new UserInfo(); - userInfo.setUserId(userRole.getUserId()); - return userInfo; - }).toSet(); - - return users; - } + public Set queryUsersWithRole(String roleName); /** * Find role by role name, note that roleName should be unique */ - public Role findRoleByRoleName(String roleName) { - return roleRepository.findTopByRoleName(roleName); - } + public Role findRoleByRoleName(String roleName); /** * Check whether user has the permission */ - public boolean userHasPermission(String userId, String permissionType, String targetId) { - Permission permission = - permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId); - if (permission == null) { - return false; - } - - if (isSuperAdmin(userId)) { - return true; - } + public boolean userHasPermission(String userId, String permissionType, String targetId); - List userRoles = userRoleRepository.findByUserId(userId); - if (CollectionUtils.isEmpty(userRoles)) { - return false; - } - - Set roleIds = - FluentIterable.from(userRoles).transform(userRole -> userRole.getRoleId()).toSet(); - List rolePermissions = rolePermissionRepository.findByRoleIdIn(roleIds); - if (CollectionUtils.isEmpty(rolePermissions)) { - return false; - } - - for (RolePermission rolePermission : rolePermissions) { - if (rolePermission.getPermissionId() == permission.getId()) { - return true; - } - } - - return false; - } - - public boolean isSuperAdmin(String userId) { - return portalConfig.superAdmins().contains(userId); - } + public boolean isSuperAdmin(String userId); /** * Create permission, note that permissionType + targetId should be unique */ - @Transactional - public Permission createPermission(Permission permission) { - String permissionType = permission.getPermissionType(); - String targetId = permission.getTargetId(); - Permission current = - permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId); - Preconditions.checkState(current == null, - "Permission with permissionType %s targetId %s already exists!", permissionType, targetId); - - return permissionRepository.save(permission); - } + public Permission createPermission(Permission permission); /** * Create permissions, note that permissionType + targetId should be unique */ - @Transactional - public Set createPermissions(Set permissions) { - Multimap targetIdPermissionTypes = HashMultimap.create(); - for (Permission permission : permissions) { - targetIdPermissionTypes.put(permission.getTargetId(), permission.getPermissionType()); - } - - for (String targetId : targetIdPermissionTypes.keySet()) { - Collection permissionTypes = targetIdPermissionTypes.get(targetId); - List current = - permissionRepository.findByPermissionTypeInAndTargetId(permissionTypes, targetId); - Preconditions.checkState(CollectionUtils.isEmpty(current), - "Permission with permissionType %s targetId %s already exists!", permissionTypes, - targetId); - } - - Iterable results = permissionRepository.save(permissions); - return FluentIterable.from(results).toSet(); - } + public Set createPermissions(Set permissions); } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/AuthConfiguration.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/AuthConfiguration.java index 510ef7a3f1cf4e70df8af024ae398be4b2549b89..146c06988d337a787fe55ca7a398bcddbf0aeb20 100644 --- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/AuthConfiguration.java +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/AuthConfiguration.java @@ -1,7 +1,5 @@ package com.ctrip.framework.apollo.portal.spi.configuration; -import com.google.common.collect.Maps; - import com.ctrip.framework.apollo.portal.component.config.PortalConfig; import com.ctrip.framework.apollo.portal.spi.LogoutHandler; import com.ctrip.framework.apollo.portal.spi.SsoHeartbeatHandler; @@ -15,7 +13,7 @@ import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultLogoutHandler; import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultSsoHeartbeatHandler; import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultUserInfoHolder; import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultUserService; - +import com.google.common.collect.Maps; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.embedded.FilterRegistrationBean; @@ -24,11 +22,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; +import javax.servlet.Filter; import java.util.EventListener; import java.util.Map; -import javax.servlet.Filter; - @Configuration public class AuthConfiguration { @@ -168,6 +165,7 @@ public class AuthConfiguration { public SsoHeartbeatHandler ctripSsoHeartbeatHandler() { return new CtripSsoHeartbeatHandler(); } + } @@ -201,6 +199,7 @@ public class AuthConfiguration { public UserService defaultUserService() { return new DefaultUserService(); } + } diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/RoleConfiguration.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/RoleConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..08c97f83968458fb0caf1b97dc8d2bf5a66e97be --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/configuration/RoleConfiguration.java @@ -0,0 +1,24 @@ +package com.ctrip.framework.apollo.portal.spi.configuration; + +import com.ctrip.framework.apollo.portal.service.RoleInitializationService; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; +import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultRoleInitializationService; +import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultRolePermissionService; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Timothy Liu(timothy.liu@cvte.com) + */ +@Configuration +public class RoleConfiguration { + @Bean + public RoleInitializationService roleInitializationService() { + return new DefaultRoleInitializationService(); + } + + @Bean + public RolePermissionService rolePermissionService() { + return new DefaultRolePermissionService(); + } +} diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java new file mode 100644 index 0000000000000000000000000000000000000000..89a8d42e28eab1f4c6a7c3311f85a71c3dbc449b --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRoleInitializationService.java @@ -0,0 +1,120 @@ +package com.ctrip.framework.apollo.portal.spi.defaultimpl; + +import com.ctrip.framework.apollo.common.entity.App; +import com.ctrip.framework.apollo.core.ConfigConsts; +import com.ctrip.framework.apollo.portal.constant.PermissionType; +import com.ctrip.framework.apollo.portal.constant.RoleType; +import com.ctrip.framework.apollo.portal.entity.po.Permission; +import com.ctrip.framework.apollo.portal.entity.po.Role; +import com.ctrip.framework.apollo.portal.service.RoleInitializationService; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; +import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; +import com.ctrip.framework.apollo.portal.util.RoleUtils; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Set; + +/** + * Created by timothy on 2017/4/26. + */ +public class DefaultRoleInitializationService implements RoleInitializationService { + @Autowired + private UserInfoHolder userInfoHolder; + @Autowired + private RolePermissionService rolePermissionService; + + @Transactional + public void initAppRoles(App app) { + String appId = app.getAppId(); + + String appMasterRoleName = RoleUtils.buildAppMasterRoleName(appId); + + //has created before + if (rolePermissionService.findRoleByRoleName(appMasterRoleName) != null) { + return; + } + String operator = userInfoHolder.getUser().getUserId(); + //create app permissions + createAppMasterRole(appId); + + //assign master role to user + rolePermissionService + .assignRoleToUsers(RoleUtils.buildAppMasterRoleName(appId), Sets.newHashSet(app.getOwnerName()), + operator); + + initNamespaceRoles(appId, ConfigConsts.NAMESPACE_APPLICATION); + + //assign modify、release namespace role to user + rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, ConfigConsts.NAMESPACE_APPLICATION, RoleType.MODIFY_NAMESPACE), + Sets.newHashSet(operator), operator); + rolePermissionService.assignRoleToUsers(RoleUtils.buildNamespaceRoleName(appId, ConfigConsts.NAMESPACE_APPLICATION, RoleType.RELEASE_NAMESPACE), + Sets.newHashSet(operator), operator); + + } + + @Transactional + public void initNamespaceRoles(String appId, String namespaceName) { + + String modifyNamespaceRoleName = RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName); + if (rolePermissionService.findRoleByRoleName(modifyNamespaceRoleName) == null) { + createDefaultNamespaceRole(appId, namespaceName, PermissionType.MODIFY_NAMESPACE, + RoleUtils.buildModifyNamespaceRoleName(appId, namespaceName)); + } + + String releaseNamespaceRoleName = RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName); + if (rolePermissionService.findRoleByRoleName(releaseNamespaceRoleName) == null) { + createDefaultNamespaceRole(appId, namespaceName, PermissionType.RELEASE_NAMESPACE, + RoleUtils.buildReleaseNamespaceRoleName(appId, namespaceName)); + } + } + + private void createAppMasterRole(String appId) { + Set appPermissions = + FluentIterable.from(Lists.newArrayList( + PermissionType.CREATE_CLUSTER, PermissionType.CREATE_NAMESPACE, PermissionType.ASSIGN_ROLE)) + .transform(permissionType -> createPermission(appId, permissionType)).toSet(); + Set createdAppPermissions = rolePermissionService.createPermissions(appPermissions); + Set + appPermissionIds = + FluentIterable.from(createdAppPermissions).transform(permission -> permission.getId()).toSet(); + + //create app master role + Role appMasterRole = createRole(RoleUtils.buildAppMasterRoleName(appId)); + + rolePermissionService.createRoleWithPermissions(appMasterRole, appPermissionIds); + } + + private Permission createPermission(String targetId, String permissionType) { + Permission permission = new Permission(); + permission.setPermissionType(permissionType); + permission.setTargetId(targetId); + String userId = userInfoHolder.getUser().getUserId(); + permission.setDataChangeCreatedBy(userId); + permission.setDataChangeLastModifiedBy(userId); + return permission; + } + + private Role createRole(String roleName) { + Role role = new Role(); + role.setRoleName(roleName); + String operator = userInfoHolder.getUser().getUserId(); + role.setDataChangeCreatedBy(operator); + role.setDataChangeLastModifiedBy(operator); + return role; + } + + private void createDefaultNamespaceRole(String appId, String namespaceName, String permissionType, String roleName) { + + Permission permission = + createPermission(RoleUtils.buildNamespaceTargetId(appId, namespaceName), permissionType); + Permission createdPermission = rolePermissionService.createPermission(permission); + + Role role = createRole(roleName); + rolePermissionService + .createRoleWithPermissions(role, Sets.newHashSet(createdPermission.getId())); + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..f4dd42a84b23b293d8d3fc9b25f370718684b2f3 --- /dev/null +++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/defaultimpl/DefaultRolePermissionService.java @@ -0,0 +1,223 @@ +package com.ctrip.framework.apollo.portal.spi.defaultimpl; + +import com.ctrip.framework.apollo.portal.component.config.PortalConfig; +import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; +import com.ctrip.framework.apollo.portal.entity.po.Permission; +import com.ctrip.framework.apollo.portal.entity.po.Role; +import com.ctrip.framework.apollo.portal.entity.po.RolePermission; +import com.ctrip.framework.apollo.portal.entity.po.UserRole; +import com.ctrip.framework.apollo.portal.repository.PermissionRepository; +import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository; +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.google.common.base.Preconditions; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; + +/** + * Created by timothy on 2017/4/26. + */ +public class DefaultRolePermissionService implements RolePermissionService { + @Autowired + private RoleRepository roleRepository; + @Autowired + private RolePermissionRepository rolePermissionRepository; + @Autowired + private UserRoleRepository userRoleRepository; + @Autowired + private PermissionRepository permissionRepository; + @Autowired + private PortalConfig portalConfig; + + + /** + * Create role with permissions, note that role name should be unique + */ + @Transactional + public Role createRoleWithPermissions(Role role, Set permissionIds) { + Role current = findRoleByRoleName(role.getRoleName()); + Preconditions.checkState(current == null, "Role %s already exists!", role.getRoleName()); + + Role createdRole = roleRepository.save(role); + + if (!CollectionUtils.isEmpty(permissionIds)) { + Iterable rolePermissions = FluentIterable.from(permissionIds).transform( + permissionId -> { + RolePermission rolePermission = new RolePermission(); + rolePermission.setRoleId(createdRole.getId()); + rolePermission.setPermissionId(permissionId); + rolePermission.setDataChangeCreatedBy(createdRole.getDataChangeCreatedBy()); + rolePermission.setDataChangeLastModifiedBy(createdRole.getDataChangeLastModifiedBy()); + return rolePermission; + }); + rolePermissionRepository.save(rolePermissions); + } + + return createdRole; + } + + /** + * Assign role to users + * + * @return the users assigned roles + */ + @Transactional + public Set assignRoleToUsers(String roleName, Set userIds, + String operatorUserId) { + Role role = findRoleByRoleName(roleName); + Preconditions.checkState(role != null, "Role %s doesn't exist!", roleName); + + List existedUserRoles = + userRoleRepository.findByUserIdInAndRoleId(userIds, role.getId()); + Set existedUserIds = + FluentIterable.from(existedUserRoles).transform(userRole -> userRole.getUserId()).toSet(); + + Set toAssignUserIds = Sets.difference(userIds, existedUserIds); + + Iterable toCreate = FluentIterable.from(toAssignUserIds).transform(userId -> { + UserRole userRole = new UserRole(); + userRole.setRoleId(role.getId()); + userRole.setUserId(userId); + userRole.setDataChangeCreatedBy(operatorUserId); + userRole.setDataChangeLastModifiedBy(operatorUserId); + return userRole; + }); + + userRoleRepository.save(toCreate); + return toAssignUserIds; + } + + /** + * Remove role from users + */ + @Transactional + public void removeRoleFromUsers(String roleName, Set userIds, String operatorUserId) { + Role role = findRoleByRoleName(roleName); + Preconditions.checkState(role != null, "Role %s doesn't exist!", roleName); + + List existedUserRoles = + userRoleRepository.findByUserIdInAndRoleId(userIds, role.getId()); + + for (UserRole userRole : existedUserRoles) { + userRole.setDeleted(true); + userRole.setDataChangeLastModifiedTime(new Date()); + userRole.setDataChangeLastModifiedBy(operatorUserId); + } + + userRoleRepository.save(existedUserRoles); + } + + /** + * Query users with role + */ + public Set queryUsersWithRole(String roleName) { + Role role = findRoleByRoleName(roleName); + + if (role == null) { + return Collections.emptySet(); + } + + List userRoles = userRoleRepository.findByRoleId(role.getId()); + + Set users = FluentIterable.from(userRoles).transform(userRole -> { + UserInfo userInfo = new UserInfo(); + userInfo.setUserId(userRole.getUserId()); + return userInfo; + }).toSet(); + + return users; + } + + /** + * Find role by role name, note that roleName should be unique + */ + public Role findRoleByRoleName(String roleName) { + return roleRepository.findTopByRoleName(roleName); + } + + /** + * Check whether user has the permission + */ + public boolean userHasPermission(String userId, String permissionType, String targetId) { + Permission permission = + permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId); + if (permission == null) { + return false; + } + + if (isSuperAdmin(userId)) { + return true; + } + + List userRoles = userRoleRepository.findByUserId(userId); + if (CollectionUtils.isEmpty(userRoles)) { + return false; + } + + Set roleIds = + FluentIterable.from(userRoles).transform(userRole -> userRole.getRoleId()).toSet(); + List rolePermissions = rolePermissionRepository.findByRoleIdIn(roleIds); + if (CollectionUtils.isEmpty(rolePermissions)) { + return false; + } + + for (RolePermission rolePermission : rolePermissions) { + if (rolePermission.getPermissionId() == permission.getId()) { + return true; + } + } + + return false; + } + + public boolean isSuperAdmin(String userId) { + return portalConfig.superAdmins().contains(userId); + } + + /** + * Create permission, note that permissionType + targetId should be unique + */ + @Transactional + public Permission createPermission(Permission permission) { + String permissionType = permission.getPermissionType(); + String targetId = permission.getTargetId(); + Permission current = + permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId); + Preconditions.checkState(current == null, + "Permission with permissionType %s targetId %s already exists!", permissionType, targetId); + + return permissionRepository.save(permission); + } + + /** + * Create permissions, note that permissionType + targetId should be unique + */ + @Transactional + public Set createPermissions(Set permissions) { + Multimap targetIdPermissionTypes = HashMultimap.create(); + for (Permission permission : permissions) { + targetIdPermissionTypes.put(permission.getTargetId(), permission.getPermissionType()); + } + + for (String targetId : targetIdPermissionTypes.keySet()) { + Collection permissionTypes = targetIdPermissionTypes.get(targetId); + List current = + permissionRepository.findByPermissionTypeInAndTargetId(permissionTypes, targetId); + Preconditions.checkState(CollectionUtils.isEmpty(current), + "Permission with permissionType %s targetId %s already exists!", permissionTypes, + targetId); + } + + Iterable results = permissionRepository.save(permissions); + return FluentIterable.from(results).toSet(); + } + +} diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java index b3a7fcc837fee6e49b7611c79535dc1e353a28a9..063230969c489419170d57baa451709a16fd7bbc 100644 --- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java +++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AllTests.java @@ -13,8 +13,8 @@ import com.ctrip.framework.apollo.portal.service.AppNamespaceServiceTest; import com.ctrip.framework.apollo.portal.service.ConfigServiceTest; import com.ctrip.framework.apollo.portal.service.FavoriteServiceTest; import com.ctrip.framework.apollo.portal.service.NamespaceServiceTest; -import com.ctrip.framework.apollo.portal.service.RoleInitializationServiceTest; -import com.ctrip.framework.apollo.portal.service.RolePermissionServiceTest; +import com.ctrip.framework.apollo.portal.spi.defaultImpl.RoleInitializationServiceTest; +import com.ctrip.framework.apollo.portal.spi.defaultImpl.RolePermissionServiceTest; import com.ctrip.framework.apollo.portal.spi.ctrip.CtripUserServiceTest; import org.junit.runner.RunWith; diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RoleInitializationServiceTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RoleInitializationServiceTest.java similarity index 94% rename from apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RoleInitializationServiceTest.java rename to apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RoleInitializationServiceTest.java index 332111fb03b7f08f1d004e731c6979a4d9d36ab7..ebabe617585be53e89c05dbe30bc63052d4fddb7 100644 --- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RoleInitializationServiceTest.java +++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RoleInitializationServiceTest.java @@ -1,16 +1,16 @@ -package com.ctrip.framework.apollo.portal.service; - -import com.google.common.collect.Sets; +package com.ctrip.framework.apollo.portal.spi.defaultImpl; import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.portal.AbstractUnitTest; import com.ctrip.framework.apollo.portal.constant.PermissionType; +import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; import com.ctrip.framework.apollo.portal.entity.po.Permission; import com.ctrip.framework.apollo.portal.entity.po.Role; -import com.ctrip.framework.apollo.portal.entity.bo.UserInfo; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; +import com.ctrip.framework.apollo.portal.spi.defaultimpl.DefaultRoleInitializationService; import com.ctrip.framework.apollo.portal.util.RoleUtils; - +import com.google.common.collect.Sets; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; @@ -18,9 +18,7 @@ import org.mockito.Mock; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anySetOf; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class RoleInitializationServiceTest extends AbstractUnitTest { @@ -35,7 +33,7 @@ public class RoleInitializationServiceTest extends AbstractUnitTest { @Mock private UserInfoHolder userInfoHolder; @InjectMocks - private RoleInitializationService roleInitializationService; + private DefaultRoleInitializationService roleInitializationService; @Test diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RolePermissionServiceTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java similarity index 99% rename from apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RolePermissionServiceTest.java rename to apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java index 39f7ef43d9d483df15f285c78dd83b931052b63a..218be89b9a711a8ca5b1829eebf4e239b4f0552c 100644 --- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/RolePermissionServiceTest.java +++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/spi/defaultImpl/RolePermissionServiceTest.java @@ -1,5 +1,6 @@ -package com.ctrip.framework.apollo.portal.service; +package com.ctrip.framework.apollo.portal.spi.defaultImpl; +import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.google.common.collect.FluentIterable; import com.google.common.collect.Sets;