缓存改造:OAuth2Client 使用 Redis 作为缓存
This commit is contained in:
parent
5572bf3fcb
commit
7ccdf86d3a
|
@ -26,7 +26,7 @@ public class TenantRedisCacheManager extends TimeoutRedisCacheManager {
|
|||
*
|
||||
* 原因:如果只补充租户编号,可读性较差
|
||||
*/
|
||||
private static final String PREFIX = "t";
|
||||
public static final String PREFIX = "t";
|
||||
|
||||
private final TenantProperties tenantProperties;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class TenantRedisKeyDefine extends RedisKeyDefine {
|
|||
|
||||
@Override
|
||||
public String formatKey(Object... args) {
|
||||
args = ArrayUtil.append(args, TenantContextHolder.getRequiredTenantId());
|
||||
args = ArrayUtil.append(args, TenantRedisCacheManager.PREFIX + TenantContextHolder.getRequiredTenantId());
|
||||
return super.formatKey(args);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
|||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.baomidou.dynamic.datasource.annotation.Master;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
@Master
|
||||
public interface MenuMapper extends BaseMapperX<MenuDO> {
|
||||
|
||||
default MenuDO selectByParentIdAndName(Long parentId, String name) {
|
||||
|
|
|
@ -14,23 +14,15 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
|
|||
*/
|
||||
public interface RedisKeyConstants {
|
||||
|
||||
RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("验证码的缓存",
|
||||
"captcha_code:%s", // 参数为 uuid
|
||||
STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
||||
|
||||
RedisKeyDefine OAUTH2_ACCESS_TOKEN = new RedisKeyDefine("访问令牌的缓存",
|
||||
"oauth2_access_token:%s", // 参数为访问令牌 token
|
||||
STRING, OAuth2AccessTokenDO.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
||||
|
||||
RedisKeyDefine SOCIAL_AUTH_STATE = new RedisKeyDefine("社交登陆的 state", // 注意,它是被 JustAuth 的 justauth.type.prefix 使用到
|
||||
"social_auth_state:%s", // 参数为 state
|
||||
STRING, String.class, Duration.ofHours(24)); // 值为 state
|
||||
|
||||
/**
|
||||
* 指定部门的所有子部门编号数组的缓存
|
||||
*
|
||||
* KEY 格式:dept_children_ids::{id}
|
||||
* 数据类型:String 子部门编号集合
|
||||
* VALUE 数据类型:String 子部门编号集合
|
||||
*/
|
||||
String DEPT_CHILDREN_ID_LIST = "dept_children_ids";
|
||||
|
||||
|
@ -38,7 +30,7 @@ public interface RedisKeyConstants {
|
|||
* 角色的缓存
|
||||
*
|
||||
* KEY 格式:role::{id}
|
||||
* 数据类型:String 角色编号
|
||||
* VALUE 数据类型:String 角色信息
|
||||
*/
|
||||
String ROLE = "role";
|
||||
|
||||
|
@ -46,7 +38,7 @@ public interface RedisKeyConstants {
|
|||
* 用户拥有的角色编号的缓存
|
||||
*
|
||||
* KEY 格式:user_role_ids::{userId}
|
||||
* 数据类型:String 角色编号集合
|
||||
* VALUE 数据类型:String 角色编号集合
|
||||
*/
|
||||
String USER_ROLE_ID_LIST = "user_role_ids";
|
||||
|
||||
|
@ -54,7 +46,7 @@ public interface RedisKeyConstants {
|
|||
* 拥有指定菜单的角色编号的缓存
|
||||
*
|
||||
* KEY 格式:user_role_ids::{menuId}
|
||||
* 数据类型:String 角色编号集合
|
||||
* VALUE 数据类型:String 角色编号集合
|
||||
*/
|
||||
String MENU_ROLE_ID_LIST = "menu_role_ids";
|
||||
|
||||
|
@ -62,8 +54,16 @@ public interface RedisKeyConstants {
|
|||
* 拥有权限对应的菜单编号数组的缓存
|
||||
*
|
||||
* KEY 格式:permission_menu_ids::{permission}
|
||||
* 数据类型:String 菜单编号数组
|
||||
* VALUE 数据类型:String 菜单编号数组
|
||||
*/
|
||||
String PERMISSION_MENU_ID_LIST = "permission_menu_ids";
|
||||
|
||||
/**
|
||||
* OAuth2 客户端的缓存
|
||||
*
|
||||
* KEY 格式:user::{id}
|
||||
* VALUE 数据类型:String 客户端信息
|
||||
*/
|
||||
String OAUTH_CLIENT = "oauth_client";
|
||||
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.dal.redis.common;
|
||||
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
|
||||
import static cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants.CAPTCHA_CODE;
|
||||
|
||||
/**
|
||||
* 验证码的 Redis DAO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Repository
|
||||
public class CaptchaRedisDAO {
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
public String get(String uuid) {
|
||||
String redisKey = formatKey(uuid);
|
||||
return stringRedisTemplate.opsForValue().get(redisKey);
|
||||
}
|
||||
|
||||
public void set(String uuid, String code, Duration timeout) {
|
||||
String redisKey = formatKey(uuid);
|
||||
stringRedisTemplate.opsForValue().set(redisKey, code, timeout);
|
||||
}
|
||||
|
||||
public void delete(String uuid) {
|
||||
String redisKey = formatKey(uuid);
|
||||
stringRedisTemplate.delete(redisKey);
|
||||
}
|
||||
|
||||
private static String formatKey(String uuid) {
|
||||
return String.format(CAPTCHA_CODE.getKeyTemplate(), uuid);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.consumer.auth;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
|
||||
import cn.iocoder.yudao.module.system.mq.message.auth.OAuth2ClientRefreshMessage;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 针对 {@link OAuth2ClientRefreshMessage} 的消费者
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class OAuth2ClientRefreshConsumer extends AbstractChannelMessageListener<OAuth2ClientRefreshMessage> {
|
||||
|
||||
@Resource
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
|
||||
@Override
|
||||
public void onMessage(OAuth2ClientRefreshMessage message) {
|
||||
log.info("[onMessage][收到 OAuth2Client 刷新消息]");
|
||||
oauth2ClientService.initLocalCache();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.message.auth;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* OAuth 2.0 客户端的数据刷新 Message
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class OAuth2ClientRefreshMessage extends AbstractChannelMessage {
|
||||
|
||||
@Override
|
||||
public String getChannel() {
|
||||
return "system.oauth2-client.refresh";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.yudao.module.system.mq.producer.auth;
|
||||
|
||||
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
||||
import cn.iocoder.yudao.module.system.mq.message.auth.OAuth2ClientRefreshMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* OAuth 2.0 客户端相关消息的 Producer
|
||||
*/
|
||||
@Component
|
||||
public class OAuth2ClientProducer {
|
||||
|
||||
@Resource
|
||||
private RedisMQTemplate redisMQTemplate;
|
||||
|
||||
/**
|
||||
* 发送 {@link OAuth2ClientRefreshMessage} 消息
|
||||
*/
|
||||
public void sendOAuth2ClientRefreshMessage() {
|
||||
OAuth2ClientRefreshMessage message = new OAuth2ClientRefreshMessage();
|
||||
redisMQTemplate.send(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -18,11 +18,6 @@ import java.util.Collection;
|
|||
*/
|
||||
public interface OAuth2ClientService {
|
||||
|
||||
/**
|
||||
* 初始化 OAuth2Client 的本地缓存
|
||||
*/
|
||||
void initLocalCache();
|
||||
|
||||
/**
|
||||
* 创建 OAuth2 客户端
|
||||
*
|
||||
|
@ -53,6 +48,14 @@ public interface OAuth2ClientService {
|
|||
*/
|
||||
OAuth2ClientDO getOAuth2Client(Long id);
|
||||
|
||||
/**
|
||||
* 获得 OAuth2 客户端,从缓存中
|
||||
*
|
||||
* @param clientId 客户端编号
|
||||
* @return OAuth2 客户端
|
||||
*/
|
||||
OAuth2ClientDO getOAuth2ClientFromCache(String clientId);
|
||||
|
||||
/**
|
||||
* 获得 OAuth2 客户端分页
|
||||
*
|
||||
|
@ -82,7 +85,7 @@ public interface OAuth2ClientService {
|
|||
* @param redirectUri 重定向地址
|
||||
* @return 客户端
|
||||
*/
|
||||
OAuth2ClientDO validOAuthClientFromCache(String clientId, String clientSecret,
|
||||
String authorizedGrantType, Collection<String> scopes, String redirectUri);
|
||||
OAuth2ClientDO validOAuthClientFromCache(String clientId, String clientSecret, String authorizedGrantType,
|
||||
Collection<String> scopes, String redirectUri);
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.oauth2;
|
|||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
|
@ -12,22 +13,18 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl
|
|||
import cn.iocoder.yudao.module.system.convert.auth.OAuth2ClientConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
|
@ -40,48 +37,21 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|||
@Slf4j
|
||||
public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
||||
|
||||
/**
|
||||
* 客户端缓存
|
||||
* key:客户端编号 {@link OAuth2ClientDO#getClientId()} ()}
|
||||
*
|
||||
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
||||
*/
|
||||
@Getter // 解决单测
|
||||
@Setter // 解决单测
|
||||
private volatile Map<String, OAuth2ClientDO> clientCache;
|
||||
|
||||
@Resource
|
||||
private OAuth2ClientMapper oauth2ClientMapper;
|
||||
|
||||
@Resource
|
||||
private OAuth2ClientProducer oauth2ClientProducer;
|
||||
|
||||
/**
|
||||
* 初始化 {@link #clientCache} 缓存
|
||||
*/
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void initLocalCache() {
|
||||
// 第一步:查询数据
|
||||
List<OAuth2ClientDO> clients = oauth2ClientMapper.selectList();
|
||||
log.info("[initLocalCache][缓存 OAuth2 客户端,数量为:{}]", clients.size());
|
||||
|
||||
// 第二步:构建缓存。
|
||||
clientCache = convertMap(clients, OAuth2ClientDO::getClientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createOAuth2Client(OAuth2ClientCreateReqVO createReqVO) {
|
||||
validateClientIdExists(null, createReqVO.getClientId());
|
||||
// 插入
|
||||
OAuth2ClientDO oauth2Client = OAuth2ClientConvert.INSTANCE.convert(createReqVO);
|
||||
oauth2ClientMapper.insert(oauth2Client);
|
||||
// 发送刷新消息
|
||||
oauth2ClientProducer.sendOAuth2ClientRefreshMessage();
|
||||
return oauth2Client.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.OAUTH_CLIENT,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为可能修改到 clientId 字段,不好清理
|
||||
public void updateOAuth2Client(OAuth2ClientUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateOAuth2ClientExists(updateReqVO.getId());
|
||||
|
@ -91,18 +61,16 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
|||
// 更新
|
||||
OAuth2ClientDO updateObj = OAuth2ClientConvert.INSTANCE.convert(updateReqVO);
|
||||
oauth2ClientMapper.updateById(updateObj);
|
||||
// 发送刷新消息
|
||||
oauth2ClientProducer.sendOAuth2ClientRefreshMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.OAUTH_CLIENT,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 id 不是直接的缓存 key,不好清理
|
||||
public void deleteOAuth2Client(Long id) {
|
||||
// 校验存在
|
||||
validateOAuth2ClientExists(id);
|
||||
// 删除
|
||||
oauth2ClientMapper.deleteById(id);
|
||||
// 发送刷新消息
|
||||
oauth2ClientProducer.sendOAuth2ClientRefreshMessage();
|
||||
}
|
||||
|
||||
private void validateOAuth2ClientExists(Long id) {
|
||||
|
@ -131,16 +99,22 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
|||
return oauth2ClientMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = RedisKeyConstants.OAUTH_CLIENT, key = "#clientId")
|
||||
public OAuth2ClientDO getOAuth2ClientFromCache(String clientId) {
|
||||
return oauth2ClientMapper.selectByClientId(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<OAuth2ClientDO> getOAuth2ClientPage(OAuth2ClientPageReqVO pageReqVO) {
|
||||
return oauth2ClientMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2ClientDO validOAuthClientFromCache(String clientId, String clientSecret,
|
||||
String authorizedGrantType, Collection<String> scopes, String redirectUri) {
|
||||
public OAuth2ClientDO validOAuthClientFromCache(String clientId, String clientSecret, String authorizedGrantType,
|
||||
Collection<String> scopes, String redirectUri) {
|
||||
// 校验客户端存在、且开启
|
||||
OAuth2ClientDO client = clientCache.get(clientId);
|
||||
OAuth2ClientDO client = getSelf().getOAuth2ClientFromCache(clientId);
|
||||
if (client == null) {
|
||||
throw exception(OAUTH2_CLIENT_NOT_EXISTS);
|
||||
}
|
||||
|
@ -167,4 +141,13 @@ public class OAuth2ClientServiceImpl implements OAuth2ClientService {
|
|||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得自身的代理对象,解决 AOP 生效问题
|
||||
*
|
||||
* @return 自己
|
||||
*/
|
||||
private OAuth2ClientServiceImpl getSelf() {
|
||||
return SpringUtil.getBean(getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
|
@ -9,14 +9,12 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl
|
|||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2ClientUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.auth.OAuth2ClientProducer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
|
@ -24,7 +22,8 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic
|
|||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link OAuth2ClientServiceImpl} 的单元测试类
|
||||
|
@ -40,26 +39,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
@Resource
|
||||
private OAuth2ClientMapper oauth2ClientMapper;
|
||||
|
||||
@MockBean
|
||||
private OAuth2ClientProducer oauth2ClientProducer;
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO clientDO1 = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(clientDO1);
|
||||
OAuth2ClientDO clientDO2 = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(clientDO2);
|
||||
|
||||
// 调用
|
||||
oauth2ClientService.initLocalCache();
|
||||
// 断言 clientCache 缓存
|
||||
Map<String, OAuth2ClientDO> clientCache = oauth2ClientService.getClientCache();
|
||||
assertEquals(2, clientCache.size());
|
||||
assertPojoEquals(clientDO1, clientCache.get(clientDO1.getClientId()));
|
||||
assertPojoEquals(clientDO2, clientCache.get(clientDO2.getClientId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOAuth2Client_success() {
|
||||
// 准备参数
|
||||
|
@ -73,7 +52,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
// 校验记录的属性是否正确
|
||||
OAuth2ClientDO oAuth2Client = oauth2ClientMapper.selectById(oauth2ClientId);
|
||||
assertPojoEquals(reqVO, oAuth2Client);
|
||||
verify(oauth2ClientProducer).sendOAuth2ClientRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -92,7 +70,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
// 校验是否更新正确
|
||||
OAuth2ClientDO oAuth2Client = oauth2ClientMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, oAuth2Client);
|
||||
verify(oauth2ClientProducer).sendOAuth2ClientRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,7 +93,6 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
oauth2ClientService.deleteOAuth2Client(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(oauth2ClientMapper.selectById(id));
|
||||
verify(oauth2ClientProducer).sendOAuth2ClientRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -166,6 +142,19 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
assertPojoEquals(clientDO, dbClientDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2ClientFromCache() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(clientDO);
|
||||
// 准备参数
|
||||
String clientId = clientDO.getClientId();
|
||||
|
||||
// 调用,并断言
|
||||
OAuth2ClientDO dbClientDO = oauth2ClientService.getOAuth2ClientFromCache(clientId);
|
||||
assertPojoEquals(clientDO, dbClientDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2ClientPage() {
|
||||
// mock 数据
|
||||
|
@ -193,36 +182,39 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
|||
|
||||
@Test
|
||||
public void testValidOAuthClientFromCache() {
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default")
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable")
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
Map<String, OAuth2ClientDO> clientCache = MapUtil.<String, OAuth2ClientDO>builder()
|
||||
.put(client.getClientId(), client)
|
||||
.put(client02.getClientId(), client02).build();
|
||||
oauth2ClientService.setClientCache(clientCache);
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(OAuth2ClientServiceImpl.class)))
|
||||
.thenReturn(oauth2ClientService);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(),
|
||||
null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable",
|
||||
null, null, null, null), OAUTH2_CLIENT_DISABLE);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test");
|
||||
// 成功调用(1:参数完整)
|
||||
OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(),
|
||||
client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0));
|
||||
assertPojoEquals(client, result);
|
||||
// 成功调用(2:只有 clientId 参数)
|
||||
result = oauth2ClientService.validOAuthClientFromCache(client.getClientId());
|
||||
assertPojoEquals(client, result);
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default")
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
oauth2ClientMapper.insert(client);
|
||||
OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable")
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
oauth2ClientMapper.insert(client02);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(),
|
||||
null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable",
|
||||
null, null, null, null), OAUTH2_CLIENT_DISABLE);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test");
|
||||
// 成功调用(1:参数完整)
|
||||
OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(),
|
||||
client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0));
|
||||
assertPojoEquals(client, result);
|
||||
// 成功调用(2:只有 clientId 参数)
|
||||
result = oauth2ClientService.validOAuthClientFromCache(client.getClientId());
|
||||
assertPojoEquals(client, result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ yudao:
|
|||
- tmp_report_data_income
|
||||
ignore-caches:
|
||||
- permission_menu_ids
|
||||
- oauth_client
|
||||
sms-code: # 短信验证码相关的配置项
|
||||
expire-times: 10m
|
||||
send-frequency: 1m
|
||||
|
|
Loading…
Reference in New Issue