refactor(permission): 权限缓存统一处理;增加暂时禁用处理逻辑和接口

This commit is contained in:
zhansihu 2024-01-04 11:45:36 +08:00
parent 9502c353a8
commit 26cee3d6b5
11 changed files with 259 additions and 63 deletions

View File

@ -3,10 +3,10 @@ package cn.axzo.tyr.client.feign;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq;
import cn.axzo.tyr.client.model.req.IdentityAuthReq;
import cn.axzo.tyr.client.model.req.BatchListIdentityFromPermissionReq;
import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq;
import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq;
import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq;
import cn.axzo.tyr.client.model.req.PermissionCacheReq;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp;
import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp;
@ -86,7 +86,8 @@ public interface TyrSaasAuthApi {
@PostMapping("/api/v2/auth/batchListIdentityFromPermission")
ApiResult<List<ListIdentityFromPermissionResp>> batchListIdentityFromPermission(@RequestBody List<ListIdentityFromPermissionReq> req);
/** 暂时禁用权限缓存,至缓存失效 - 实现刷新 **/
@PostMapping("/api/v2/auth/tempDisableAuthCache")
ApiResult<Void> tempDisableAuthCache(@Valid @RequestBody PermissionCacheReq req);
}

View File

@ -0,0 +1,28 @@
package cn.axzo.tyr.client.model.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 权限缓存处理请求
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2024/1/2 18:36
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PermissionCacheReq {
private Long personId;
private Long identityId;
private Integer identityType;
private Boolean disableAll;
}

View File

