diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java index 1cd649ad..0c8f837d 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/IdentityAuthReq.java @@ -59,6 +59,10 @@ public class IdentityAuthReq { /** 指定角色ID - 预览用,不需要用户已配置角色 **/ private Set specifyRoleIds; + /** 是否使用缓存 **/ + @Builder.Default + private boolean useCache = false; + @Data @Builder diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IdentityAuthRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IdentityAuthRes.java index eac35aab..ae66126e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IdentityAuthRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/IdentityAuthRes.java @@ -59,7 +59,7 @@ public class IdentityAuthRes { // private FeatureType featureType; - // private String terminal; + private String terminal; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/auth/TyrSaasAuthController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/auth/TyrSaasAuthController.java index 9ec351e5..c3c404a6 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/auth/TyrSaasAuthController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/auth/TyrSaasAuthController.java @@ -47,7 +47,7 @@ public class TyrSaasAuthController implements TyrSaasAuthApi { @Override public ApiResult findIdentityAuth(@Valid IdentityAuthReq identityAuthReq) { - return ApiResult.ok(tyrSaasAuthService.findIdentityAuth(identityAuthReq)); + return ApiResult.ok(tyrSaasAuthService.findIdentityAuthMix(identityAuthReq)); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java index 1e239849..177e30fa 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/TyrSaasAuthService.java @@ -27,16 +27,16 @@ public interface TyrSaasAuthService { //------------------上面权限接口为2023/10月未上线前提供的接口,在此日期之后(含)的接口统一使用下面的接口--------------------------- - /** - * 查询指定人的权限 - * @param identityAuthReq - * @return - */ - IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq); boolean hasPermissionForIdentityV2(CheckIdentityPermissionReq req); ListIdentityFromPermissionResp listIdentityFromPermission(ListIdentityFromPermissionReq req); List batchListIdentityFromPermission(List req); + /** + * 查询指定人的权限 + * @param identityAuthReq + * @return + */ + IdentityAuthRes findIdentityAuthMix(IdentityAuthReq identityAuthReq); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java index 991c734d..2953e1f4 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureServiceImpl.java @@ -8,6 +8,7 @@ import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.server.service.SaasFeatureService; import cn.axzo.tyr.server.service.TyrSaasAuthService; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -44,13 +45,15 @@ public class SaasFeatureServiceImpl implements SaasFeatureService { workspaceOuPair.setWorkspaceJoinType(req.getWorkspaceJoinType()); authReq.setWorkspaceOusPairs(Lists.newArrayList(workspaceOuPair)); - IdentityAuthRes identityAuthRes = tyrSaasAuthService.findIdentityAuth(authReq); + IdentityAuthRes identityAuthRes = tyrSaasAuthService.findIdentityAuthMix(authReq); List workspacePermissionList = identityAuthRes.getPermissions(); if (CollUtil.isNotEmpty(workspacePermissionList)) { IdentityAuthRes.WorkspacePermission workspacePermission = workspacePermissionList.get(0); featurePermissionRes.setSuperAdmin(workspacePermission.isSuperAdmin()); featurePermissionRes.setPermissionCodes(workspacePermission.getPermissionPoint() - .stream().map(IdentityAuthRes.PermissionPoint::getFeatureCode).collect(Collectors.toSet())); + .stream() + .map(IdentityAuthRes.PermissionPoint::getFeatureCode) + .collect(Collectors.toSet())); } return featurePermissionRes; } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java index c263b903..18171743 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/TyrSaasAuthServiceImpl.java @@ -4,6 +4,7 @@ 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; @@ -36,6 +37,8 @@ import cn.hutool.core.date.StopWatch; import cn.hutool.core.util.ArrayUtil; 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; @@ -292,8 +295,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } - @Override - public IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { + private IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { log.info("find identityAuth :{}", JSONUtil.toJsonStr(identityAuthReq)); StopWatch stopWatch = new StopWatch("find identity Auth"); AssertUtil.notNull(identityAuthReq.getIdentityId(), "查询指定人的权限失败,未获取到人员信息"); @@ -433,14 +435,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //通过子级查询父级并打平树型结构 List allPermissionPoint = permissionPointService.listTreeNodesFlatChild(PermissionPointTreeQueryReq.builder() .ids(buttonPermissionPointId) - .terminalList(identityAuthReq.getTerminal()) .build()); workspacePermission.getPermissionPoint().addAll(allPermissionPoint.stream() .map(permissionPointTreeNode -> IdentityAuthRes.PermissionPoint.builder() .featureCode(permissionPointTreeNode.getCode()) .featureId(permissionPointTreeNode.getPermissionPointId()) - // .terminal(permissionPointTreeNode.getTerminal()) + .terminal(permissionPointTreeNode.getTerminal()) // .featureType(FeatureType.apply(permissionPointTreeNode.getFeatureType())) .build()) .collect(Collectors.toList())); @@ -470,24 +471,13 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { //通过子级查询父级并平铺菜单 List allPermissionPoint = permissionPointService.listTreeNodesFlatChild(PermissionPointTreeQueryReq.builder() .ids(new HashSet<>(resultHashAuthPointId)) - .terminalList(identityAuthReq.getTerminal()) .build()); workspacePermission.getPermissionPoint().addAll(allPermissionPoint.stream() - .filter(permissionPointTreeNode -> { - - if (CollectionUtil.isEmpty(identityAuthReq.getFeatureId()) && CollectionUtil.isEmpty(identityAuthReq.getFeatureCode())) { - return Boolean.TRUE; - } - - return (identityAuthReq.getFeatureId().contains(permissionPointTreeNode.getPermissionPointId())) || - identityAuthReq.getFeatureCode().contains(permissionPointTreeNode.getCode()); - } - ) .map(permissionPointTreeNode -> IdentityAuthRes.PermissionPoint.builder() .featureCode(permissionPointTreeNode.getCode()) .featureId(permissionPointTreeNode.getPermissionPointId()) - // .terminal(permissionPointTreeNode.getTerminal()) + .terminal(permissionPointTreeNode.getTerminal()) // .featureType(FeatureType.apply(permissionPointTreeNode.getFeatureType())) .build()) .collect(Collectors.toList())); @@ -521,7 +511,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } List pairs = BeanMapper.copyList(req.getWorkspaceAndOU(), IdentityAuthReq.WorkspaceOuPair.class); request.setWorkspaceOusPairs(pairs); - IdentityAuthRes authRes = this.findIdentityAuth(request); + IdentityAuthRes authRes = this.findIdentityAuthMix(request); HashSet codeSet = new HashSet<>(req.getCodes()); //比较code return authRes.getPermissions().stream() @@ -693,6 +683,86 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } + + @Override + public IdentityAuthRes findIdentityAuthMix(IdentityAuthReq req) { + List permissions = null; + if (req.isUseCache() || CollectionUtil.isNotEmpty(req.getSpecifyRoleIds())) { + //不走缓存 或者 角色预览 + permissions = findIdentityPermission(req); + } else { + permissions = findIdentityPermissionFromCache(req); + } + + IdentityAuthRes result = new IdentityAuthRes(); + result.setIdentity(req.getIdentityId()); + result.setIdentityType(req.getIdentityType()); + + //过滤参数统一处理 + boolean needFilter = CollectionUtil.isNotEmpty(req.getTerminal()) + || CollectionUtil.isNotEmpty(req.getFeatureCode()) + || CollectionUtil.isNotEmpty(req.getFeatureId()); + if (!needFilter) { + return result; + } + Set terminals = req.getTerminal() == null ? null : new HashSet<>(req.getTerminal()); + permissions.forEach(permission -> { + List filterPermission = permission.getPermissionPoint().stream() + .filter(p -> CollectionUtil.isEmpty(terminals) || terminals.contains(p.getTerminal())) + .filter(p -> CollectionUtil.isEmpty(req.getFeatureId()) || req.getFeatureId().contains(p.getFeatureId())) + .filter(p -> CollectionUtil.isEmpty(req.getFeatureCode()) || req.getFeatureCode().contains(p.getFeatureCode())) + .collect(Collectors.toList()); + permission.setPermissionPoint(filterPermission); + }); + result.setPermissions(permissions); + return result; + } + + private List findIdentityPermission(IdentityAuthReq req) { + return findIdentityAuth(req).getPermissions(); + } + + private List findIdentityPermissionFromCache(IdentityAuthReq req) { + //服务包产品变化 - 角色配置的权限变化 - 用户角色变化 + List permissions = new ArrayList<>(); + //从缓存取权限,并记录缓存中没有的OW + List needQueryPairs = new ArrayList<>(); + req.getWorkspaceOusPairs().forEach(ow -> { + String key = KeyUtil.buildKeyBySeparator("auth", req.getIdentityId(), req.getIdentityType(), ow.getOuId(), ow.getWorkspaceId()); + IdentityAuthRes.WorkspacePermission permission = getIdentityAuthFromCache(key); + if (permission == null) { + needQueryPairs.add(ow); + } else { + //加入返回 + permissions.add(permission); + } + }); + + if (CollectionUtil.isNotEmpty(needQueryPairs)) { + //有需要从数据库查询的数据 - 走原查询逻辑 并缓存结果 + req.setWorkspaceOusPairs(needQueryPairs); + List authPermission = findIdentityPermission(req); + permissions.addAll(authPermission); + authPermission.forEach(p -> { + String key = KeyUtil.buildKeyBySeparator("auth", req.getIdentityId(), req.getIdentityType(), p.getOuId(), p.getWorkspaceId()); + cacheIdentityAuth(key, p); + }); + } + + return permissions; + } + + private void cacheIdentityAuth(String key, IdentityAuthRes.WorkspacePermission permission) { + RedisUtil.StringOps.setEx(key, JSONObject.toJSONString(permission, SerializerFeature.DisableCircularReferenceDetect), + 60L, TimeUnit.MINUTES); + } + + private IdentityAuthRes.WorkspacePermission getIdentityAuthFromCache(String key) { + String permission = RedisUtil.StringOps.get(key); + return permission == null ? null : JSONObject.parseObject(StrUtil.unWrap(permission, '"', '"'), + IdentityAuthRes.WorkspacePermission.class); + } + @Data public static class UserRoleInfoMap {