Commit 49b4eedfc0ca13bfb0c4fdfab952b0574c754153
1 parent
97db4586
增加 UserRole 的缓存,完善权限相关的单元测试
Showing
8 changed files
with
451 additions
and
64 deletions
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
| ... | ... | @@ -93,7 +93,7 @@ public class AuthController { |
| 93 | 93 | return null; |
| 94 | 94 | } |
| 95 | 95 | // 获得角色列表 |
| 96 | - Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 96 | + Set<Long> roleIds = permissionService.getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 97 | 97 | List<RoleDO> roleList = roleService.getRolesFromCache(roleIds); |
| 98 | 98 | // 获得菜单列表 |
| 99 | 99 | List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds, |
| ... | ... | @@ -107,7 +107,7 @@ public class AuthController { |
| 107 | 107 | @ApiOperation("获得登录用户的菜单列表") |
| 108 | 108 | public CommonResult<List<AuthMenuRespVO>> getMenus() { |
| 109 | 109 | // 获得角色列表 |
| 110 | - Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 110 | + Set<Long> roleIds = permissionService.getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 111 | 111 | // 获得用户拥有的菜单列表 |
| 112 | 112 | List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds, |
| 113 | 113 | SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java
| ... | ... | @@ -4,8 +4,10 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | 4 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; |
| 5 | 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 6 | 6 | import org.apache.ibatis.annotations.Mapper; |
| 7 | +import org.apache.ibatis.annotations.Select; | |
| 7 | 8 | |
| 8 | 9 | import java.util.Collection; |
| 10 | +import java.util.Date; | |
| 9 | 11 | import java.util.List; |
| 10 | 12 | |
| 11 | 13 | @Mapper |
| ... | ... | @@ -36,4 +38,8 @@ public interface UserRoleMapper extends BaseMapperX<UserRoleDO> { |
| 36 | 38 | default List<UserRoleDO> selectListByRoleIds(Collection<Long> roleIds) { |
| 37 | 39 | return selectList(UserRoleDO::getRoleId, roleIds); |
| 38 | 40 | } |
| 41 | + | |
| 42 | + @Select("SELECT COUNT(*) FROM system_user_role WHERE update_time > #{maxUpdateTime}") | |
| 43 | + Long selectCountByUpdateTimeGt(Date maxUpdateTime); | |
| 44 | + | |
| 39 | 45 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/consumer/permission/UserRoleRefreshConsumer.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.mq.consumer.permission; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; | |
| 4 | +import cn.iocoder.yudao.module.system.mq.message.permission.UserRoleRefreshMessage; | |
| 5 | +import cn.iocoder.yudao.module.system.service.permission.PermissionService; | |
| 6 | +import lombok.extern.slf4j.Slf4j; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 针对 {@link UserRoleRefreshMessage} 的消费者 | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Component | |
| 17 | +@Slf4j | |
| 18 | +public class UserRoleRefreshConsumer extends AbstractChannelMessageListener<UserRoleRefreshMessage> { | |
| 19 | + | |
| 20 | + @Resource | |
| 21 | + private PermissionService permissionService; | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public void onMessage(UserRoleRefreshMessage message) { | |
| 25 | + log.info("[onMessage][收到 User 与 Role 的关联刷新消息]"); | |
| 26 | + permissionService.initLocalCache(); | |
| 27 | + } | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/message/permission/UserRoleRefreshMessage.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.mq.message.permission; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage; | |
| 4 | +import lombok.Data; | |
| 5 | +import lombok.EqualsAndHashCode; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * 用户与角色的数据刷新 Message | |
| 9 | + * | |
| 10 | + * @author 芋道源码 | |
| 11 | + */ | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +public class UserRoleRefreshMessage extends AbstractChannelMessage { | |
| 15 | + | |
| 16 | + @Override | |
| 17 | + public String getChannel() { | |
| 18 | + return "system.user-role.refresh"; | |
| 19 | + } | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/mq/producer/permission/PermissionProducer.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.mq.producer.permission; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.system.mq.message.permission.RoleMenuRefreshMessage; |
| 4 | 4 | import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; |
| 5 | +import cn.iocoder.yudao.module.system.mq.message.permission.UserRoleRefreshMessage; | |
| 5 | 6 | import org.springframework.stereotype.Component; |
| 6 | 7 | |
| 7 | 8 | import javax.annotation.Resource; |
| ... | ... | @@ -23,4 +24,12 @@ public class PermissionProducer { |
| 23 | 24 | redisMQTemplate.send(message); |
| 24 | 25 | } |
| 25 | 26 | |
| 27 | + /** | |
| 28 | + * 发送 {@link UserRoleRefreshMessage} 消息 | |
| 29 | + */ | |
| 30 | + public void sendUserRoleRefreshMessage() { | |
| 31 | + UserRoleRefreshMessage message = new UserRoleRefreshMessage(); | |
| 32 | + redisMQTemplate.send(message); | |
| 33 | + } | |
| 34 | + | |
| 26 | 35 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java
| ... | ... | @@ -37,13 +37,13 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D |
| 37 | 37 | Collection<Integer> menusStatuses); |
| 38 | 38 | |
| 39 | 39 | /** |
| 40 | - * 获得用户拥有的角色编号集合 | |
| 40 | + * 获得用户拥有的角色编号集合,从缓存中获取 | |
| 41 | 41 | * |
| 42 | 42 | * @param userId 用户编号 |
| 43 | 43 | * @param roleStatuses 角色状态集合. 允许为空,为空时不过滤 |
| 44 | 44 | * @return 角色编号集合 |
| 45 | 45 | */ |
| 46 | - Set<Long> getUserRoleIds(Long userId, @Nullable Collection<Integer> roleStatuses); | |
| 46 | + Set<Long> getUserRoleIdsFromCache(Long userId, @Nullable Collection<Integer> roleStatuses); | |
| 47 | 47 | |
| 48 | 48 | /** |
| 49 | 49 | * 获得角色拥有的菜单编号集合 |
| ... | ... | @@ -54,6 +54,14 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D |
| 54 | 54 | Set<Long> getRoleMenuIds(Long roleId); |
| 55 | 55 | |
| 56 | 56 | /** |
| 57 | + * 获得拥有多个角色的用户编号集合 | |
| 58 | + * | |
| 59 | + * @param roleIds 角色编号集合 | |
| 60 | + * @return 用户编号集合 | |
| 61 | + */ | |
| 62 | + Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds); | |
| 63 | + | |
| 64 | + /** | |
| 57 | 65 | * 设置角色菜单 |
| 58 | 66 | * |
| 59 | 67 | * @param roleId 角色编号 |
| ... | ... | @@ -70,14 +78,6 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D |
| 70 | 78 | Set<Long> getUserRoleIdListByUserId(Long userId); |
| 71 | 79 | |
| 72 | 80 | /** |
| 73 | - * 获得拥有某个角色的用户编号集合 | |
| 74 | - * | |
| 75 | - * @param roleId 角色编号 | |
| 76 | - * @return 用户编号集合 | |
| 77 | - */ | |
| 78 | - Set<Long> getUserRoleIdListByRoleId(Long roleId); | |
| 79 | - | |
| 80 | - /** | |
| 81 | 81 | * 设置用户角色 |
| 82 | 82 | * |
| 83 | 83 | * @param userId 角色编号 |
| ... | ... | @@ -115,12 +115,4 @@ public interface PermissionService extends SecurityPermissionFrameworkService, D |
| 115 | 115 | */ |
| 116 | 116 | void processUserDeleted(Long userId); |
| 117 | 117 | |
| 118 | - /** | |
| 119 | - * 获得拥有多个角色的用户编号集合 | |
| 120 | - * | |
| 121 | - * @param roleIds 角色编号集合 | |
| 122 | - * @return 用户编号集合 | |
| 123 | - */ | |
| 124 | - Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds); | |
| 125 | - | |
| 126 | 118 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
| ... | ... | @@ -23,10 +23,13 @@ import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; |
| 23 | 23 | import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer; |
| 24 | 24 | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| 25 | 25 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| 26 | +import com.google.common.annotations.VisibleForTesting; | |
| 26 | 27 | import com.google.common.base.Suppliers; |
| 27 | 28 | import com.google.common.collect.ImmutableMultimap; |
| 28 | 29 | import com.google.common.collect.Multimap; |
| 29 | 30 | import com.google.common.collect.Sets; |
| 31 | +import lombok.Getter; | |
| 32 | +import lombok.Setter; | |
| 30 | 33 | import lombok.extern.slf4j.Slf4j; |
| 31 | 34 | import org.springframework.context.annotation.Lazy; |
| 32 | 35 | import org.springframework.scheduling.annotation.Scheduled; |
| ... | ... | @@ -40,6 +43,8 @@ import javax.annotation.Resource; |
| 40 | 43 | import java.util.*; |
| 41 | 44 | import java.util.function.Supplier; |
| 42 | 45 | |
| 46 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 47 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue; | |
| 43 | 48 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 44 | 49 | import static java.util.Collections.singleton; |
| 45 | 50 | |
| ... | ... | @@ -65,6 +70,8 @@ public class PermissionServiceImpl implements PermissionService { |
| 65 | 70 | * |
| 66 | 71 | * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 |
| 67 | 72 | */ |
| 73 | + @Getter | |
| 74 | + @Setter // 单元测试 | |
| 68 | 75 | private volatile Multimap<Long, Long> roleMenuCache; |
| 69 | 76 | /** |
| 70 | 77 | * 菜单编号与角色编号的缓存映射 |
| ... | ... | @@ -73,11 +80,29 @@ public class PermissionServiceImpl implements PermissionService { |
| 73 | 80 | * |
| 74 | 81 | * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 |
| 75 | 82 | */ |
| 83 | + @Getter | |
| 76 | 84 | private volatile Multimap<Long, Long> menuRoleCache; |
| 77 | 85 | /** |
| 78 | - * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新 | |
| 86 | + * 缓存 RoleMenu 的最大更新时间,用于后续的增量轮询,判断是否有更新 | |
| 79 | 87 | */ |
| 80 | - private volatile Date maxUpdateTime; | |
| 88 | + @Getter | |
| 89 | + private volatile Date roleMenuMaxUpdateTime; | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * 用户编号与角色编号的缓存映射 | |
| 93 | + * key:用户编号 | |
| 94 | + * value:角色编号的数组 | |
| 95 | + * | |
| 96 | + * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 | |
| 97 | + */ | |
| 98 | + @Getter | |
| 99 | + @Setter // 单元测试需要 | |
| 100 | + private volatile Map<Long, Set<Long>> userRoleCache; | |
| 101 | + /** | |
| 102 | + * 缓存 UserRole 的最大更新时间,用于后续的增量轮询,判断是否有更新 | |
| 103 | + */ | |
| 104 | + @Getter | |
| 105 | + private volatile Date userRoleMaxUpdateTime; | |
| 81 | 106 | |
| 82 | 107 | @Resource |
| 83 | 108 | private RoleMenuMapper roleMenuMapper; |
| ... | ... | @@ -104,15 +129,21 @@ public class PermissionServiceImpl implements PermissionService { |
| 104 | 129 | @Lazy // 注入自己,所以延迟加载 |
| 105 | 130 | private PermissionService self; |
| 106 | 131 | |
| 107 | - /** | |
| 108 | - * 初始化 {@link #roleMenuCache} 和 {@link #menuRoleCache} 缓存 | |
| 109 | - */ | |
| 110 | 132 | @Override |
| 111 | 133 | @PostConstruct |
| 112 | 134 | @TenantIgnore // 初始化缓存,无需租户过滤 |
| 113 | 135 | public void initLocalCache() { |
| 136 | + initUserRoleLocalCache(); | |
| 137 | + initRoleMenuLocalCache(); | |
| 138 | + } | |
| 139 | + | |
| 140 | + /** | |
| 141 | + * 初始化 {@link #roleMenuCache} 和 {@link #menuRoleCache} 缓存 | |
| 142 | + */ | |
| 143 | + @VisibleForTesting | |
| 144 | + void initRoleMenuLocalCache() { | |
| 114 | 145 | // 获取角色与菜单的关联列表,如果有更新 |
| 115 | - List<RoleMenuDO> roleMenuList = loadRoleMenuIfUpdate(maxUpdateTime); | |
| 146 | + List<RoleMenuDO> roleMenuList = loadRoleMenuIfUpdate(roleMenuMaxUpdateTime); | |
| 116 | 147 | if (CollUtil.isEmpty(roleMenuList)) { |
| 117 | 148 | return; |
| 118 | 149 | } |
| ... | ... | @@ -126,8 +157,27 @@ public class PermissionServiceImpl implements PermissionService { |
| 126 | 157 | }); |
| 127 | 158 | roleMenuCache = roleMenuCacheBuilder.build(); |
| 128 | 159 | menuRoleCache = menuRoleCacheBuilder.build(); |
| 129 | - maxUpdateTime = CollectionUtils.getMaxValue(roleMenuList, RoleMenuDO::getUpdateTime); | |
| 130 | - log.info("[initLocalCache][初始化角色与菜单的关联数量为 {}]", roleMenuList.size()); | |
| 160 | + roleMenuMaxUpdateTime = getMaxValue(roleMenuList, RoleMenuDO::getUpdateTime); | |
| 161 | + log.info("[initRoleMenuLocalCache][初始化角色与菜单的关联数量为 {}]", roleMenuList.size()); | |
| 162 | + } | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * 初始化 {@link #userRoleCache} 缓存 | |
| 166 | + */ | |
| 167 | + @VisibleForTesting | |
| 168 | + void initUserRoleLocalCache() { | |
| 169 | + // 获取用户与角色的关联列表,如果有更新 | |
| 170 | + List<UserRoleDO> userRoleList = loadUserRoleIfUpdate(userRoleMaxUpdateTime); | |
| 171 | + if (CollUtil.isEmpty(userRoleList)) { | |
| 172 | + return; | |
| 173 | + } | |
| 174 | + | |
| 175 | + // 初始化 userRoleCache 缓存 | |
| 176 | + ImmutableMultimap.Builder<Long, Long> userRoleCacheBuilder = ImmutableMultimap.builder(); | |
| 177 | + userRoleList.forEach(userRoleDO -> userRoleCacheBuilder.put(userRoleDO.getUserId(), userRoleDO.getRoleId())); | |
| 178 | + userRoleCache = CollectionUtils.convertMultiMap2(userRoleList, UserRoleDO::getUserId, UserRoleDO::getRoleId); | |
| 179 | + userRoleMaxUpdateTime = getMaxValue(userRoleList, UserRoleDO::getUpdateTime); | |
| 180 | + log.info("[initUserRoleLocalCache][初始化用户与角色的关联数量为 {}]", userRoleList.size()); | |
| 131 | 181 | } |
| 132 | 182 | |
| 133 | 183 | @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) |
| ... | ... | @@ -156,6 +206,27 @@ public class PermissionServiceImpl implements PermissionService { |
| 156 | 206 | return roleMenuMapper.selectList(); |
| 157 | 207 | } |
| 158 | 208 | |
| 209 | + /** | |
| 210 | + * 如果用户与角色的关联发生变化,从数据库中获取最新的全量用户与角色的关联。 | |
| 211 | + * 如果未发生变化,则返回空 | |
| 212 | + * | |
| 213 | + * @param maxUpdateTime 当前角色与菜单的关联的最大更新时间 | |
| 214 | + * @return 角色与菜单的关联列表 | |
| 215 | + */ | |
| 216 | + protected List<UserRoleDO> loadUserRoleIfUpdate(Date maxUpdateTime) { | |
| 217 | + // 第一步,判断是否要更新。 | |
| 218 | + if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 | |
| 219 | + log.info("[loadUserRoleIfUpdate][首次加载全量用户与角色的关联]"); | |
| 220 | + } else { // 判断数据库中是否有更新的用户与角色的关联 | |
| 221 | + if (userRoleMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) { | |
| 222 | + return null; | |
| 223 | + } | |
| 224 | + log.info("[loadUserRoleIfUpdate][增量加载全量用户与角色的关联]"); | |
| 225 | + } | |
| 226 | + // 第二步,如果有更新,则从数据库加载所有用户与角色的关联 | |
| 227 | + return userRoleMapper.selectList(); | |
| 228 | + } | |
| 229 | + | |
| 159 | 230 | @Override |
| 160 | 231 | public List<MenuDO> getRoleMenuListFromCache(Collection<Long> roleIds, Collection<Integer> menuTypes, |
| 161 | 232 | Collection<Integer> menusStatuses) { |
| ... | ... | @@ -176,35 +247,33 @@ public class PermissionServiceImpl implements PermissionService { |
| 176 | 247 | } |
| 177 | 248 | |
| 178 | 249 | @Override |
| 179 | - public Set<Long> getUserRoleIds(Long userId, Collection<Integer> roleStatuses) { | |
| 180 | - List<UserRoleDO> userRoleList = userRoleMapper.selectListByUserId(userId); | |
| 250 | + public Set<Long> getUserRoleIdsFromCache(Long userId, Collection<Integer> roleStatuses) { | |
| 251 | + Set<Long> roleIds = new HashSet<>(userRoleCache.get(userId)); | |
| 181 | 252 | // 过滤角色状态 |
| 182 | 253 | if (CollectionUtil.isNotEmpty(roleStatuses)) { |
| 183 | - userRoleList.removeIf(userRoleDO -> { | |
| 184 | - RoleDO role = roleService.getRoleFromCache(userRoleDO.getRoleId()); | |
| 254 | + roleIds.removeIf(roleId -> { | |
| 255 | + RoleDO role = roleService.getRoleFromCache(roleId); | |
| 185 | 256 | return role == null || !roleStatuses.contains(role.getStatus()); |
| 186 | 257 | }); |
| 187 | 258 | } |
| 188 | - return CollectionUtils.convertSet(userRoleList, UserRoleDO::getRoleId); | |
| 259 | + return roleIds; | |
| 189 | 260 | } |
| 190 | 261 | |
| 191 | 262 | @Override |
| 192 | 263 | public Set<Long> getRoleMenuIds(Long roleId) { |
| 193 | 264 | // 如果是管理员的情况下,获取全部菜单编号 |
| 194 | - RoleDO role = roleService.getRole(roleId); | |
| 195 | - if (roleService.hasAnySuperAdmin(Collections.singletonList(role))) { | |
| 196 | - return CollectionUtils.convertSet(menuService.getMenus(), MenuDO::getId); | |
| 265 | + if (roleService.hasAnySuperAdmin(Collections.singleton(roleId))) { | |
| 266 | + return convertSet(menuService.getMenus(), MenuDO::getId); | |
| 197 | 267 | } |
| 198 | 268 | // 如果是非管理员的情况下,获得拥有的菜单编号 |
| 199 | - return CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId), | |
| 200 | - RoleMenuDO::getMenuId); | |
| 269 | + return convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); | |
| 201 | 270 | } |
| 202 | 271 | |
| 203 | 272 | @Override |
| 204 | 273 | @Transactional(rollbackFor = Exception.class) |
| 205 | 274 | public void assignRoleMenu(Long roleId, Set<Long> menuIds) { |
| 206 | 275 | // 获得角色拥有菜单编号 |
| 207 | - Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId), | |
| 276 | + Set<Long> dbMenuIds = convertSet(roleMenuMapper.selectListByRoleId(roleId), | |
| 208 | 277 | RoleMenuDO::getMenuId); |
| 209 | 278 | // 计算新增和删除的菜单编号 |
| 210 | 279 | Collection<Long> createMenuIds = CollUtil.subtract(menuIds, dbMenuIds); |
| ... | ... | @@ -234,20 +303,21 @@ public class PermissionServiceImpl implements PermissionService { |
| 234 | 303 | |
| 235 | 304 | @Override |
| 236 | 305 | public Set<Long> getUserRoleIdListByUserId(Long userId) { |
| 237 | - return CollectionUtils.convertSet(userRoleMapper.selectListByUserId(userId), | |
| 306 | + return convertSet(userRoleMapper.selectListByUserId(userId), | |
| 238 | 307 | UserRoleDO::getRoleId); |
| 239 | 308 | } |
| 240 | 309 | |
| 241 | 310 | @Override |
| 242 | - public Set<Long> getUserRoleIdListByRoleId(Long roleId) { | |
| 243 | - return CollectionUtils.convertSet(userRoleMapper.selectListByRoleId(roleId), | |
| 244 | - UserRoleDO::getRoleId); | |
| 311 | + public Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds) { | |
| 312 | + return convertSet(userRoleMapper.selectListByRoleIds(roleIds), | |
| 313 | + UserRoleDO::getUserId); | |
| 245 | 314 | } |
| 246 | 315 | |
| 247 | 316 | @Override |
| 317 | + @Transactional(rollbackFor = Exception.class) | |
| 248 | 318 | public void assignUserRole(Long userId, Set<Long> roleIds) { |
| 249 | 319 | // 获得角色拥有角色编号 |
| 250 | - Set<Long> dbRoleIds = CollectionUtils.convertSet(userRoleMapper.selectListByUserId(userId), | |
| 320 | + Set<Long> dbRoleIds = convertSet(userRoleMapper.selectListByUserId(userId), | |
| 251 | 321 | UserRoleDO::getRoleId); |
| 252 | 322 | // 计算新增和删除的角色编号 |
| 253 | 323 | Collection<Long> createRoleIds = CollUtil.subtract(roleIds, dbRoleIds); |
| ... | ... | @@ -264,6 +334,15 @@ public class PermissionServiceImpl implements PermissionService { |
| 264 | 334 | if (!CollectionUtil.isEmpty(deleteMenuIds)) { |
| 265 | 335 | userRoleMapper.deleteListByUserIdAndRoleIdIds(userId, deleteMenuIds); |
| 266 | 336 | } |
| 337 | + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了 | |
| 338 | + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { | |
| 339 | + | |
| 340 | + @Override | |
| 341 | + public void afterCommit() { | |
| 342 | + permissionProducer.sendUserRoleRefreshMessage(); | |
| 343 | + } | |
| 344 | + | |
| 345 | + }); | |
| 267 | 346 | } |
| 268 | 347 | |
| 269 | 348 | @Override |
| ... | ... | @@ -284,6 +363,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 284 | 363 | @Override |
| 285 | 364 | public void afterCommit() { |
| 286 | 365 | permissionProducer.sendRoleMenuRefreshMessage(); |
| 366 | + permissionProducer.sendUserRoleRefreshMessage(); | |
| 287 | 367 | } |
| 288 | 368 | |
| 289 | 369 | }); |
| ... | ... | @@ -305,8 +385,17 @@ public class PermissionServiceImpl implements PermissionService { |
| 305 | 385 | } |
| 306 | 386 | |
| 307 | 387 | @Override |
| 388 | + @Transactional(rollbackFor = Exception.class) | |
| 308 | 389 | public void processUserDeleted(Long userId) { |
| 309 | 390 | userRoleMapper.deleteListByUserId(userId); |
| 391 | + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { | |
| 392 | + | |
| 393 | + @Override | |
| 394 | + public void afterCommit() { | |
| 395 | + permissionProducer.sendUserRoleRefreshMessage(); | |
| 396 | + } | |
| 397 | + | |
| 398 | + }); | |
| 310 | 399 | } |
| 311 | 400 | |
| 312 | 401 | @Override |
| ... | ... | @@ -322,7 +411,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 322 | 411 | } |
| 323 | 412 | |
| 324 | 413 | // 获得当前登录的角色。如果为空,说明没有权限 |
| 325 | - Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 414 | + Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 326 | 415 | if (CollUtil.isEmpty(roleIds)) { |
| 327 | 416 | return false; |
| 328 | 417 | } |
| ... | ... | @@ -357,7 +446,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 357 | 446 | } |
| 358 | 447 | |
| 359 | 448 | // 获得当前登录的角色。如果为空,说明没有权限 |
| 360 | - Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 449 | + Set<Long> roleIds = getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 361 | 450 | if (CollUtil.isEmpty(roleIds)) { |
| 362 | 451 | return false; |
| 363 | 452 | } |
| ... | ... | @@ -365,7 +454,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 365 | 454 | if (roleService.hasAnySuperAdmin(roleIds)) { |
| 366 | 455 | return true; |
| 367 | 456 | } |
| 368 | - Set<String> userRoles = CollectionUtils.convertSet(roleService.getRolesFromCache(roleIds), | |
| 457 | + Set<String> userRoles = convertSet(roleService.getRolesFromCache(roleIds), | |
| 369 | 458 | RoleDO::getCode); |
| 370 | 459 | return CollUtil.containsAny(userRoles, Sets.newHashSet(roles)); |
| 371 | 460 | } |
| ... | ... | @@ -375,7 +464,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 375 | 464 | public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) { |
| 376 | 465 | DeptDataPermissionRespDTO result = new DeptDataPermissionRespDTO(); |
| 377 | 466 | // 获得用户的角色 |
| 378 | - Set<Long> roleIds = getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 467 | + Set<Long> roleIds = getUserRoleIdsFromCache(userId, singleton(CommonStatusEnum.ENABLE.getStatus())); | |
| 379 | 468 | if (CollUtil.isEmpty(roleIds)) { |
| 380 | 469 | return result; |
| 381 | 470 | } |
| ... | ... | @@ -425,10 +514,4 @@ public class PermissionServiceImpl implements PermissionService { |
| 425 | 514 | return result; |
| 426 | 515 | } |
| 427 | 516 | |
| 428 | - @Override | |
| 429 | - public Set<Long> getUserRoleIdListByRoleIds(Collection<Long> roleIds) { | |
| 430 | - return CollectionUtils.convertSet(userRoleMapper.selectListByRoleIds(roleIds), | |
| 431 | - UserRoleDO::getUserId); | |
| 432 | - } | |
| 433 | - | |
| 434 | 517 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
| 1 | 1 | package cn.iocoder.yudao.module.system.service.permission; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 4 | 5 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 6 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 5 | 7 | import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO; |
| 6 | 8 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 7 | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; |
| 10 | +import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | |
| 8 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; |
| 9 | 12 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO; |
| 10 | 13 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; |
| ... | ... | @@ -17,20 +20,24 @@ import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; |
| 17 | 20 | import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer; |
| 18 | 21 | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| 19 | 22 | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| 23 | +import com.google.common.collect.ImmutableMultimap; | |
| 24 | +import com.google.common.collect.Multimap; | |
| 20 | 25 | import org.junit.jupiter.api.Test; |
| 21 | 26 | import org.springframework.boot.test.mock.mockito.MockBean; |
| 22 | 27 | import org.springframework.context.annotation.Import; |
| 23 | 28 | |
| 24 | 29 | import javax.annotation.Resource; |
| 25 | -import java.util.List; | |
| 30 | +import java.util.*; | |
| 26 | 31 | |
| 32 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 27 | 33 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 28 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 29 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 34 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | |
| 35 | +import static java.util.Arrays.asList; | |
| 30 | 36 | import static java.util.Collections.singleton; |
| 31 | 37 | import static java.util.Collections.singletonList; |
| 32 | 38 | import static org.junit.jupiter.api.Assertions.*; |
| 33 | 39 | import static org.mockito.ArgumentMatchers.eq; |
| 40 | +import static org.mockito.ArgumentMatchers.same; | |
| 34 | 41 | import static org.mockito.Mockito.verify; |
| 35 | 42 | import static org.mockito.Mockito.when; |
| 36 | 43 | |
| ... | ... | @@ -63,6 +70,226 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 63 | 70 | private PermissionProducer permissionProducer; |
| 64 | 71 | |
| 65 | 72 | @Test |
| 73 | + public void testInitRoleMenuLocalCache() { | |
| 74 | + // mock 数据 | |
| 75 | + RoleMenuDO roleMenuDO01 = randomPojo(RoleMenuDO.class, o -> o.setRoleId(1L).setMenuId(10L)); | |
| 76 | + roleMenuMapper.insert(roleMenuDO01); | |
| 77 | + RoleMenuDO roleMenuDO02 = randomPojo(RoleMenuDO.class, o -> o.setRoleId(1L).setMenuId(20L)); | |
| 78 | + roleMenuMapper.insert(roleMenuDO02); | |
| 79 | + | |
| 80 | + // 调用 | |
| 81 | + permissionService.initRoleMenuLocalCache(); | |
| 82 | + // 断言 roleMenuCache 缓存 | |
| 83 | + assertEquals(1, permissionService.getRoleMenuCache().keySet().size()); | |
| 84 | + assertEquals(asList(10L, 20L), permissionService.getRoleMenuCache().get(1L)); | |
| 85 | + // 断言 menuRoleCache 缓存 | |
| 86 | + assertEquals(2, permissionService.getMenuRoleCache().size()); | |
| 87 | + assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(10L)); | |
| 88 | + assertEquals(singletonList(1L), permissionService.getMenuRoleCache().get(20L)); | |
| 89 | + // 断言 maxUpdateTime 缓存 | |
| 90 | + Date maxUpdateTime = permissionService.getRoleMenuMaxUpdateTime(); | |
| 91 | + assertEquals(ObjectUtils.max(roleMenuDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime); | |
| 92 | + } | |
| 93 | + | |
| 94 | + @Test | |
| 95 | + public void testInitUserRoleLocalCache() { | |
| 96 | + // mock 数据 | |
| 97 | + UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L)); | |
| 98 | + userRoleMapper.insert(userRoleDO01); | |
| 99 | + UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(20L)); | |
| 100 | + userRoleMapper.insert(roleMenuDO02); | |
| 101 | + | |
| 102 | + // 调用 | |
| 103 | + permissionService.initUserRoleLocalCache(); | |
| 104 | + // 断言 roleMenuCache 缓存 | |
| 105 | + assertEquals(1, permissionService.getUserRoleCache().size()); | |
| 106 | + assertEquals(asSet(10L, 20L), permissionService.getUserRoleCache().get(1L)); | |
| 107 | + // 断言 maxUpdateTime 缓存 | |
| 108 | + Date maxUpdateTime = permissionService.getUserRoleMaxUpdateTime(); | |
| 109 | + assertEquals(ObjectUtils.max(userRoleDO01.getUpdateTime(), roleMenuDO02.getUpdateTime()), maxUpdateTime); | |
| 110 | + } | |
| 111 | + | |
| 112 | + @Test | |
| 113 | + public void testGetRoleMenuListFromCache_superAdmin() { | |
| 114 | + // 准备参数 | |
| 115 | + Collection<Long> roleIds = singletonList(100L); | |
| 116 | + Collection<Integer> menuTypes = asList(2, 3); | |
| 117 | + Collection<Integer> menusStatuses = asList(0, 1); | |
| 118 | + // mock 方法 | |
| 119 | + List<RoleDO> roleList = singletonList(randomPojo(RoleDO.class, o -> o.setId(100L))); | |
| 120 | + when(roleService.getRolesFromCache(eq(roleIds))).thenReturn(roleList); | |
| 121 | + when(roleService.hasAnySuperAdmin(same(roleList))).thenReturn(true); | |
| 122 | + List<MenuDO> menuList = randomPojoList(MenuDO.class); | |
| 123 | + when(menuService.getMenuListFromCache(eq(menuTypes), eq(menusStatuses))).thenReturn(menuList); | |
| 124 | + | |
| 125 | + // 调用 | |
| 126 | + List<MenuDO> result = permissionService.getRoleMenuListFromCache(roleIds, menuTypes, menusStatuses); | |
| 127 | + // 断言 | |
| 128 | + assertSame(menuList, result); | |
| 129 | + } | |
| 130 | + | |
| 131 | + @Test | |
| 132 | + public void testGetRoleMenuListFromCache_normal() { | |
| 133 | + // 准备参数 | |
| 134 | + Collection<Long> roleIds = asSet(100L, 200L); | |
| 135 | + Collection<Integer> menuTypes = asList(2, 3); | |
| 136 | + Collection<Integer> menusStatuses = asList(0, 1); | |
| 137 | + // mock 方法 | |
| 138 | + Multimap<Long, Long> roleMenuCache = ImmutableMultimap.<Long, Long>builder().put(100L, 1000L) | |
| 139 | + .put(200L, 2000L).put(200L, 2001L).build(); | |
| 140 | + permissionService.setRoleMenuCache(roleMenuCache); | |
| 141 | + List<MenuDO> menuList = randomPojoList(MenuDO.class); | |
| 142 | + when(menuService.getMenuListFromCache(eq(asList(1000L, 2000L, 2001L)), eq(menuTypes), eq(menusStatuses))).thenReturn(menuList); | |
| 143 | + | |
| 144 | + // 调用 | |
| 145 | + List<MenuDO> result = permissionService.getRoleMenuListFromCache(roleIds, menuTypes, menusStatuses); | |
| 146 | + // 断言 | |
| 147 | + assertSame(menuList, result); | |
| 148 | + } | |
| 149 | + | |
| 150 | + @Test | |
| 151 | + public void testGetUserRoleIdsFromCache() { | |
| 152 | + // 准备参数 | |
| 153 | + Long userId = 1L; | |
| 154 | + Collection<Integer> roleStatuses = singleton(CommonStatusEnum.ENABLE.getStatus()); | |
| 155 | + // mock 方法 | |
| 156 | + Map<Long, Set<Long>> userRoleCache = MapUtil.<Long, Set<Long>>builder() | |
| 157 | + .put(1L, asSet(10L, 20L)).build(); | |
| 158 | + permissionService.setUserRoleCache(userRoleCache); | |
| 159 | + RoleDO roleDO01 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 160 | + when(roleService.getRoleFromCache(eq(10L))).thenReturn(roleDO01); | |
| 161 | + RoleDO roleDO02 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 162 | + when(roleService.getRoleFromCache(eq(20L))).thenReturn(roleDO02); | |
| 163 | + | |
| 164 | + // 调用 | |
| 165 | + Set<Long> roleIds = permissionService.getUserRoleIdsFromCache(userId, roleStatuses); | |
| 166 | + // 断言 | |
| 167 | + assertEquals(asSet(10L), roleIds); | |
| 168 | + } | |
| 169 | + | |
| 170 | + @Test | |
| 171 | + public void testGetRoleMenuIds_superAdmin() { | |
| 172 | + // 准备参数 | |
| 173 | + Long roleId = 100L; | |
| 174 | + // mock 方法 | |
| 175 | + when(roleService.hasAnySuperAdmin(eq(singleton(100L)))).thenReturn(true); | |
| 176 | + List<MenuDO> menuList = singletonList(randomPojo(MenuDO.class).setId(1L)); | |
| 177 | + when(menuService.getMenus()).thenReturn(menuList); | |
| 178 | + | |
| 179 | + // 调用 | |
| 180 | + Set<Long> menuIds = permissionService.getRoleMenuIds(roleId); | |
| 181 | + // 断言 | |
| 182 | + assertEquals(singleton(1L), menuIds); | |
| 183 | + } | |
| 184 | + | |
| 185 | + @Test | |
| 186 | + public void testGetRoleMenuIds_normal() { | |
| 187 | + // 准备参数 | |
| 188 | + Long roleId = 100L; | |
| 189 | + // mock 数据 | |
| 190 | + RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(1L); | |
| 191 | + roleMenuMapper.insert(roleMenu01); | |
| 192 | + RoleMenuDO roleMenu02 = randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(2L); | |
| 193 | + roleMenuMapper.insert(roleMenu02); | |
| 194 | + | |
| 195 | + // 调用 | |
| 196 | + Set<Long> menuIds = permissionService.getRoleMenuIds(roleId); | |
| 197 | + // 断言 | |
| 198 | + assertEquals(asSet(1L, 2L), menuIds); | |
| 199 | + } | |
| 200 | + | |
| 201 | + @Test | |
| 202 | + public void testAssignRoleMenu() { | |
| 203 | + // 准备参数 | |
| 204 | + Long roleId = 1L; | |
| 205 | + Set<Long> menuIds = asSet(200L, 300L); | |
| 206 | + // mock 数据 | |
| 207 | + RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(1L).setMenuId(100L); | |
| 208 | + roleMenuMapper.insert(roleMenu01); | |
| 209 | + RoleMenuDO roleMenu02 = randomPojo(RoleMenuDO.class).setRoleId(1L).setMenuId(200L); | |
| 210 | + roleMenuMapper.insert(roleMenu02); | |
| 211 | + | |
| 212 | + // 调用 | |
| 213 | + permissionService.assignRoleMenu(roleId, menuIds); | |
| 214 | + // 断言 | |
| 215 | + List<RoleMenuDO> roleMenuList = roleMenuMapper.selectList(); | |
| 216 | + assertEquals(2, roleMenuList.size()); | |
| 217 | + assertEquals(1L, roleMenuList.get(0).getRoleId()); | |
| 218 | + assertEquals(200L, roleMenuList.get(0).getMenuId()); | |
| 219 | + assertEquals(1L, roleMenuList.get(1).getRoleId()); | |
| 220 | + assertEquals(300L, roleMenuList.get(1).getMenuId()); | |
| 221 | + verify(permissionProducer).sendRoleMenuRefreshMessage(); | |
| 222 | + } | |
| 223 | + | |
| 224 | + @Test | |
| 225 | + public void testAssignUserRole() { | |
| 226 | + // 准备参数 | |
| 227 | + Long userId = 1L; | |
| 228 | + Set<Long> roleIds = asSet(200L, 300L); | |
| 229 | + // mock 数据 | |
| 230 | + UserRoleDO userRole01 = randomPojo(UserRoleDO.class).setUserId(1L).setRoleId(100L); | |
| 231 | + userRoleMapper.insert(userRole01); | |
| 232 | + UserRoleDO userRole02 = randomPojo(UserRoleDO.class).setUserId(1L).setRoleId(200L); | |
| 233 | + userRoleMapper.insert(userRole02); | |
| 234 | + | |
| 235 | + // 调用 | |
| 236 | + permissionService.assignUserRole(userId, roleIds); | |
| 237 | + // 断言 | |
| 238 | + List<UserRoleDO> userRoleDOList = userRoleMapper.selectList(); | |
| 239 | + assertEquals(2, userRoleDOList.size()); | |
| 240 | + assertEquals(1L, userRoleDOList.get(0).getUserId()); | |
| 241 | + assertEquals(200L, userRoleDOList.get(0).getRoleId()); | |
| 242 | + assertEquals(1L, userRoleDOList.get(1).getUserId()); | |
| 243 | + assertEquals(300L, userRoleDOList.get(1).getRoleId()); | |
| 244 | + verify(permissionProducer).sendUserRoleRefreshMessage(); | |
| 245 | + } | |
| 246 | + | |
| 247 | + @Test | |
| 248 | + public void testGetUserRoleIdListByUserId() { | |
| 249 | + // 准备参数 | |
| 250 | + Long userId = 1L; | |
| 251 | + // mock 数据 | |
| 252 | + UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L)); | |
| 253 | + userRoleMapper.insert(userRoleDO01); | |
| 254 | + UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(20L)); | |
| 255 | + userRoleMapper.insert(roleMenuDO02); | |
| 256 | + | |
| 257 | + // 调用 | |
| 258 | + Set<Long> result = permissionService.getUserRoleIdListByUserId(userId); | |
| 259 | + // 断言 | |
| 260 | + assertEquals(asSet(10L, 20L), result); | |
| 261 | + } | |
| 262 | + | |
| 263 | + @Test | |
| 264 | + public void testGetUserRoleIdListByRoleIds() { | |
| 265 | + // 准备参数 | |
| 266 | + Collection<Long> roleIds = asSet(10L, 20L); | |
| 267 | + // mock 数据 | |
| 268 | + UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L)); | |
| 269 | + userRoleMapper.insert(userRoleDO01); | |
| 270 | + UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(2L).setRoleId(20L)); | |
| 271 | + userRoleMapper.insert(roleMenuDO02); | |
| 272 | + | |
| 273 | + // 调用 | |
| 274 | + Set<Long> result = permissionService.getUserRoleIdListByRoleIds(roleIds); | |
| 275 | + // 断言 | |
| 276 | + assertEquals(asSet(1L, 2L), result); | |
| 277 | + } | |
| 278 | + | |
| 279 | + @Test | |
| 280 | + public void testAssignRoleDataScope() { | |
| 281 | + // 准备参数 | |
| 282 | + Long roleId = 1L; | |
| 283 | + Integer dataScope = 2; | |
| 284 | + Set<Long> dataScopeDeptIds = asSet(10L, 20L); | |
| 285 | + | |
| 286 | + // 调用 | |
| 287 | + permissionService.assignRoleDataScope(roleId, dataScope, dataScopeDeptIds); | |
| 288 | + // 断言 | |
| 289 | + verify(roleService).updateRoleDataScope(eq(roleId), eq(dataScope), eq(dataScopeDeptIds)); | |
| 290 | + } | |
| 291 | + | |
| 292 | + @Test | |
| 66 | 293 | public void testProcessRoleDeleted() { |
| 67 | 294 | // 准备参数 |
| 68 | 295 | Long roleId = randomLongId(); |
| ... | ... | @@ -89,6 +316,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 89 | 316 | assertPojoEquals(dbUserRoles.get(0), userRoleDO02); |
| 90 | 317 | // 断言调用 |
| 91 | 318 | verify(permissionProducer).sendRoleMenuRefreshMessage(); |
| 319 | + verify(permissionProducer).sendUserRoleRefreshMessage(); | |
| 92 | 320 | } |
| 93 | 321 | |
| 94 | 322 | @Test |
| ... | ... | @@ -127,14 +355,33 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 127 | 355 | List<UserRoleDO> dbUserRoles = userRoleMapper.selectList(); |
| 128 | 356 | assertEquals(1, dbUserRoles.size()); |
| 129 | 357 | assertPojoEquals(dbUserRoles.get(0), userRoleDO02); |
| 358 | + // 断言调用 | |
| 359 | + verify(permissionProducer).sendUserRoleRefreshMessage(); | |
| 130 | 360 | } |
| 131 | 361 | |
| 362 | +// @Test | |
| 363 | +// public void testHasAnyRoles_superAdmin() { | |
| 364 | +// // 准备参数 | |
| 365 | +// String[] roles = new String[]{"yunai", "tudou"}; | |
| 366 | +// // mock 方法 | |
| 367 | +// List<RoleDO> roleList = singletonList(randomPojo(RoleDO.class, o -> o.setId(100L))); | |
| 368 | +// when(roleService.getRolesFromCache(eq(roleIds))).thenReturn(roleList); | |
| 369 | +// when(roleService.hasAnySuperAdmin(same(roleList))).thenReturn(true); | |
| 370 | +// List<MenuDO> menuList = randomPojoList(MenuDO.class); | |
| 371 | +// when(menuService.getMenuListFromCache(eq(menuTypes), eq(menusStatuses))).thenReturn(menuList); | |
| 372 | +// | |
| 373 | +// // 调用 | |
| 374 | +// List<MenuDO> result = permissionService.getRoleMenuListFromCache(roleIds, menuTypes, menusStatuses); | |
| 375 | +// // 断言 | |
| 376 | +// assertSame(menuList, result); | |
| 377 | +// } | |
| 378 | + | |
| 132 | 379 | @Test |
| 133 | 380 | public void testGetDeptDataPermission_All() { |
| 134 | 381 | // 准备参数 |
| 135 | 382 | Long userId = 1L; |
| 136 | 383 | // mock 用户的角色编号 |
| 137 | - userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L)); | |
| 384 | + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(2L)).build()); | |
| 138 | 385 | // mock 获得用户的角色 |
| 139 | 386 | RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope()) |
| 140 | 387 | .setStatus(CommonStatusEnum.ENABLE.getStatus())); |
| ... | ... | @@ -154,7 +401,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 154 | 401 | // 准备参数 |
| 155 | 402 | Long userId = 1L; |
| 156 | 403 | // mock 用户的角色编号 |
| 157 | - userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L)); | |
| 404 | + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(2L)).build()); | |
| 158 | 405 | // mock 获得用户的角色 |
| 159 | 406 | RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope()) |
| 160 | 407 | .setStatus(CommonStatusEnum.ENABLE.getStatus())); |
| ... | ... | @@ -164,7 +411,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 164 | 411 | when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 |
| 165 | 412 | |
| 166 | 413 | // 调用 |
| 167 | - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(1L); | |
| 414 | + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId); | |
| 168 | 415 | // 断言 |
| 169 | 416 | assertFalse(result.getAll()); |
| 170 | 417 | assertFalse(result.getSelf()); |
| ... | ... | @@ -178,7 +425,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 178 | 425 | // 准备参数 |
| 179 | 426 | Long userId = 1L; |
| 180 | 427 | // mock 用户的角色编号 |
| 181 | - userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L)); | |
| 428 | + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(2L)).build()); | |
| 182 | 429 | // mock 获得用户的角色 |
| 183 | 430 | RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope()) |
| 184 | 431 | .setStatus(CommonStatusEnum.ENABLE.getStatus())); |
| ... | ... | @@ -188,7 +435,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 188 | 435 | when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 |
| 189 | 436 | |
| 190 | 437 | // 调用 |
| 191 | - DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(1L); | |
| 438 | + DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId); | |
| 192 | 439 | // 断言 |
| 193 | 440 | assertFalse(result.getAll()); |
| 194 | 441 | assertFalse(result.getSelf()); |
| ... | ... | @@ -201,7 +448,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 201 | 448 | // 准备参数 |
| 202 | 449 | Long userId = 1L; |
| 203 | 450 | // mock 用户的角色编号 |
| 204 | - userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L)); | |
| 451 | + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(2L)).build()); | |
| 205 | 452 | // mock 获得用户的角色 |
| 206 | 453 | RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope()) |
| 207 | 454 | .setStatus(CommonStatusEnum.ENABLE.getStatus())); |
| ... | ... | @@ -229,7 +476,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 229 | 476 | // 准备参数 |
| 230 | 477 | Long userId = 1L; |
| 231 | 478 | // mock 用户的角色编号 |
| 232 | - userRoleMapper.insert(new UserRoleDO().setUserId(userId).setRoleId(2L)); | |
| 479 | + permissionService.setUserRoleCache(MapUtil.<Long, Set<Long>>builder().put(1L, asSet(2L)).build()); | |
| 233 | 480 | // mock 获得用户的角色 |
| 234 | 481 | RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope()) |
| 235 | 482 | .setStatus(CommonStatusEnum.ENABLE.getStatus())); | ... | ... |