@ -3,15 +3,19 @@ package cn.axzo.tyr.server.controller.auth;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.tyr.client.feign.TyrSaasAuthApi;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq;
import cn.axzo.tyr.client.model.req.IdentityAuthReq;
import cn.axzo.tyr.client.model.req.BatchListIdentityFromPermissionReq;
import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq;
import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq;
import cn.axzo.tyr.client.model.req.ListPermissionFromIdentityReq;
import cn.axzo.tyr.client.model.req.PermissionCacheReq;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp;
import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.axzo.tyr.server.service.TyrSaasAuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -30,6 +34,7 @@ import java.util.List;
public class TyrSaasAuthController implements TyrSaasAuthApi {
private final TyrSaasAuthService tyrSaasAuthService;
private final PermissionCacheService permissionCacheService;
@Override
public ApiResult<Boolean> hasPermissionForIdentity(CheckIdentityPermissionReq req) {
@ -71,4 +76,14 @@ public class TyrSaasAuthController implements TyrSaasAuthApi {
return ApiResult.ok(tyrSaasAuthService.batchListIdentityFromPermission(req));
}
@Override
public ApiResult<Void> tempDisableAuthCache(PermissionCacheReq req) {
permissionCacheService.markTempDisable(PermissionCacheKey.builder()
.disableAll(req.getDisableAll())
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(IdentityType.getIdentityType(req.getIdentityType()))
.build());
return ApiResult.ok();
}
}

View File

@ -11,12 +11,13 @@ import cn.axzo.tyr.client.model.product.ProductSearchListReq;
import cn.axzo.tyr.client.model.product.ProductSearchPageReq;
import cn.axzo.tyr.client.model.product.ProductUpdateReq;
import cn.axzo.tyr.client.model.product.ProductVO;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.axzo.tyr.server.service.ProductFeatureRelationService;
import cn.axzo.tyr.server.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@ -36,6 +37,7 @@ public class ProductController implements ProductApi {
private final ProductService productService;
private final ProductFeatureRelationService productFeatureRelationService;
private final PermissionCacheService permissionCacheService;
/**
* 获取产品基础信息的列表
*
@ -124,6 +126,7 @@ public class ProductController implements ProductApi {
if(CollectionUtils.isEmpty(req)) {
return ApiResult.ok(false);
}
permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build());
return productFeatureRelationService.updateFeatureRelation(req);
}

View File

@ -15,6 +15,8 @@ import cn.axzo.tyr.client.model.res.RoleWithUserRes;
import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO;
import cn.axzo.tyr.client.model.vo.SaasRoleVO;
import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.axzo.tyr.server.service.RoleService;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
@ -39,10 +41,14 @@ public class SaasRoleController implements TyrSaasRoleApi {
@Autowired
RoleService roleService;
@Autowired
PermissionCacheService permissionCacheService;
@Override
public ApiResult<Long> saveOrUpdate(SaveOrUpdateRoleVO saveOrUpdateRole) {
return ApiResult.ok(roleService.saveOrUpdate(saveOrUpdateRole));
Long result = roleService.saveOrUpdate(saveOrUpdateRole);
permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build());
return ApiResult.ok(result);
}
@Override
@ -66,6 +72,7 @@ public class SaasRoleController implements TyrSaasRoleApi {
@Override
public ApiResult<Void> deleteRole(List<Long> roleIds, Long workSpaceId, Long outId) {
roleService.deleteRole(roleIds, workSpaceId, outId);
permissionCacheService.markTempDisable(PermissionCacheKey.builder().disableAll(true).build());
return ApiResult.ok();
}

View File

@ -5,16 +5,19 @@ import cn.axzo.framework.domain.web.result.ApiPageResult;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserDTO;
import cn.axzo.tyr.client.model.roleuser.dto.SuperAminInfoResp;
import cn.axzo.tyr.client.model.roleuser.req.*;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.axzo.tyr.server.service.SaasRoleUserRelationService;
import cn.axzo.tyr.server.service.SaasRoleUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@ -33,10 +36,17 @@ public class RoleUserController implements TyrSaasRoleUserApi {
private final SaasRoleUserService saasRoleUserService;
private final SaasRoleUserRelationService saasRoleUserRelationService;
private final SaasRoleUserRelationDao saasRoleUserRelationDao;
private final PermissionCacheService permissionCacheService;
@Override
public ApiResult<Void> saveOrUpdate(@Valid RoleUserReq req) {
saasRoleUserService.saveOrUpdate(req);
permissionCacheService.markTempDisable(PermissionCacheKey.builder()
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(req.getIdentityType())
.build());
return ApiResult.ok();
}
@ -44,6 +54,11 @@ public class RoleUserController implements TyrSaasRoleUserApi {
public ApiResult<Void> batchSaveOrUpdate(List<RoleUserReq> req) {
for (RoleUserReq roleUserReq : req) {
saasRoleUserService.saveOrUpdate(roleUserReq);
permissionCacheService.markTempDisable(PermissionCacheKey.builder()
.personId(roleUserReq.getPersonId())
.identityId(roleUserReq.getIdentityId())
.identityType(roleUserReq.getIdentityType())
.build());
}
return ApiResult.ok();
}
@ -62,6 +77,11 @@ public class RoleUserController implements TyrSaasRoleUserApi {
@Override
public ApiResult<Void> createSuperAdminRole(CreateSuperAdminRoleParam param) {
saasRoleUserService.createSuperAdminRole(param);
permissionCacheService.markTempDisable(PermissionCacheKey.builder()
.personId(param.getNaturalPersonId())
.identityId(param.getIdentityId())
.identityType(param.getIdentityType())
.build());
return ApiResult.ok();
}
@ -89,10 +109,18 @@ public class RoleUserController implements TyrSaasRoleUserApi {
*/
public ApiResult removeRoleUserRelation(@RequestBody @Valid List<Long> ids){
AssertUtil.isTrue(!CollectionUtils.isEmpty(ids),"用户角色关联id不能为空");
List<SaasRoleUserRelation> relations = saasRoleUserRelationDao.listByIds(ids);
saasRoleUserRelationDao.lambdaUpdate()
.in(BaseEntity::getId,ids)
.setSql(" is_delete = id")
.update();
for (SaasRoleUserRelation relation : relations) {
permissionCacheService.markTempDisable(PermissionCacheKey.builder()
.personId(relation.getNaturalPersonId())
.identityId(relation.getIdentityId())
.identityType(IdentityType.getIdentityType(relation.getIdentityType()))
.build());
}
return ApiResult.ok();
}

View File

@ -18,7 +18,7 @@ import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AuthPermissionCacheKey {
public class PermissionCacheKey {
private Long personId;
@ -30,8 +30,22 @@ public class AuthPermissionCacheKey {
private Long ouId;
public String buildKey() {
private Boolean disableAll;
public String buildAuthKey() {
return personId == null ? KeyUtil.buildKeyBySeparator("auth-i", identityId, identityType.getCode(), ouId, workspaceId)
: KeyUtil.buildKeyBySeparator("auth-p", personId, ouId, workspaceId);
}
public String buildPersonDisableKey() {
return KeyUtil.buildKeyBySeparator("auth-d-p", personId);
}
public String buildIdentityDisableKey() {
return KeyUtil.buildKeyBySeparator("auth-d-i", identityId, identityType.getCode());
}
public static String buildAllDisableKey() {
return "auth-disable-all";
}
}

View File

@ -0,0 +1,26 @@
package cn.axzo.tyr.server.service;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.axzo.tyr.server.model.PermissionCacheKey;
/**
* 授权缓存服务
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2024/1/3 17:21
*/
public interface PermissionCacheService {
/** 缓存开关 **/
boolean cacheDisable(PermissionCacheKey key);
/** 从缓存获取权限 **/
IdentityAuthRes.WorkspacePermission getPermissionFromCache(PermissionCacheKey key);
/** 缓存权限 **/
void cachePermission(PermissionCacheKey key, IdentityAuthRes.WorkspacePermission permission);
/** 标记缓存暂时不可用 - 等缓存全部失效 **/
void markTempDisable(PermissionCacheKey key);
}

View File

@ -1,5 +1,6 @@
package cn.axzo.tyr.server.service;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq;
import cn.axzo.tyr.client.model.req.IdentityAuthReq;
import cn.axzo.tyr.client.model.req.BatchListIdentityFromPermissionReq;

View File

@ -0,0 +1,96 @@
package cn.axzo.tyr.server.service.impl;
import cn.axzo.pokonyan.config.redis.RedisUtil;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 授权缓存服务实现
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2024/1/3 17:22
*/
@Slf4j
@Service
public class PermissionCacheServiceImpl implements PermissionCacheService {
/** 缓存权限信息开关 **/
@Value("${axzo.cache.auth.enable:true}")
private boolean enable = true;
/** 授权缓存过期时间 **/
@Value("${axzo.cache.auth.expire:30}")
private Long expireInMinutes;
@Override
public boolean cacheDisable(PermissionCacheKey key) {
//缓存开关关闭 或者 标记为临时不可用
return !enable || tempDisable(key);
}
private boolean tempDisable(PermissionCacheKey key) {
//服务包关联产品变化 - 产品下权限点变化 - 角色配置的权限变化 - 用户角色变化 - 权限点类型变化
String allDisable = RedisUtil.StringValueOps.get(PermissionCacheKey.buildAllDisableKey());
if (StrUtil.isNotBlank(allDisable)) {
return true;
}
if (Objects.nonNull(key.getPersonId())) {
String personDisable = RedisUtil.StringValueOps.get(key.buildPersonDisableKey());
return StrUtil.isNotBlank(personDisable);
}
if (Objects.nonNull(key.getIdentityId()) && Objects.nonNull(key.getIdentityType())) {
String identityDisable = RedisUtil.StringValueOps.get(key.buildIdentityDisableKey());
return StrUtil.isNotBlank(identityDisable);
}
return false;
}
@Override
public IdentityAuthRes.WorkspacePermission getPermissionFromCache(PermissionCacheKey key) {
String permission = RedisUtil.StringValueOps.get(key.buildAuthKey());
return permission == null ? null : JSONObject.parseObject(permission,
IdentityAuthRes.WorkspacePermission.class);
}
@Override
public void cachePermission(PermissionCacheKey key, IdentityAuthRes.WorkspacePermission permission) {
RedisUtil.StringValueOps.setEx(key.buildPersonDisableKey(),
JSONObject.toJSONString(permission, SerializerFeature.DisableCircularReferenceDetect),
expireInMinutes, TimeUnit.MINUTES);
}
@Override
public void markTempDisable(PermissionCacheKey key) {
try {
if (BooleanUtil.isTrue(key.getDisableAll())) {
RedisUtil.StringValueOps.setEx(PermissionCacheKey.buildAllDisableKey(), "1", expireInMinutes, TimeUnit.MINUTES);
return;
}
if (Objects.nonNull(key.getPersonId())) {
RedisUtil.StringValueOps.setEx(key.buildPersonDisableKey(), "1", expireInMinutes, TimeUnit.MINUTES);
}
if (Objects.nonNull(key.getIdentityId()) && Objects.nonNull(key.getIdentityType())) {
RedisUtil.StringValueOps.setEx(key.buildIdentityDisableKey(), "1", expireInMinutes, TimeUnit.MINUTES);
}
} catch (Exception ex) {
log.error("mark permission refresh error", ex);
}
}
}

View File

@ -1,10 +1,8 @@
package cn.axzo.tyr.server.service.impl;
import cn.axzo.basics.common.BeanMapper;
import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
import cn.axzo.pokonyan.config.redis.RedisUtil;
import cn.axzo.pokonyan.util.TraceSupplier;
import cn.axzo.thrones.client.saas.ServicePkgClient;
import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct;
@ -15,7 +13,6 @@ import cn.axzo.tyr.client.model.enums.DelegatedType;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.permission.PermissionPointListQueryRequest;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeNode;
import cn.axzo.tyr.client.model.permission.PermissionPointTreeQueryReq;
import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO;
import cn.axzo.tyr.client.model.req.*;
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
@ -23,9 +20,10 @@ import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp;
import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp;
import cn.axzo.tyr.client.model.res.SimplePermissionPointResp;
import cn.axzo.tyr.client.model.vo.SaasRoleVO;
import cn.axzo.tyr.server.model.AuthPermissionCacheKey;
import cn.axzo.tyr.server.model.PermissionCacheKey;
import cn.axzo.tyr.server.repository.entity.*;
import cn.axzo.tyr.server.repository.mapper.TyrSaasAuthMapper;
import cn.axzo.tyr.server.service.PermissionCacheService;
import cn.axzo.tyr.server.service.PermissionPointService;
import cn.axzo.tyr.server.service.ProductFeatureRelationService;
import cn.axzo.tyr.server.service.RoleService;
@ -40,15 +38,12 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
@ -71,9 +66,6 @@ import static cn.axzo.tyr.server.util.RpcInternalUtil.checkAndGetData;
@Slf4j
public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
/** 缓存权限信息开关 **/
@Value("${axzo.cache.auth.enable:true}")
private boolean authCache = true;
private final TyrSaasAuthMapper saasAuthMapper;
@ -86,6 +78,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
private final ProductFeatureRelationService productFeatureRelationService;
private final PermissionPointService permissionPointService;
private final PermissionCacheService permissionCacheService;
/**
* 通过身份查询人员权限
@ -700,10 +694,15 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
@Override
public IdentityAuthRes findIdentityAuthMix(IdentityAuthReq req) {
List<IdentityAuthRes.WorkspacePermission> permissions = null;
//不走缓存的情况关闭缓存开关 - 请求指明不走缓存 - 角色预览操作
boolean notUseCache = !authCache
|| BooleanUtil.isFalse(req.getUseCache())
|| CollectionUtil.isNotEmpty(req.getSpecifyRoleIds());
//不走缓存的情况关闭缓存开关 - 缓存需要刷新 - 请求指明不走缓存 - 角色预览操作
boolean notUseCache = BooleanUtil.isFalse(req.getUseCache())
|| CollectionUtil.isNotEmpty(req.getSpecifyRoleIds())
|| !permissionCacheService.cacheDisable(
PermissionCacheKey.builder()
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(req.getIdentityType())
.build());
if (notUseCache) {
permissions = findIdentityPermission(req);
} else {
@ -744,28 +743,22 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
List<IdentityAuthRes.WorkspacePermission> permissions = new ArrayList<>();
List<IdentityAuthReq.WorkspaceOuPair> needQueryPairs = new ArrayList<>();
if (needRefreshAuth(req.getPersonId(), req.getIdentityId(), req.getIdentityType())) {
//缓存需要刷新 - 直接走原查询逻辑
needQueryPairs.addAll(req.getWorkspaceOusPairs());
} else {
//从缓存取权限并记录缓存中没有的OW
req.getWorkspaceOusPairs().forEach(ow -> {
IdentityAuthRes.WorkspacePermission permission = getIdentityAuthFromCache(AuthPermissionCacheKey.builder()
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(req.getIdentityType())
.ouId(ow.getOuId())
.workspaceId(ow.getWorkspaceId())
.build()
.buildKey());
if (permission == null) {
needQueryPairs.add(ow);
} else {
//加入返回
permissions.add(permission);
}
});
}
//从缓存取权限并记录缓存中没有的OW
req.getWorkspaceOusPairs().forEach(ow -> {
IdentityAuthRes.WorkspacePermission permission = permissionCacheService.getPermissionFromCache(PermissionCacheKey.builder()
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(req.getIdentityType())
.ouId(ow.getOuId())
.workspaceId(ow.getWorkspaceId())
.build());
if (permission == null) {
needQueryPairs.add(ow);
} else {
//加入返回
permissions.add(permission);
}
});
if (CollectionUtil.isNotEmpty(needQueryPairs)) {
//有需要从数据库查询的数据 - 走原查询逻辑 并缓存结果
@ -783,36 +776,20 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService {
.isSuperAdmin(false)
.permissionPoint(Collections.emptyList())
.build());
cacheIdentityAuth(AuthPermissionCacheKey.builder()
permissionCacheService.cachePermission(PermissionCacheKey.builder()
.personId(req.getPersonId())
.identityId(req.getIdentityId())
.identityType(req.getIdentityType())
.ouId(p.getOuId())
.workspaceId(p.getWorkspaceId())
.build()
.buildKey(), permission);
.build(), permission);
});
}
return permissions;
}
private boolean needRefreshAuth(Long personId, Long identityId, IdentityType identityType) {
//TODO:@Zhan 触发刷新逻辑检测
//服务包关联产品变化 - 产品下权限点变化 - 角色配置的权限变化 - 用户角色变化 - 权限点类型变化
return false;
}
private void cacheIdentityAuth(String key, IdentityAuthRes.WorkspacePermission permission) {
RedisUtil.StringValueOps.setEx(key, JSONObject.toJSONString(permission, SerializerFeature.DisableCircularReferenceDetect),
30L, TimeUnit.MINUTES);
}
private IdentityAuthRes.WorkspacePermission getIdentityAuthFromCache(String key) {
String permission = RedisUtil.StringValueOps.get(key);
return permission == null ? null : JSONObject.parseObject(permission,
IdentityAuthRes.WorkspacePermission.class);
}
@Data
public static class UserRoleInfoMap {