diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasAuthApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasAuthApi.java index aad7b6f8..14e6e2b5 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasAuthApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasAuthApi.java @@ -101,6 +101,7 @@ public interface TyrSaasAuthApi { /** * * 通过资源ID、资源类型、角色分类 查询权限 + * 该分类下不能有管理员角色,原始代码没有实现管理员角色的权限 * @param listPermissionFromRoleGroupReq * @return */ diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java index 46d9e129..0c364f10 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/feign/TyrSaasRoleUserApi.java @@ -4,6 +4,8 @@ import cn.axzo.foundation.page.PageResp; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.tyr.client.model.permission.BaseIdentityReq; +import cn.axzo.tyr.client.model.req.PageRoleReq; +import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.roleuser.RoleUserUpdateReq; import cn.axzo.tyr.client.model.roleuser.dto.GetUserAutoOwnRoleResp; import cn.axzo.tyr.client.model.roleuser.dto.GetUserFeatureResourceIdsResp; @@ -17,6 +19,7 @@ import cn.axzo.tyr.client.model.roleuser.req.GantOrUnGantaWorkerLeaderRoleReq; import cn.axzo.tyr.client.model.roleuser.req.GetUserAutoOwnRoleReq; import cn.axzo.tyr.client.model.roleuser.req.GetUserFeatureResourceIdsReq; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; +import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationParam; import cn.axzo.tyr.client.model.roleuser.req.PageRoleUserRelationReq; import cn.axzo.tyr.client.model.roleuser.req.RoleUserParam; import cn.axzo.tyr.client.model.roleuser.req.RoleUserReq; @@ -103,6 +106,14 @@ public interface TyrSaasRoleUserApi { @PostMapping("/api/saas-role-user/list/v2") ApiResult> roleUserListV2(@RequestBody @Valid ListRoleUserRelationParam param); + /** + * 用户角色page接口 + * @param request + * @return + */ + @PostMapping("/api/saasRoleUser/page") + ApiResult> page(@RequestBody PageRoleUserRelationParam request); + /** * 批量查询超管, 只能批量获取单个工作台台下的超管,业务系统需要根据返回的identityId和identityType查询identityProfile查询用户明细信息 */ diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/WorkspaceOUPair.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/WorkspaceOUPair.java index 863ef25f..be4c0c18 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/WorkspaceOUPair.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/base/WorkspaceOUPair.java @@ -1,10 +1,13 @@ package cn.axzo.tyr.client.model.base; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Set; + /** * OU Workspace对 * @@ -22,7 +25,9 @@ public class WorkspaceOUPair { private Long workspaceId; - private String buildKey() { - return ouId + "-" + workspaceId; + private Set tags; + + public String buildKey() { + return ouId + "_" + workspaceId; } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RolePermissionTagEnum.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RolePermissionTagEnum.java new file mode 100644 index 00000000..6b655f72 --- /dev/null +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/enums/RolePermissionTagEnum.java @@ -0,0 +1,17 @@ +package cn.axzo.tyr.client.model.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public enum RolePermissionTagEnum { + + JOINED("在职"), + LEAVE("离场"), + ; + + private String desc; +} diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchPermissionCheckReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchPermissionCheckReq.java index 3267bcdc..617fdd72 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchPermissionCheckReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/BatchPermissionCheckReq.java @@ -10,6 +10,7 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; @Data @Builder diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DetailFeatureResourceReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DetailFeatureResourceReq.java index 8f65fa43..7a6ac981 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DetailFeatureResourceReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/DetailFeatureResourceReq.java @@ -1,11 +1,13 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; +import java.util.Set; @Data @Builder @@ -22,4 +24,13 @@ public class DetailFeatureResourceReq { * 资源类型1-菜单 2-页面 3-应用入口 4-组件;5-root节点 */ private Integer featureType; + + private Boolean needChildren; + + private Boolean needPageElement; + + /** + * 只有当needRole = true才有效果,这里查询有指定标签权限的角色信息 + */ + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java index 2afd9e5a..3f5f0d29 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/FeatureRoleRelationReq.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,6 +9,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; @Data @Builder @@ -35,11 +37,24 @@ public class FeatureRoleRelationReq { private Integer featureType; /** 应用的角色Id列表 **/ - private List roleIds; + private Set roles; /** 授权类型 0-全部角色 1-指定角色 **/ private Integer authType; private String terminal; } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Role { + private Long roleId; + + /** + * 权限标签:默认为JOINED + */ + private Set tags; + } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java index 16788bd8..fa255b3e 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/GetUserHasPermissionPageElementReq.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,6 +9,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.util.Set; /** * @author likunpeng @@ -42,4 +44,9 @@ public class GetUserHasPermissionPageElementReq { @NotNull(message = "租户ID不能为空") @Min(value = 1, message = "租户ID有误") private Long workspaceId; + + /** + * 权限标签,默认是根据personId在当前项目的状态解析的 + */ + private Set tags; } 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 13da1cae..d45cd102 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 @@ -2,7 +2,7 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.tyr.client.model.enums.IdentityType; -import cn.axzo.tyr.client.model.res.IdentityAuthRes; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.hutool.core.collection.CollectionUtil; import lombok.AllArgsConstructor; import lombok.Builder; @@ -80,23 +80,6 @@ public class IdentityAuthReq { */ private Integer versionMax; - public IdentityAuthRes toEmpty() { - IdentityAuthRes result = new IdentityAuthRes(); - result.setIdentity(this.getIdentityId()); - result.setIdentityType(this.getIdentityType()); - result.setPersonId(this.getPersonId()); - - List permissions = this.getWorkspaceOusPairs().stream() - .map(workspaceOuPair -> IdentityAuthRes.WorkspacePermission.builder() - .workspaceId(workspaceOuPair.getWorkspaceId()) - .ouId(workspaceOuPair.getOuId()) - .build()) - .collect(Collectors.toList()); - result.setPermissions(permissions); - - return result; - } - public void distinctOUWorkspacePair() { if (CollectionUtil.isEmpty(this.workspaceOusPairs)) { return; @@ -128,6 +111,8 @@ public class IdentityAuthReq { /** 基于角色标签查询逻辑不再用该参数 **/ private Integer workspaceJoinType; + private Set tags; + public String buildOuWorkspaceKey() { return this.getOuId() + "_" + this.getWorkspaceId(); } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java index b68981af..ec61a422 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListIdentityFromPermissionReq.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -7,6 +8,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** @@ -40,4 +42,5 @@ public class ListIdentityFromPermissionReq { */ private String terminal; + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java index 66c0b1c6..3a6c8497 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFeatureReq.java @@ -4,6 +4,7 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; import cn.axzo.tyr.client.model.base.WorkspaceOUPair; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -67,4 +68,5 @@ public class ListPermissionFeatureReq { * 显示或者隐藏,如果父节点是隐藏,则子节点也会隐藏 */ private FeatureResourceStatus status; + } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFromRoleGroupReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFromRoleGroupReq.java index f6245c80..c0076037 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFromRoleGroupReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListPermissionFromRoleGroupReq.java @@ -2,6 +2,7 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.tyr.client.common.enums.SaasPositionEnum; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,6 +10,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** * 通过角色分组及分类查询人员的权限 diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java index 3b05af9a..71e01fbd 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/ListRoleReq.java @@ -3,6 +3,7 @@ package cn.axzo.tyr.client.model.req; import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import lombok.AllArgsConstructor; import lombok.Data; @@ -80,6 +81,13 @@ public class ListRoleReq { @CriteriaField(ignore = true) private Boolean needPermission; + /** + * 根据权限标签去过滤角色对应的权限, + * 只有在needPermission = true时才生效 + */ + @CriteriaField(ignore = true) + private Set permissionTags; + /** * 是否需要角色对应的角色分组信息 */ diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/OUWorkspacePair.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/OUWorkspacePair.java index 64600db5..d11b1be7 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/OUWorkspacePair.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/OUWorkspacePair.java @@ -1,8 +1,10 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.Data; import javax.validation.constraints.NotNull; +import java.util.Set; /** * OU和workspace对 @@ -28,4 +30,6 @@ public class OUWorkspacePair { /** 参建类型 - 直接依赖角色标签 不需要传了 **/ @Deprecated private Integer workspaceJoinType; + + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java index 3039feb2..a3d554af 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PagePgroupPermissionRelationReq.java @@ -4,12 +4,14 @@ import cn.axzo.foundation.dao.support.wrapper.CriteriaField; import cn.axzo.foundation.dao.support.wrapper.Operator; import cn.axzo.foundation.page.IPageReq; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; @Data @Builder @@ -58,4 +60,7 @@ public class PagePgroupPermissionRelationReq implements IPageReq { */ @CriteriaField(ignore = true) private List featureIdPairs; + + @CriteriaField(ignore = true) + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java index 11064145..d0fd1517 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/PermissionCheckReq.java @@ -1,5 +1,7 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; +import com.google.common.collect.Sets; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -8,6 +10,7 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** * 权限校验请求 @@ -38,4 +41,9 @@ public class PermissionCheckReq { * 登录端,历史的cms和cmp,cm端没有给端,给了会有问题 */ private String terminal; + + /** + * 权限标签 + */ + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java index 6f57bed7..f13a5615 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/TreePermissionReq.java @@ -4,6 +4,7 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; import cn.axzo.tyr.client.model.base.WorkspaceOUPair; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -79,4 +80,5 @@ public class TreePermissionReq { * 显示或者隐藏,如果父节点是隐藏,则子节点也会隐藏 */ private FeatureResourceStatus status; + } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/WorkspacePermissionIdentityReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/WorkspacePermissionIdentityReq.java index 87c93534..f88bd05c 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/WorkspacePermissionIdentityReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/req/WorkspacePermissionIdentityReq.java @@ -1,9 +1,11 @@ package cn.axzo.tyr.client.model.req; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** * @version V1.0 @@ -20,4 +22,6 @@ public class WorkspacePermissionIdentityReq { /** 权限点CODE **/ @NotNull private List featureCodes; + + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java index 8cb87ea7..922c19cf 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/FeatureResourceTreeNode.java @@ -1,8 +1,11 @@ package cn.axzo.tyr.client.model.res; import cn.axzo.basics.common.model.IBaseTree; +import cn.axzo.tyr.client.common.enums.RoleTypeEnum; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; @@ -27,7 +30,24 @@ public class FeatureResourceTreeNode extends FeatureResourceDTO implements IBase private List roleCodes; - private Set roleIds; + /** + * 兼容 + */ + private List roles; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Role { + private Long roleId; + + private String roleCode; + + private Set tags; + + private RoleTypeEnum roleType; + } @JsonIgnore @Override diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFromRoleGroupResp.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFromRoleGroupResp.java index d2547c25..50db400c 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFromRoleGroupResp.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/ListPermissionFromRoleGroupResp.java @@ -1,6 +1,7 @@ package cn.axzo.tyr.client.model.res; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -88,6 +89,12 @@ public class ListPermissionFromRoleGroupResp { private Long featureId; /** 0:saas_feature,1:saas_feature_resource **/ private Integer relationType; + + private Set tags; + } + + public String buildOuWorkspaceKey() { + return this.getOuId() + "_" + this.getWorkspaceId(); } } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java index 60d129ec..4bae5fe6 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/RoleTreeRes.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.res; +import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -63,4 +64,9 @@ public class RoleTreeRes { private String idStr; private Integer ouType; + + /** + * type = ROLE时,会返回roleType + */ + private RoleTypeEnum roleType; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java index f8ba9b09..a42930dc 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRelationRes.java @@ -1,10 +1,13 @@ package cn.axzo.tyr.client.model.res; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Set; + @Data @Builder @NoArgsConstructor @@ -25,4 +28,11 @@ public class SaasPermissionRelationRes { * 菜单资源树节点类型 */ private Integer featureType; + + /** + * 权限点标签: + * 在职:JOINED + * 离场:LEAVE + */ + private Set tags; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java index 2cf6fc65..c43a5415 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/res/SaasPermissionRes.java @@ -1,10 +1,13 @@ package cn.axzo.tyr.client.model.res; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Set; + @Data @Builder @NoArgsConstructor @@ -23,4 +26,6 @@ public class SaasPermissionRes { */ private String terminal; + private Set tags; + } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java index b4b69369..636183ff 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/dto/SaasRoleUserRelationDTO.java @@ -78,4 +78,6 @@ public class SaasRoleUserRelationDTO { private String roleType; private String roleCode; + + private String roleName; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationReq.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationReq.java index a23b2f86..5b017f3a 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationReq.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/roleuser/req/PageRoleUserRelationReq.java @@ -34,6 +34,8 @@ public class PageRoleUserRelationReq{ private Boolean includeDelete; - @NotEmpty(message = "roleIds不能为空") +// @NotEmpty(message = "roleIds不能为空") private Set roleIds; + + private Set personIds; } diff --git a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java index 0e53d2d7..573f9f31 100644 --- a/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java +++ b/tyr-api/src/main/java/cn/axzo/tyr/client/model/vo/SaveOrUpdateRoleVO.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.client.model.vo; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -71,9 +72,10 @@ public class SaveOrUpdateRoleVO { private List selectedPPIds; /** - * 新的oms权限 + * 角色对应的权限 + * selectedPPIds、permissionIds、permissions只能选一个 */ - private Set permissionIds; + private Set permissions; /** * '角色编码' @@ -103,4 +105,14 @@ public class SaveOrUpdateRoleVO { */ private String workspaceTypeCode; } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Permission { + private Long permissionId; + + private Set tags; + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java index 709f03e2..ab3066a2 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateController.java @@ -28,7 +28,6 @@ import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; -import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.event.inner.SendDingTalkHandler; import cn.axzo.tyr.server.event.outer.CacheWorkspaceProductHandler; import cn.axzo.tyr.server.event.payload.SaasFeatureResourceUpsertPayload; @@ -75,7 +74,6 @@ import cn.axzo.tyr.server.service.WorkspaceProductService; import cn.axzo.tyr.server.service.impl.SaasFeatureResourceCacheService; import cn.axzo.tyr.server.util.FeatureCodeUtil; import cn.azxo.framework.common.utils.StringUtils; -import com.alibaba.excel.EasyExcel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; @@ -92,14 +90,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -380,11 +375,6 @@ public class PrivateController { return productPermissionCacheService.list(request); } - @PostMapping("/api/private/permission/auth") - public Object authPermission(@Validated @RequestBody PermissionCheckReq request) { - return tyrSaasAuthService.authPermission(request); - } - /** 刷新表saas_pgroup_permission_relation的type字段 **/ @PostMapping("/api/private/pgroupPermissionRelation/refresh") public ApiResult refreshPgroupPermissionRelation(@Validated @RequestBody RefreshPgroupPermissionRelationParam request) { diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java index 37a731f9..18e7a9db 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/PrivateRoleController.java @@ -5,11 +5,11 @@ import cn.axzo.framework.rocketmq.Event; import cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; +import cn.axzo.tyr.client.model.enums.PermissionGroupType; import cn.axzo.tyr.client.model.enums.PermissionType; import cn.axzo.tyr.client.model.enums.WorkspaceTypeCodeEnum; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.ListSaasRoleGroupParam; -import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleGroupDTO; @@ -20,11 +20,13 @@ import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.config.MqProducer; +import cn.axzo.tyr.server.event.inner.CacheRoleSaasFeatureResourceHandler; import cn.axzo.tyr.server.event.payload.RolePermissionCreatedPayload; -import cn.axzo.tyr.server.model.ResourcePermission; +import cn.axzo.tyr.server.repository.dao.SaasPermissionGroupDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; import cn.axzo.tyr.server.repository.dao.SaasRoleDao; import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao; +import cn.axzo.tyr.server.repository.entity.SaasPermissionGroup; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; import cn.axzo.tyr.server.repository.entity.SaasRole; @@ -47,6 +49,7 @@ import com.alibaba.excel.metadata.CellExtra; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.common.collect.Streams; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -105,6 +108,10 @@ public class PrivateRoleController { private SaasPgroupRoleRelationDao saasPgroupRoleRelationDao; @Autowired private MqProducer mqProducer; + @Autowired + private SaasPermissionGroupDao saasPermissionGroupDao; + @Autowired + private CacheRoleSaasFeatureResourceHandler cacheRoleSaasFeatureResourceHandler; private static final String TARGET_TYPE = "saasFeatureResourceId"; @@ -664,7 +671,101 @@ public class PrivateRoleController { return "ok"; } - @Data + @PostMapping("/api/private/superAdmin/pgroupPermission/init") + public Object createSuperAdminPgroupPermission() { + ListRoleReq listRoleReq = ListRoleReq.builder() + .roleTypes(Lists.newArrayList(RoleTypeEnum.SUPER_ADMIN.getValue(), RoleTypeEnum.ADMIN.getValue())) + .build(); + + List allSuperAdminRoles = roleService.list(listRoleReq); + if (CollectionUtils.isEmpty(allSuperAdminRoles)) { + return "ok"; + } + + Set hasRoleIds = saasPgroupRoleRelationDao.lambdaQuery() + .in(SaasPgroupRoleRelation::getRoleId, Lists.transform(allSuperAdminRoles, SaasRoleRes::getId)) + .list() + .stream() + .map(SaasPgroupRoleRelation::getRoleId) + .collect(Collectors.toSet()); + + List initRoles = allSuperAdminRoles.stream() + .filter(role -> !hasRoleIds.contains(role.getId())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(initRoles)) { + return "ok"; + } + + List saasPermissionGroups = initRoles.stream() + .map(role -> { + SaasPermissionGroup saasPermissionGroup = new SaasPermissionGroup(); + saasPermissionGroup.setName("通用权限"); + saasPermissionGroup.setIsCommon(PermissionGroupType.COMMON.getCode()); + saasPermissionGroup.setCreateBy(154587L); + saasPermissionGroup.setCreatorName("王今"); + saasPermissionGroup.setUpdateBy(154587L); + saasPermissionGroup.setUpdatorName("王今"); + saasPermissionGroup.setType("feature"); + return saasPermissionGroup; + }) + .collect(Collectors.toList()); + + saasPermissionGroupDao.saveBatch(saasPermissionGroups); + + List saasPgroupRoleRelations = Streams.zip(initRoles.stream(), saasPermissionGroups.stream(), + (role, pgroup) -> { + SaasPgroupRoleRelation saasPgroupRoleRelation = new SaasPgroupRoleRelation(); + saasPgroupRoleRelation.setRoleId(role.getId()); + saasPgroupRoleRelation.setGroupId(pgroup.getId()); + saasPgroupRoleRelation.setCreateBy(154587L); + saasPgroupRoleRelation.setUpdateBy(154587L); + saasPgroupRoleRelation.setCreateAt(new Date()); + saasPgroupRoleRelation.setUpdateAt(new Date()); + return saasPgroupRoleRelation; + }) + .collect(Collectors.toList()); + saasPgroupRoleRelationDao.saveBatch(saasPgroupRoleRelations); + return "ok"; + } + + @PostMapping("/api/private/rolePermission/delete") + public Object deleteRolePermission() { + + List relations = saasPgroupPermissionRelationService.lambdaQuery() + .eq(SaasPgroupPermissionRelation::getType, NEW_FEATURE) + .in(SaasPgroupPermissionRelation::getTerminal, Lists.newArrayList("NT_CMS_WEB_GENERAL", "NT_CMP_APP_GENERAL")) + .list(); + + List ids = relations.stream() + .collect(Collectors.groupingBy(e -> e.getFeatureId() + "_" + e.getGroupId())) + .entrySet() + .stream() + .filter(e -> e.getValue().size() > 1) + .flatMap(e -> e.getValue().subList(0, e.getValue().size() - 1).stream()) + .map(SaasPgroupPermissionRelation::getId) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(ids)) { + return "ok"; + } + + saasPgroupPermissionRelationService.lambdaUpdate() + .set(SaasPgroupPermissionRelation::getIsDelete, 20241107) + .in(SaasPgroupPermissionRelation::getId, ids) + .update(); + return "ok"; + } + + @PostMapping("/api/private/test") + public Object test(@RequestBody @Validated RolePermissionCreatedPayload payload) { + cacheRoleSaasFeatureResourceHandler.onRolePermissionUpsert(Event.builder() + .data(payload) + .build(), null); + return "ok"; + } + + @Data @Builder @NoArgsConstructor @AllArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java index bbcd3653..6399b0bb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/permission/PermissionQueryController.java @@ -97,7 +97,6 @@ public class PermissionQueryController implements PermissionQueryApi { @Override public ApiResult> listPermission(ListPermissionFeatureReq req) { - return ApiResult.ok(permissionService.listPermission(req)); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java index 9a240cd1..599a2cbb 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/role/SaasRoleController.java @@ -5,6 +5,7 @@ import cn.axzo.framework.domain.web.result.ApiListResult; import cn.axzo.framework.domain.web.result.ApiPageResult; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum; +import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.feign.TyrSaasRoleApi; import cn.axzo.tyr.client.model.enums.DictWorkSpaceTypeEnum; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; @@ -33,7 +34,6 @@ import cn.axzo.tyr.client.model.vo.DeleteRoleVO; import cn.axzo.tyr.client.model.vo.SaasRoleAndGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleCategoryVO; import cn.axzo.tyr.client.model.vo.SaasRoleGroupCodeVO; -import cn.axzo.tyr.client.model.vo.SaasRoleGroupVO; import cn.axzo.tyr.client.model.vo.SaasRoleVO; import cn.axzo.tyr.client.model.vo.SaveOrUpdateRoleVO; import cn.axzo.tyr.server.model.PermissionCacheKey; @@ -481,6 +481,7 @@ public class SaasRoleController implements TyrSaasRoleApi { .workspaceId(role.getWorkspaceId()) .ouId(role.getOwnerOuId()) .ouType(role.getProductUnitType()) + .roleType(RoleTypeEnum.getRoleType(role.getRoleType())) .build(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java index ef2f9ad4..80227edc 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/controller/roleuser/RoleUserController.java @@ -192,6 +192,11 @@ public class RoleUserController implements TyrSaasRoleUserApi { return ApiResult.ok(saasRoleUserRelationService.listV2(param)); } + @Override + public ApiResult> page(PageRoleUserRelationParam param) { + return ApiResult.ok(saasRoleUserRelationService.page(param)); + } + @Override public ApiResult createSuperAdminRole(CreateSuperAdminRoleParam param) { saasRoleUserService.createSuperAdminRole(param); @@ -343,24 +348,29 @@ public class RoleUserController implements TyrSaasRoleUserApi { } return saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder() - .roleIds(Lists.newArrayList(param.getRoleIds())) - .workspaceOuPairs(Optional.ofNullable(param.getWorkspaceOUPairs()) - .map(e -> e.stream().map(f -> ListRoleUserRelationParam.WorkspaceOuPair.builder() - .workspaceId(f.getWorkspaceId()) - .ouId(f.getOuId()) - .build()) - .collect(Collectors.toList())) - .orElse(null)) - .build()) - .stream() - .map(e -> { - SaasRoleUserRelationDTO saasRoleUserRelationDTO = SaasRoleUserRelationDTO.builder().build(); - BeanUtils.copyProperties(e, saasRoleUserRelationDTO); - saasRoleUserRelationDTO.setId(e.getId()); - saasRoleUserRelationDTO.setNaturalPersonId(e.getSaasRoleUser().getPersonId()); - return saasRoleUserRelationDTO; - }) - .collect(Collectors.toList()); + .roleIds(Optional.ofNullable(param.getRoleIds()) + .map(Lists::newArrayList) + .orElse(null)) + .personIds(Optional.ofNullable(param.getPersonIds()) + .map(Lists::newArrayList) + .orElse(null)) + .workspaceOuPairs(Optional.ofNullable(param.getWorkspaceOUPairs()) + .map(e -> e.stream().map(f -> ListRoleUserRelationParam.WorkspaceOuPair.builder() + .workspaceId(f.getWorkspaceId()) + .ouId(f.getOuId()) + .build()) + .collect(Collectors.toList())) + .orElse(null)) + .build()) + .stream() + .map(e -> { + SaasRoleUserRelationDTO saasRoleUserRelationDTO = SaasRoleUserRelationDTO.builder().build(); + BeanUtils.copyProperties(e, saasRoleUserRelationDTO); + saasRoleUserRelationDTO.setId(e.getId()); + saasRoleUserRelationDTO.setNaturalPersonId(e.getSaasRoleUser().getPersonId()); + return saasRoleUserRelationDTO; + }) + .collect(Collectors.toList()); } @Override diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRolePermissionHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRolePermissionHandler.java index 20bc1f7a..1f4afeed 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRolePermissionHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRolePermissionHandler.java @@ -2,7 +2,6 @@ package cn.axzo.tyr.server.event.inner; import cn.axzo.framework.rocketmq.Event; import cn.axzo.framework.rocketmq.EventConsumer; -import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; @@ -49,7 +48,6 @@ public class CacheRolePermissionHandler implements InitializingBean { .roleIds(Optional.ofNullable(payload.getRoleIds()) .map(Lists::newArrayList) .orElse(null)) - .roleTypesNotIn(RoleTypeEnum.listAdmin()) .build(); Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) @@ -74,7 +72,6 @@ public class CacheRolePermissionHandler implements InitializingBean { } ListRoleReq listSaasRoleParam = ListRoleReq.builder() - .roleTypesNotIn(RoleTypeEnum.listAdmin()) .build(); Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRoleSaasFeatureResourceHandler.java b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRoleSaasFeatureResourceHandler.java index e8d327a3..b3bd8e32 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRoleSaasFeatureResourceHandler.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/event/inner/CacheRoleSaasFeatureResourceHandler.java @@ -2,7 +2,6 @@ package cn.axzo.tyr.server.event.inner; import cn.axzo.framework.rocketmq.Event; import cn.axzo.framework.rocketmq.EventConsumer; -import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload; @@ -40,17 +39,10 @@ public class CacheRoleSaasFeatureResourceHandler implements InitializingBean { log.info("begin cached role saasFeatureResource handler rocketmq event: {}", event); RolePermissionCreatedPayload payload = event.normalizedData(RolePermissionCreatedPayload.class); - // 影响角色权限入口的代码没法简单重构,导致发送的roleIds可能不准确,所以一旦有角色权限的更新事件后,全量更新角色权限,角色权限数量不多 - // 后续收口了代码就准确根据角色去更新缓存 -// if (CollectionUtils.isEmpty(payload.getRoleIds())) { -// return; -// } - ListRoleReq listSaasRoleParam = ListRoleReq.builder() .roleIds(Optional.ofNullable(payload.getRoleIds()) .map(Lists::newArrayList) .orElse(null)) - .roleTypesNotIn(RoleTypeEnum.listAdmin()) .build(); Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) @@ -74,9 +66,7 @@ public class CacheRoleSaasFeatureResourceHandler implements InitializingBean { return; } - ListRoleReq listSaasRoleParam = ListRoleReq.builder() - .roleTypesNotIn(RoleTypeEnum.listAdmin()) - .build(); + ListRoleReq listSaasRoleParam = ListRoleReq.builder().build(); Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductFeatureResourceJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductFeatureResourceJob.java index 0bbc2b63..7933977d 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductFeatureResourceJob.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductFeatureResourceJob.java @@ -9,6 +9,7 @@ import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -19,7 +20,7 @@ import java.util.stream.Collectors; @Slf4j @Component -public class CacheProductFeatureResourceJob extends IJobHandler { +public class CacheProductFeatureResourceJob extends IJobHandler implements InitializingBean { @Autowired private ProductSaasFeatureResourceCacheService productSaasFeatureResourceCacheService; @@ -50,4 +51,10 @@ public class CacheProductFeatureResourceJob extends IJobHandler { productSaasFeatureResourceCacheService.refreshCache(param); return ReturnT.SUCCESS; } + + @Override + public void afterPropertiesSet() throws Exception { + // 启动时加载做localCache + execute(null); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductPermissionJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductPermissionJob.java index e7913351..3c89a156 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductPermissionJob.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheProductPermissionJob.java @@ -9,6 +9,7 @@ import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -19,7 +20,7 @@ import java.util.stream.Collectors; @Slf4j @Component -public class CacheProductPermissionJob extends IJobHandler { +public class CacheProductPermissionJob extends IJobHandler implements InitializingBean { @Autowired private ProductPermissionCacheService productPermissionCacheService; @@ -49,4 +50,10 @@ public class CacheProductPermissionJob extends IJobHandler { productPermissionCacheService.refreshCache(param); return ReturnT.SUCCESS; } + + @Override + public void afterPropertiesSet() throws Exception { + // 启动时加载做localCache + execute(null); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRoleFeatureResourceJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRoleFeatureResourceJob.java index bc60ddd2..dcd89db4 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRoleFeatureResourceJob.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRoleFeatureResourceJob.java @@ -10,6 +10,7 @@ import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -20,7 +21,7 @@ import java.util.stream.Collectors; @Slf4j @Component -public class CacheRoleFeatureResourceJob extends IJobHandler { +public class CacheRoleFeatureResourceJob extends IJobHandler implements InitializingBean { @Autowired private RoleService roleService; @@ -35,7 +36,6 @@ public class CacheRoleFeatureResourceJob extends IJobHandler { ListRoleReq listSaasRoleParam = Optional.ofNullable(s) .map(e -> JSONObject.parseObject(e, ListRoleReq.class)) .orElseGet(() -> ListRoleReq.builder().build()); - listSaasRoleParam.setRoleTypesNotIn(RoleTypeEnum.listAdmin()); Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) @@ -51,4 +51,10 @@ public class CacheRoleFeatureResourceJob extends IJobHandler { return ReturnT.SUCCESS; } + + @Override + public void afterPropertiesSet() throws Exception { + // 启动时加载做localCache + execute(null); + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRolePermissionJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRolePermissionJob.java index edba7b4f..26187ffe 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRolePermissionJob.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheRolePermissionJob.java @@ -10,6 +10,7 @@ import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -20,7 +21,7 @@ import java.util.stream.Collectors; @Slf4j @Component -public class CacheRolePermissionJob extends IJobHandler { +public class CacheRolePermissionJob extends IJobHandler implements InitializingBean { @Autowired private RoleService roleService; @@ -37,8 +38,6 @@ public class CacheRolePermissionJob extends IJobHandler { .map(e -> JSONObject.parseObject(e, ListRoleReq.class)) .orElseGet(() -> ListRoleReq.builder().build()); - listSaasRoleParam.setRoleTypesNotIn(RoleTypeEnum.listAdmin()); - Set roleIds = roleService.list(listSaasRoleParam).stream() .map(SaasRoleRes::getId) .collect(Collectors.toSet()); @@ -53,4 +52,10 @@ public class CacheRolePermissionJob extends IJobHandler { return ReturnT.SUCCESS; } + @Override + public void afterPropertiesSet() throws Exception { + // 启动时加载做localCache + execute(null); + } + } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheSaasFeatureJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheSaasFeatureJob.java index 622a1b4c..70e4d129 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheSaasFeatureJob.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/CacheSaasFeatureJob.java @@ -15,6 +15,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -24,7 +25,7 @@ import java.util.stream.Collectors; @Slf4j @Component -public class CacheSaasFeatureJob extends IJobHandler { +public class CacheSaasFeatureJob extends IJobHandler implements InitializingBean { @Autowired private SaasFeatureDao saasFeatureDao; @@ -85,6 +86,12 @@ public class CacheSaasFeatureJob extends IJobHandler { saasFeatureResourceService.refreshCache(param); } + @Override + public void afterPropertiesSet() throws Exception { + // 启动时加载做localCache + execute(null); + } + @Data @Builder @NoArgsConstructor diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java index 9a6a146b..8f4ba3bf 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/model/FilterRoleAuth.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.model; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.server.service.impl.TyrSaasAuthServiceImpl; import lombok.AllArgsConstructor; import lombok.Builder; @@ -7,6 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; +import java.util.Set; /** * 通过工作台过滤角色的权限 @@ -23,5 +25,4 @@ public class FilterRoleAuth { private Long roleId; private Long workspaceId; - } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java index 3ab81d9d..401f86a0 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/entity/SaasPgroupPermissionRelation.java @@ -1,17 +1,23 @@ package cn.axzo.tyr.server.repository.entity; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedJdbcTypes; +import org.apache.ibatis.type.MappedTypes; import java.io.Serializable; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; /** * 权限集功能中间表(SaasPgroupPermissionRelation)表实体类 @@ -23,7 +29,7 @@ import java.util.Objects; @Setter @ToString @EqualsAndHashCode(callSuper = true) -@TableName("saas_pgroup_permission_relation") +@TableName(value = "saas_pgroup_permission_relation", autoResultMap = true) public class SaasPgroupPermissionRelation extends BaseEntity { public static final Integer OLD_FEATURE = 0; @@ -70,6 +76,12 @@ public class SaasPgroupPermissionRelation extends BaseEntity tags; + /** * 获取主键值 * @@ -87,5 +99,28 @@ public class SaasPgroupPermissionRelation extends BaseEntity { + + private Class type; + + public TagTypeHandler(Class type) { + this.type = type; + } + + @Override + protected Object parse(String json) { + return JSONArray.parseArray(json).stream() + .map(e -> RolePermissionTagEnum.valueOf(e.toString())) + .collect(Collectors.toSet()); + } + + @Override + protected String toJson(Object obj) { + return JSONArray.toJSONString(obj); + } + } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java index f1608317..6d81a629 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionCacheService.java @@ -1,14 +1,6 @@ package cn.axzo.tyr.server.service; -import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.server.model.PermissionCacheKey; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; -import java.util.Set; /** * 授权缓存服务 @@ -18,140 +10,6 @@ import java.util.Set; * @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); - - /** - * 缓存权限码跟角色的信息,采用set数据结构 - * redisKey:featureCode - * redisValue: roleId - * @param param - */ - void cachePermissionRole(CachePermissionRoleParam param); - - /** - * 根据权限码查询对应的角色信息 - * @param param - * @return - */ - List listPermissionRole(ListPermissionRoleParam param); - - /** - * 缓存权限码跟产品和单位类型的信息,采用set数据结构 - * redisKey: featureCode - * redisValue: 产品信息 - * @param param - */ - void cachePermissionProduct(CachePermissionProductParam param); - - /** - * 根据权限码查询对应的产品信息 - * 一个权限点对应的产品数据比较少,一般10多个,所以没有聚合返回,方便排查哪些权限点已经在redis中,不用从数据库中查询 - * @param param - * @return - */ - List listPermissionProduct(ListPermissionProductParam param); - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class HasPermissionRoleParam { - - private List featureCodes; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class ListPermissionRoleParam { - - private List featureCodes; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class CachePermissionRoleParam { - - private List permissionRoles; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class PermissionRole { - /** - * 权限码 - */ - private String featureCode; - - /** - * 角色id - */ - private List roleIds; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class ListPermissionProductParam { - - private List featureCodes; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class CachePermissionProductParam { - - private List permissionProducts; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class PermissionProduct { - /** - * 权限码 - */ - private String featureCode; - - /** - * 产品信息 - */ - private List products; - } - - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - class Product { - /** - * 产品id - */ - private Long productId; - - /** - * 单位类型 - */ - private Integer ouType; - } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java new file mode 100644 index 00000000..a4f07a0d --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/PermissionTagService.java @@ -0,0 +1,53 @@ +package cn.axzo.tyr.server.service; + +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Set; + +public interface PermissionTagService { + + List resolvePermissionTag(ResolvePermissionTagParam param); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ResolvePermissionTagParam { + + private List personPermissions; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class PersonPermission { + + private Long workspaceId; + + private Long ouId; + + private Long personId; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + class ResolvePermissionDTO { + + private Long workspaceId; + + private Long ouId; + + private Long personId; + + private Set tags; + } +} + diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java index 67b62a8d..d866482a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RolePermissionCacheService.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.service; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -42,6 +43,8 @@ public interface RolePermissionCacheService { private Set roleIds; private Set featureCodes; + + private Set tags; } @Data @@ -70,5 +73,12 @@ public interface RolePermissionCacheService { private String terminal; private Integer featureType; + + /** + * 权限点标签: + * 在职:JOINED + * 离场:LEAVE + */ + private Set tags; } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleSaasFeatureResourceCacheService.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleSaasFeatureResourceCacheService.java index 5d70fe28..073e543a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleSaasFeatureResourceCacheService.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/RoleSaasFeatureResourceCacheService.java @@ -1,5 +1,6 @@ package cn.axzo.tyr.server.service; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -70,5 +71,7 @@ public interface RoleSaasFeatureResourceCacheService { private Integer featureType; private String uniCode; + + private Set tags; } } 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 36f8a2b1..ad487d34 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 @@ -1,14 +1,11 @@ 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; 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.ListPermissionFromRoleGroupReq; -import cn.axzo.tyr.client.model.req.PermissionCheckReq; import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; @@ -52,24 +49,4 @@ public interface TyrSaasAuthService { * @return */ List listAuthByResourceAndRoleGroup(ListPermissionFromRoleGroupReq listPermissionFromRoleGroupReq); - - /** - * 基于saas_feature的接口鉴权 - * @param req - * @return - */ - boolean authPermission(PermissionCheckReq req); - - /** - * 基于saas_feature_resource的接口鉴权 - * @param req - * @return - */ - boolean authNewPermission(PermissionCheckReq req); - - /** - * 增加统一的开关:权限是否从数据库查询 - * @return - */ - boolean permissionFromDB(); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java index c97a8a99..39951186 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/FeatureResourceSyncServiceImpl.java @@ -9,6 +9,7 @@ import cn.axzo.framework.rocketmq.Event; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.req.GetFeatureResourceTreeReq; import cn.axzo.tyr.client.model.req.ResourceSyncReq; import cn.axzo.tyr.client.model.res.FeatureResourceTreeNode; @@ -22,7 +23,12 @@ import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationD import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; import cn.axzo.tyr.server.repository.dao.SaasRoleDao; -import cn.axzo.tyr.server.repository.entity.*; +import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; +import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; +import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelationOperateLog; +import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; +import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.service.FeatureResourceSyncService; import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService; import cn.axzo.tyr.server.util.RpcInternalUtil; @@ -31,6 +37,10 @@ import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -41,9 +51,8 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -124,10 +133,20 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic allFeatureResourceIds.addAll(CollectionUtils.emptyIfNull(componentList).stream().map(BaseEntity::getId).collect(Collectors.toList())); resourceList.addAll(componentList); } - Map> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds); + Map> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds); List dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class); - dtoList.forEach(e -> e.setRoleCodes(featureResourceRoleCodeMap.get(e.getId()))); + dtoList.forEach(e -> { + List roles = featureResourceRoleCodeMap.get(e.getId()); + if (Objects.isNull(roles)) { + return; + } + e.setRoleCodes(roles.stream() + .map(FeatureResourceTreeNode.Role::getRoleCode) + .distinct() + .collect(Collectors.toList())); + e.setRoles(roles); + }); return TreeUtil.buildTree(dtoList); } @@ -277,7 +296,7 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } // 处理资源关联的权限 - RelationOperateLogResourceBindRoleDO logResourceBindRoleDO = doFeatureResourceRole(baseResource, treeNode.getRoleCodes(), operatorId, syncedRoleFeatureResourceIds); + RelationOperateLogResourceBindRoleDO logResourceBindRoleDO = doFeatureResourceRole(baseResource, treeNode, operatorId, syncedRoleFeatureResourceIds); if (Objects.nonNull(logResourceBindRoleDO)) { operateDos.add(logResourceBindRoleDO); } @@ -308,8 +327,10 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } } - private RelationOperateLogResourceBindRoleDO doFeatureResourceRole(SaasFeatureResource featureResource, List roleCodes, - Long operatorId, Set syncedRoleFeatureResourceIds) { + private RelationOperateLogResourceBindRoleDO doFeatureResourceRole(SaasFeatureResource featureResource, + FeatureResourceTreeNode treeNode, + Long operatorId, + Set syncedRoleFeatureResourceIds) { if (Objects.isNull(featureResource)) { return null; } @@ -336,26 +357,29 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic .uniCode(featureResource.getUniCode()) .build(); - roleCodes = CollectionUtils.emptyIfNull(roleCodes).stream().filter(StringUtils::isNotBlank).collect(Collectors.toList()); + List roleCodes = CollectionUtils.emptyIfNull(treeNode.getRoles()).stream() + .map(FeatureResourceTreeNode.Role::getRoleCode) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); if (CollectionUtils.isEmpty(roleCodes)) { return logResourceBindRoleDO; } -// List existRoleCodes = getFeatureResourceRoleCodeMap(Lists.newArrayList(featureResource.getId())) -// .get(featureResource.getId()); -// -// if (CollectionUtils.isNotEmpty(existRoleCodes)) { -// roleCodes.removeAll(existRoleCodes); -// } -// if (CollectionUtils.isEmpty(roleCodes)) { -// return; -// } - List saasRoles = saasRoleDao.listByRoleCodes(roleCodes); if (CollectionUtils.isEmpty(saasRoles)) { return logResourceBindRoleDO; } + + Map sourceRoleMap = treeNode.getRoles().stream() + .collect(Collectors.toMap(FeatureResourceTreeNode.Role::getRoleCode, Function.identity(), (f, s) -> s)); + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(saasRoles.stream().map(BaseEntity::getId).collect(Collectors.toList())); + Map pgroupRoleMap = saasPgroupRoleRelations.stream() + .collect(Collectors.toMap(SaasPgroupRoleRelation::getGroupId, Function.identity())); + + Map localRoleMap = saasRoles.stream() + .collect(Collectors.toMap(SaasRole::getId, Function.identity())); + Set groupIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toSet()); List existRoleIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getRoleId).collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(groupIds)) { @@ -368,6 +392,11 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic relation.setType(NEW_FEATURE); relation.setFeatureType(featureResource.getFeatureType()); relation.setTerminal(featureResource.getTerminal()); + + SaasPgroupRoleRelation saasPgroupRoleRelation = pgroupRoleMap.get(groupId); + SaasRole saasRole = localRoleMap.get(saasPgroupRoleRelation.getRoleId()); + FeatureResourceTreeNode.Role role = sourceRoleMap.get(saasRole.getRoleCode()); + relation.setTags(role.getTags()); return relation; }) .collect(Collectors.toList()); @@ -387,7 +416,20 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic return logResourceBindRoleDO; } - private Map> getFeatureResourceRoleCodeMap(List allFeatureResourceIds) { + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + private static class PermissionGroupRoleWrapper { + + private Long featureId; + + private String roleCode; + + private Set tags; + } + + private Map> getFeatureResourceRoleCodeMap(List allFeatureResourceIds) { allFeatureResourceIds = allFeatureResourceIds.stream().distinct().collect(Collectors.toList()); List permissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() .eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value) @@ -414,9 +456,6 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic return Collections.emptyMap(); } - Map> featureIdToGroupIdsMap = permissionRelations.stream() - .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getFeatureId, - Collectors.mapping(SaasPgroupPermissionRelation::getGroupId, Collectors.toList()))); Map> groupIdToRoleIdsMap = roleRelations.stream() .collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId, @@ -429,18 +468,35 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic } } - Map> featureRoleMap = new HashMap<>(); - featureIdToGroupIdsMap.forEach((featureId, groupIds) -> { - List roleCodes = groupIds.stream() - .flatMap(groupId -> groupIdToRoleIdsMap.getOrDefault(groupId, Collections.emptyList()).stream()) - .map(roleIdToRoleCodeMap::get) - .filter(StringUtils::isNotBlank) - .collect(Collectors.toList()); + return permissionRelations.stream() + .map(e -> { + List roleIds = groupIdToRoleIdsMap.get(e.getGroupId()); + if (CollectionUtils.isEmpty(roleIds)) { + return null; + } + return roleIds.stream() + .map(roleId -> { + String roleCode = roleIdToRoleCodeMap.get(roleId); + if (StringUtils.isBlank(roleCode)) { + return null; + } + return PermissionGroupRoleWrapper.builder() + .featureId(e.getFeatureId()) + .roleCode(roleCode) + .tags(e.getTags()) + .build(); - featureRoleMap.put(featureId, roleCodes); - }); - - return featureRoleMap; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + }) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.groupingBy(PermissionGroupRoleWrapper::getFeatureId, + Collectors.mapping(e -> FeatureResourceTreeNode.Role.builder() + .roleCode(e.getRoleCode()) + .tags(e.getTags()) + .build(), Collectors.toList()))); } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java index 10f2fe8c..8908441a 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionCacheServiceImpl.java @@ -1,32 +1,18 @@ package cn.axzo.tyr.server.service.impl; -import cn.axzo.pokonyan.config.redis.RedisClient; 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.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.google.common.collect.Streams; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.dao.DataAccessException; -import org.springframework.data.redis.core.RedisOperations; -import org.springframework.data.redis.core.SessionCallback; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; -import java.util.Collections; -import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; /** * 授权缓存服务实现 @@ -40,58 +26,12 @@ import java.util.stream.Collectors; @RefreshScope public class PermissionCacheServiceImpl implements PermissionCacheService { - /** 缓存权限信息开关 **/ - @Value("${axzo.cache.auth.enable:true}") - private boolean enable = true; /** 授权缓存过期时间 **/ @Value("${axzo.cache.auth.expire:30}") private Long expireInMinutes; @Autowired protected StringRedisTemplate redisTemplate; - private static final String PERMISSION_ROLE_KEY = "permission:role:%s"; - private static final String PERMISSION_PRODUCT_KEY = "permission:product:%s"; - - @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.buildAuthKey(), - JSONObject.toJSONString(permission, SerializerFeature.DisableCircularReferenceDetect), - expireInMinutes, TimeUnit.MINUTES); - } @Override public void markTempDisable(PermissionCacheKey key) { @@ -110,111 +50,4 @@ public class PermissionCacheServiceImpl implements PermissionCacheService { log.error("mark permission refresh error", ex); } } - - @Override - public void cachePermissionRole(CachePermissionRoleParam param) { - redisTemplate.executePipelined(new SessionCallback() { - @Override - public Object execute(RedisOperations operations) throws DataAccessException { - - for (PermissionRole permissionRole : param.getPermissionRoles()) { - String redisKey = getKey(PERMISSION_ROLE_KEY, permissionRole.getFeatureCode()); - - String[] redisValues = permissionRole.getRoleIds().stream().toArray(String[]::new); - - RedisClient.SetOps.sAdd(redisKey, redisValues); - redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); - log.info("succeed to store permission role: redisKey:{} value:{}", redisKey, redisValues); - } - return null; - } - }); - } - - @Override - public List listPermissionRole(ListPermissionRoleParam param) { - if (CollectionUtils.isEmpty(param.getFeatureCodes())) { - return Collections.emptyList(); - } - - List redisValues = redisTemplate.executePipelined(new SessionCallback() { - @Override - public Object execute(RedisOperations operations) throws DataAccessException { - - for (String featureCode : param.getFeatureCodes()) { - String redisKey = getKey(PERMISSION_ROLE_KEY, featureCode); - operations.opsForSet().members(redisKey); - } - return null; - } - }); - - return Streams.zip(param.getFeatureCodes().stream(), - redisValues.stream(), - (featureCode, redisValue) -> { - PermissionRole permissionProduct = PermissionRole.builder() - .featureCode(featureCode) - .roleIds(JSONArray.parseArray(JSONArray.toJSONString(redisValue), Long.class)) - .build(); - return permissionProduct; - }) - .collect(Collectors.toList()); - } - - @Override - public void cachePermissionProduct(CachePermissionProductParam param) { - redisTemplate.executePipelined(new SessionCallback() { - @Override - public Object execute(RedisOperations operations) throws DataAccessException { - - for (PermissionProduct permissionProduct : param.getPermissionProducts()) { - String redisKey = getKey(PERMISSION_PRODUCT_KEY, permissionProduct.getFeatureCode()); - - String[] redisValues = permissionProduct.getProducts().stream() - .map(JSONObject::toJSONString) - .toArray(String[]::new); - - RedisClient.SetOps.sAdd(redisKey, redisValues); - redisTemplate.expire(redisKey, 4, TimeUnit.DAYS); - log.info("succeed to store permission product: redisKey:{} value:{}", redisKey, redisValues); - } - return null; - } - }); - } - - @Override - public List listPermissionProduct(ListPermissionProductParam param) { - if (CollectionUtils.isEmpty(param.getFeatureCodes())) { - return Collections.emptyList(); - } - - - List redisValues = redisTemplate.executePipelined(new SessionCallback() { - @Override - public Object execute(RedisOperations operations) throws DataAccessException { - - for (String featureCode : param.getFeatureCodes()) { - String redisKey = getKey(PERMISSION_PRODUCT_KEY, featureCode); - operations.opsForSet().members(redisKey); - } - return null; - } - }); - - return Streams.zip(param.getFeatureCodes().stream(), - redisValues.stream(), - (featureCode, redisValue) -> { - PermissionProduct permissionProduct = PermissionProduct.builder() - .featureCode(featureCode) - .products(JSONArray.parseArray(JSONArray.toJSONString(redisValue), Product.class)) - .build(); - return permissionProduct; - }) - .collect(Collectors.toList()); - } - - private String getKey(String pref, Object... params) { - return String.format(pref, params); - } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java index 71206132..aec2c278 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionQueryServiceImpl.java @@ -8,19 +8,17 @@ import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.framework.domain.web.result.ApiResult; import cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum; import cn.axzo.pokonyan.config.mybatisplus.BaseEntity; -import cn.axzo.pokonyan.util.TraceSupplier; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; -import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.base.FeatureResourceExtraDO; import cn.axzo.tyr.client.model.base.WorkspaceOUPair; import cn.axzo.tyr.client.model.enums.IdentityType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.product.ProductFeatureRelationVO; -import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.ListPermissionFeatureReq; import cn.axzo.tyr.client.model.req.NavTreeReq; @@ -36,8 +34,6 @@ import cn.axzo.tyr.client.model.res.ListPermissionFeatureResp; import cn.axzo.tyr.client.model.res.NavTreeResp; import cn.axzo.tyr.client.model.res.ProductFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; -import cn.axzo.tyr.client.model.res.SaasPermissionRelationRes; -import cn.axzo.tyr.client.model.res.SaasRoleRes; import cn.axzo.tyr.client.model.res.TreePermissionResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; @@ -51,8 +47,8 @@ import cn.axzo.tyr.server.model.WorkspaceFeatureRelation; import cn.axzo.tyr.server.repository.dao.ProductModuleDao; import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; -import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; import cn.axzo.tyr.server.service.PermissionQueryService; +import cn.axzo.tyr.server.service.PermissionTagService; import cn.axzo.tyr.server.service.ProductFeatureRelationService; import cn.axzo.tyr.server.service.ProductSaasFeatureResourceCacheService; import cn.axzo.tyr.server.service.RoleSaasFeatureResourceCacheService; @@ -72,8 +68,6 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; -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; @@ -89,13 +83,10 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.tyr.server.repository.entity.SaasFeatureResource.DISPLAY_STATUS; -import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation.NEW_FEATURE; /** * 权限查询服务实现 * @@ -110,7 +101,6 @@ import static cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation. public class PermissionQueryServiceImpl implements PermissionQueryService { private final SaasFeatureResourceService featureResourceService; - private final RoleUserService roleUserService; private final RoleService roleService; private final TyrSaasAuthService saasAuthService; private final ServicePkgClient servicePkgClient; @@ -120,16 +110,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { private final SaasRoleUserRelationService saasRoleUserRelationService; private final WorkspaceProductService workspaceProductService; private final RoleSaasFeatureResourceCacheService roleSaasFeatureResourceCacheService; - private final TyrSaasAuthService tyrSaasAuthService; - - - @Qualifier("authExecutor") - @Autowired - private Executor executor; - - - @Value("${use.old.auth:true}") - private boolean USE_OLD_AUTH; + private final PermissionTagService permissionTagService; @Value("${not.auth.uniCodes:}") private Set notAuthUniCodes; @@ -151,8 +132,14 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } List featureIds = permissions.stream() .map(PermissionDO::getFeatureIds) + .filter(Objects::nonNull) .flatMap(Set::stream) .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(featureIds)) { + return Collections.emptyList(); + } + //反查资源信息-仅页面 List resourceList = featureResourceService.listNavByIds(featureIds, FeatureResourceType.pageTypes()); //查所有上级菜单 @@ -206,18 +193,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } } - if (USE_OLD_AUTH) { - log.info("user old auth"); - return hasPermissionV2(req); - } - log.info("user new auth"); - - List> authFutures = Lists.newArrayList(); - authFutures.add(CompletableFuture.supplyAsync(TraceSupplier.create(() -> saasAuthService.authPermission(req)), executor)); - authFutures.add(CompletableFuture.supplyAsync(TraceSupplier.create(() -> saasAuthService.authNewPermission(req)), executor)); - return authFutures.stream() - .anyMatch(CompletableFuture::join); - + return hasPermissionV2(req); } //权限编码转ID List resourcePermissions = featureResourceService.permissionQuery( @@ -244,7 +220,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .personId(req.getPersonId()) .workspaceOusPairs(Collections.singletonList(IdentityAuthReq.WorkspaceOuPair.builder() .workspaceId(req.getWorkspaceId()) - .ouId(req.getOuId()).build())) + .ouId(req.getOuId()) + .tags(req.getTags()) + .build())) .featureCode(new HashSet<>(req.getFeatureCodes())) .terminal(StringUtils.isBlank(req.getTerminal()) ? null : Collections.singletonList(req.getTerminal())) .build(); @@ -341,125 +319,11 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } - private List resolveFeatureIds(TreePermissionReq treePermissionReq) { - if (CollectionUtils.isEmpty(treePermissionReq.getUniCodes())) { - return Collections.emptyList(); - } - - PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .uniCodes(treePermissionReq.getUniCodes()) - .build(); - return featureResourceService.list(pageSaasFeatureResourceReq).stream() - .map(SaasFeatureResourceResp::getId) - .collect(Collectors.toList()); - } - - private List listUserPermission(TreePermissionReq treePermissionReq, List featureIds) { - List workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() - .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() - .workspaceId(e.getWorkspaceId()) - .ouId(e.getOuId()) - .build()) - .collect(Collectors.toList()); - - ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() - .personId(treePermissionReq.getPersonId()) - .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) - .needRole(true) - .needPermissionRelation(true) - .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) - .type(NEW_FEATURE) - .terminal(treePermissionReq.getTerminal()) - .featureIds(featureIds) - .build(); - return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() - .filter(e -> e.getSaasRole() != null) - .collect(Collectors.toList()); - } - - private Set listUserPermissionFeatureIdsFromDB(TreePermissionReq treePermissionReq) { - - List featureIds = resolveFeatureIds(treePermissionReq); - - if (CollectionUtils.isNotEmpty(treePermissionReq.getUniCodes()) && CollectionUtils.isEmpty(featureIds)) { - return Collections.emptySet(); - } - - List saasRoleUserV2DTOS = listUserPermission(treePermissionReq, featureIds); - - // 用户可能没有角色 - if (CollectionUtils.isEmpty(saasRoleUserV2DTOS)) { - return Collections.emptySet(); - } - - List workspaceProducts = listWorkspaceProducts(treePermissionReq, featureIds); - - //免授权 - Set authFreeFeatureIds = listNotAuthFeatures(treePermissionReq); - - //取交集确定权限 - return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds); - } - - private Set mixFeatureIds(List saasRoleUsers, - List workspaceProducts, - Set authFreeFeatureIds) { - - Map workspaceProductMap = workspaceProducts.stream() - .collect(Collectors.toMap(WorkspaceProductService.WorkspaceProduct::getWorkspaceId, Function.identity())); - - return saasRoleUsers.stream() - .filter(roleUser -> { - WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId()); - if (workspaceProduct == null || CollectionUtils.isEmpty(workspaceProduct.getSaasProductModuleFeatureRelations())) { - log.warn("no workspace product feature found for id:{}", roleUser.getSaasRoleUser().getWorkspaceId()); - return false; - } - return true; - }) - .map(roleUser -> { - WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId()); - - SaasRoleUserV2DTO.SaasRole saasRole = roleUser.getSaasRole(); - if (RoleTypeEnum.isAdmin(saasRole.getRoleType())) { - return resolveAdminRole(workspaceProduct, saasRole); - } - return resolveNormalRole(workspaceProduct, saasRole, authFreeFeatureIds); - }) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); - } - - private List listWorkspaceProducts(TreePermissionReq treePermissionReq, - List featureIds) { - //查询租户产品权限点 - Set workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream() - .map(WorkspaceOUPair::getWorkspaceId) - .collect(Collectors.toSet()); - - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .terminal(treePermissionReq.getTerminal()) - .workspaceIds(workspaceIds) - .featureResourceTypes(treePermissionReq.getFeatureResourceTypes()) - .type(NEW_FEATURE) - .build(); - - if (CollectionUtils.isNotEmpty(featureIds)) { - workspaceProductParam.setFeatureIdPairs(Lists.newArrayList(FeatureIdPair.builder() - .featureIds(Sets.newHashSet(featureIds)) - .type(NEW_FEATURE) - .build())); - } - return workspaceProductService.listWorkspaceProduct(workspaceProductParam); - } - - - @Override public List treePermission(TreePermissionReq req) { Set allFeatureIds = Sets.newHashSet(); - Set featureIds = resovlePermission(req); + Set featureIds = listUserPermissionFeatureIds(req); Set defaultFeatureIds = listNotAuthFeatureIds(req); allFeatureIds.addAll(featureIds); @@ -557,20 +421,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .collect(Collectors.toList()); } - private Set resovlePermission(TreePermissionReq req) { - - if (tyrSaasAuthService.permissionFromDB()) { - return listUserPermissionFeatureIdsFromDB(req); - } - - try { - return listUserPermissionFeatureIds(req); - } catch (Exception ex) { - log.error("查询权限异常,执行降级处理"); - return listUserPermissionFeatureIdsFromDB(req); - } - } - private List filterFeature(List saasFeatureResources) { if (CollectionUtils.isEmpty(saasFeatureResources)) { return Collections.emptyList(); @@ -867,6 +717,51 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .orElse(Collections.emptyList()); } + private void assembleTag(TreePermissionReq treePermissionReq) { + + if (CollectionUtils.isEmpty(treePermissionReq.getWorkspaceOUPairs())) { + return; + } + + List needResolveTags = treePermissionReq.getWorkspaceOUPairs().stream() + .filter(e -> CollectionUtils.isEmpty(e.getTags())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(needResolveTags)) { + return; + } + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(needResolveTags.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(treePermissionReq.getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + Map resolvePermissions = permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); + + treePermissionReq.getWorkspaceOUPairs().forEach(e -> { + if (CollectionUtils.isNotEmpty(e.getTags())) { + return; + } + + PermissionTagService.ResolvePermissionDTO resolvePermissionDTO = resolvePermissions.get(e.buildKey()); + if (Objects.isNull(resolvePermissionDTO)) { + return; + } + + e.setTags(resolvePermissionDTO.getTags()); + }); + } + + /** + * 用户可能只有子节点的权限,但是要构建这个菜单树,所以需要先查询这个端的所有菜单,然后根据用户的权限找到对应的父节点构建树 + * @param treePermissionReq + * @return + */ private Set listUserPermissionFeatureIds(TreePermissionReq treePermissionReq) { List allFeatureResources = listAllFeatureResources(treePermissionReq); @@ -875,7 +770,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return Collections.emptySet(); } - List saasRoleUsers = listUserPermission(treePermissionReq); + assembleTag(treePermissionReq); + + List saasRoleUsers = listUserRole(treePermissionReq); if (CollectionUtils.isEmpty(saasRoleUsers)) { return Collections.emptySet(); } @@ -890,7 +787,14 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { //免授权 Set authFreeFeatureIds = allFeatureResources.stream() .filter(e -> BooleanUtils.isTrue(e.isNotAuth())) - .map(SaasFeatureResourceService.SaasFeatureResourceCache::getFeatureId) + .flatMap(e -> { + Set parentIds = e.getParentIds(); + if (CollectionUtils.isEmpty(parentIds)) { + return Sets.newHashSet(e.getFeatureId()).stream(); + } + parentIds.add(e.getFeatureId()); + return parentIds.stream(); + }) .collect(Collectors.toSet()); Set allFeatureIds = allFeatureResources.stream() @@ -906,16 +810,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { allFeatureIds); } - private Set listNotAuthFeatures(TreePermissionReq treePermissionReq) { - PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .terminal(treePermissionReq.getTerminal()) - .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) - .build(); - return featureResourceService.list(pageSaasFeatureResourceReq).stream() - .map(SaasFeatureResourceResp::getId) - .collect(Collectors.toSet()); - } - private List listWorkspaceProducts(TreePermissionReq treePermissionReq) { //查询租户产品权限点 Set workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream() @@ -931,7 +825,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { return workspaceProductService.listWorkspaceProductFeatureResourceCached(listWorkspaceProductFeatureSourceCacheParam); } - private List listUserPermission(TreePermissionReq treePermissionReq) { + private List listUserRole(TreePermissionReq treePermissionReq) { List workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() .workspaceId(e.getWorkspaceId()) @@ -981,6 +875,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .map(e -> e.stream().map(FeatureResourceType::getCode).collect(Collectors.toSet())) .orElseGet(Sets::newHashSet); + Map workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream() + .collect(Collectors.toMap(WorkspaceOUPair::buildKey, Function.identity(), (f, s) -> f)); + return saasRoleUsers.stream() .map(roleUser -> { List productFeatureSources = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId()) @@ -998,15 +895,32 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { SaasRoleUserV2DTO.SaasRole saasRole = roleUser.getSaasRole(); - Set adminFeatureIds = resolveAdminRole(productFeatureSources, saasRole); - Set notAuthFeatureIds = resolveNotAuthFeatureIds(productFeatureSources, authFreeFeatureIds); + WorkspaceOUPair workspaceOUPair = workspaceOuPairs.get(roleUser.getSaasRoleUser().buildOuWorkspaceKey()); + if (Objects.isNull(workspaceOUPair)) { + return null; + } + Set adminFeatureIds = resolveAdminRole(productFeatureSources, saasRole, workspaceOUPair); + Set notAuthFeatureIds = resolveNotAuthFeatureIds(productFeatureSources, authFreeFeatureIds); List roleFeatureResources = Optional.ofNullable(roleFeatureResourceMap.get(saasRole.getId())) .map(role -> role.stream() .filter(e -> StringUtils.isBlank(treePermissionReq.getTerminal()) || Objects.equals(e.getTerminal(), treePermissionReq.getTerminal())) .filter(e -> CollectionUtils.isEmpty(featureTypes) || featureTypes.contains(e.getFeatureType())) + .filter(e -> { + if (CollectionUtils.isEmpty(workspaceOUPair.getTags())) { + return true; + } + + Set rolePermissionTags = Optional.ofNullable(e.getTags()) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED)); + if (Sets.intersection(workspaceOUPair.getTags(), rolePermissionTags).isEmpty()) { + return false; + } + + return true; + }) .collect(Collectors.toList())) .orElseGet(Lists::newArrayList); @@ -1025,12 +939,17 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { } private Set resolveAdminRole(List productFeatureSources, - SaasRoleUserV2DTO.SaasRole saasRole) { + SaasRoleUserV2DTO.SaasRole saasRole, + WorkspaceOUPair workspaceOUPair) { if (!RoleTypeEnum.isAdmin(saasRole.getRoleType())) { return Collections.emptySet(); } + if (!CollectionUtils.isEmpty(workspaceOUPair.getTags()) && !workspaceOUPair.getTags().contains(RolePermissionTagEnum.JOINED)) { + return Collections.emptySet(); + } + //超管和管理员 直接取和角色类型匹配的租户产品权限 return productFeatureSources.stream() .filter(e -> Objects.equals(e.getCooperateType(), saasRole.getProductUnitType().toString()) @@ -1071,33 +990,4 @@ public class PermissionQueryServiceImpl implements PermissionQueryService { .filter(authFreeFeatureIds::contains) .collect(Collectors.toSet()); } - - private List resolveAdminRole(WorkspaceProductService.WorkspaceProduct workspaceProduct, - SaasRoleUserV2DTO.SaasRole saasRole) { - - //超管和管理员 直接取和角色类型匹配的租户产品权限 - return workspaceProduct.getSaasProductModuleFeatureRelations().stream() - .filter(f -> Objects.equals(f.getDictCode(), saasRole.getProductUnitType().toString()) - || !NumberUtil.isPositiveNumber(saasRole.getProductUnitType())) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toList()); - } - - private List resolveNormalRole(WorkspaceProductService.WorkspaceProduct workspaceProduct, - SaasRoleUserV2DTO.SaasRole saasRole, - Set authFreeFeatureIds) { - //普通角色:角色同类型的租户产品权限已分配 且角色上已分配 + 免授权 - Set roleFeatureIds = Optional.ofNullable(saasRole.getPermissionRelations()) - .map(e -> e.stream() - .map(SaasPermissionRelationRes::getFeatureId) - .collect(Collectors.toSet())) - .orElseGet(Collections::emptySet); - - return workspaceProduct.getSaasProductModuleFeatureRelations().stream() - .filter(f -> Objects.equals(f.getDictCode(), saasRole.getProductUnitType().toString()) - || !NumberUtil.isPositiveNumber(saasRole.getProductUnitType())) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .filter(id -> roleFeatureIds.contains(id) || authFreeFeatureIds.contains(id)) - .collect(Collectors.toList()); - } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java new file mode 100644 index 00000000..8c0eecdd --- /dev/null +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/PermissionTagServiceImpl.java @@ -0,0 +1,85 @@ +package cn.axzo.tyr.server.service.impl; + +import cn.axzo.maokai.api.client.OrgUserApi; +import cn.axzo.maokai.api.vo.request.OrgUserListReq; +import cn.axzo.maokai.api.vo.request.WorkspaceOuPair; +import cn.axzo.maokai.api.vo.response.OrgUserRes; +import cn.axzo.maokai.common.enums.OrgUserStatusEnum; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; +import cn.axzo.tyr.server.service.PermissionTagService; +import cn.axzo.tyr.server.utils.RpcInternalUtil; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Sets; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class PermissionTagServiceImpl implements PermissionTagService { + + @Autowired + private OrgUserApi orgUserApi; + + private static final Map ORG_USER_TAGS = Maps.newHashMap(); + + static { + // 除了用户在项目下是离场状态要取离场权限,其他为了兼容都取在场权限,因为人岗架可能会新增状态,其他删除这些状态会删除用户角色 + ORG_USER_TAGS.put(OrgUserStatusEnum.LEAVE, RolePermissionTagEnum.LEAVE); + } + + @Override + public List resolvePermissionTag(ResolvePermissionTagParam param) { + + if (CollectionUtils.isEmpty(param.getPersonPermissions())) { + return Collections.emptyList(); + } + + List personIds = param.getPersonPermissions().stream() + .map(PersonPermission::getPersonId) + .collect(Collectors.toList()); + List workspaceOuPairs = param.getPersonPermissions().stream() + .map(e -> WorkspaceOuPair.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .build()) + .collect(Collectors.toList()); + + // 因为底层接口实现没有根据personId和workspaceOu去匹配查询,可能会多返回数据,所以这里要过滤 + OrgUserListReq orgUserListReq = OrgUserListReq.builder() + .personIds(personIds) + .ouWorkspacePairs(workspaceOuPairs) + .build(); + + List orgUserRes = RpcInternalUtil.rpcApiListResultProcessor(() -> orgUserApi.listOrgUser(orgUserListReq), + "查询人员在项目的状态", orgUserListReq).getData(); + + if (CollectionUtils.isEmpty(orgUserRes)) { + return Collections.emptyList(); + } + + Set keys = param.getPersonPermissions().stream() + .map(e -> e.getOuId() + "_" + e.getWorkspaceId() + "_" + e.getPersonId()) + .collect(Collectors.toSet()); + + return orgUserRes.stream() + .filter(e -> keys.contains(e.getOuId() + "_" + e.getWorkspaceId() + "_" + e.getPersonId())) + .map(e -> ResolvePermissionDTO.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(e.getPersonId()) + .tags(Optional.ofNullable(ORG_USER_TAGS.get(e.getStatus())) + .map(Sets::newHashSet) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED))) + .build()) + .collect(Collectors.toList()); + } +} diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java index 7c8fd442..e2c59d92 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RolePermissionCacheServiceImpl.java @@ -17,6 +17,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.config.annotation.RefreshScope; @@ -84,18 +85,23 @@ public class RolePermissionCacheServiceImpl implements RolePermissionCacheServic .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().orElseGet(Lists::newArrayList))); } catch (ExecutionException ex) { log.error("list role cache permission error:{} error", param.getRoleIds(), ex); - // 外面有做降级 throw new ServiceException("查询角色权限缓存异常"); } - if (CollectionUtils.isEmpty(param.getFeatureCodes())) { - return rolePermissions; - } - return rolePermissions.entrySet() .stream() .map(e -> Pair.of(e.getKey(), e.getValue().stream() - .filter(permission -> param.getFeatureCodes().contains(permission.getFeatureCode())) + .filter(permission -> CollectionUtils.isEmpty(param.getFeatureCodes()) + || param.getFeatureCodes().contains(permission.getFeatureCode())) + .filter(permission -> { + if (CollectionUtils.isEmpty(param.getTags()) || CollectionUtils.isEmpty(permission.getTags())) { + return true; + } + if (Sets.intersection(param.getTags(), permission.getTags()).isEmpty()) { + return false; + } + return true; + }) .collect(Collectors.toList())) ) .filter(e -> !CollectionUtils.isEmpty(e.getValue())) @@ -183,6 +189,7 @@ public class RolePermissionCacheServiceImpl implements RolePermissionCacheServic .featureCode(saasFeature.getFeatureCode()) .featureType(saasFeature.getFeatureType()) .terminal(saasFeature.getTerminal()) + .tags(permissionRelation.getTags()) .build()); List parentPermissions = saasFeature.splitPath().stream() @@ -193,6 +200,7 @@ public class RolePermissionCacheServiceImpl implements RolePermissionCacheServic .featureCode(f.getFeatureCode()) .featureType(f.getFeatureType()) .terminal(f.getTerminal()) + .tags(permissionRelation.getTags()) .build()) .collect(Collectors.toList()); @@ -217,6 +225,7 @@ public class RolePermissionCacheServiceImpl implements RolePermissionCacheServic .featureCode(pageElement.getCode()) .featureType(featureResource.getFeatureType()) .terminal(featureResource.getTerminal()) + .tags(permissionRelation.getTags()) .build()) .collect(Collectors.toList()); @@ -235,6 +244,7 @@ public class RolePermissionCacheServiceImpl implements RolePermissionCacheServic .featureCode(pageElement.getCode()) .featureType(f.getFeatureType()) .terminal(f.getTerminal()) + .tags(permissionRelation.getTags()) .build()) .collect(Collectors.toList()); }) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleSaasFeatureResourceCacheServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleSaasFeatureResourceCacheServiceImpl.java index 1336c29e..15756bad 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleSaasFeatureResourceCacheServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleSaasFeatureResourceCacheServiceImpl.java @@ -162,6 +162,7 @@ public class RoleSaasFeatureResourceCacheServiceImpl implements RoleSaasFeatureR .featureType(featureResource.getFeatureType()) .terminal(featureResource.getTerminal()) .uniCode(featureResource.getUniCode()) + .tags(permissionRelation.getTags()) .build()); List parentPermissions = featureResource.resolvePath().stream() .map(parentFeatureResources::get) @@ -177,6 +178,7 @@ public class RoleSaasFeatureResourceCacheServiceImpl implements RoleSaasFeatureR .featureType(f.getFeatureType()) .terminal(f.getTerminal()) .uniCode(f.getUniCode()) + .tags(permissionRelation.getTags()) .build(); }) .filter(Objects::nonNull) diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java index 888e9065..fd25853f 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/RoleServiceImpl.java @@ -17,6 +17,7 @@ import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.IdentityType; import cn.axzo.tyr.client.model.enums.PermissionGroupType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.req.ChangeGroupLeaderRoleReq; import cn.axzo.tyr.client.model.req.FeatureRoleRelationReq; import cn.axzo.tyr.client.model.req.ListRoleReq; @@ -496,7 +497,6 @@ public class RoleServiceImpl extends ServiceImpl List groupTrees = saveOrUpdateRole.getGroupTree(); // 验证角色分组信息 validRoleGroup(groupTrees); - //validRoleName(saveOrUpdateRole); SaasRole saasRole = validAndBuildRole(saveOrUpdateRole, now); //验证权限集信息 SaasPermissionGroup saasPermissionGroup = validPermissionGroupCommon(saveOrUpdateRole); @@ -504,7 +504,7 @@ public class RoleServiceImpl extends ServiceImpl // TODO 旧的权限,待权限切完后就下掉 List saasFeatures = validFeature(saveOrUpdateRole.getSelectedPPIds()); // 新的权限 - List saasFeatureResources = validPermission(saveOrUpdateRole.getPermissionIds()); + List saasFeatureResources = validPermission(saveOrUpdateRole.getPermissions()); saasRoleDao.saveOrUpdate(saasRole); // 新增或者保存分组和角色映射关系 @@ -590,8 +590,8 @@ public class RoleServiceImpl extends ServiceImpl private void saveOperateLog4RoleBindFeature(SaveOrUpdateRoleVO saveOrUpdateRole) { SaasRole saasRole = saasRoleDao.getById(saveOrUpdateRole.getId()); List uniCodes = null; - if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getPermissionIds())) { - uniCodes = saasFeatureResourceDao.lambdaQuery().in(BaseEntity::getId, saveOrUpdateRole.getPermissionIds()).list().stream().map(SaasFeatureResource::getUniCode).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getSelectedPPIds())) { + uniCodes = saasFeatureResourceDao.lambdaQuery().in(BaseEntity::getId, saveOrUpdateRole.getSelectedPPIds()).list().stream().map(SaasFeatureResource::getUniCode).collect(Collectors.toList()); } RelationOperateLogRoleBindResourceDO operateAfter = RelationOperateLogRoleBindResourceDO.builder() @@ -622,7 +622,7 @@ public class RoleServiceImpl extends ServiceImpl private void saveSaasFeatureResourcePermission(SaveOrUpdateRoleVO saveOrUpdateRole, List resourcePermissions, SaasPermissionGroup saasPermissionGroup) { - if (CollectionUtils.isEmpty(saveOrUpdateRole.getPermissionIds())) { + if (CollectionUtils.isEmpty(saveOrUpdateRole.getPermissions())) { return; } @@ -630,17 +630,19 @@ public class RoleServiceImpl extends ServiceImpl .collect(Collectors.toMap(ResourcePermission::getId, Function.identity())); // 保存权限集和权限点映射关系 - List pgpRelations = saveOrUpdateRole.getPermissionIds().stream() - .map(ppId -> { - ResourcePermission resourcePermission = resourcePermissionMap.get(ppId); + List pgpRelations = saveOrUpdateRole.getPermissions().stream() + .map(permission -> { + ResourcePermission resourcePermission = resourcePermissionMap.get(permission.getPermissionId()); SaasPgroupPermissionRelation target = new SaasPgroupPermissionRelation(); target.setGroupId(saasPermissionGroup.getId()); - target.setFeatureId(ppId); + target.setFeatureId(permission.getPermissionId()); target.setCreateBy(saveOrUpdateRole.getOperatorId()); target.setUpdateBy(saveOrUpdateRole.getOperatorId()); target.setFeatureType(resourcePermission.getFeatureType()); target.setType(NEW_FEATURE); target.setTerminal(resourcePermission.getTerminal()); + target.setTags(Optional.ofNullable(permission.getTags()) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED))); return target; }).collect(Collectors.toList()); SaasPgroupPermissionRelationService.UpsertPermissionRelationParam upsertPermissionRelationParam = SaasPgroupPermissionRelationService.UpsertPermissionRelationParam.builder() @@ -1543,38 +1545,37 @@ public class RoleServiceImpl extends ServiceImpl return Collections.emptyMap(); } - List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() - .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) - .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .in(CollectionUtils.isNotEmpty(param.getFeatureIds()), SaasPgroupPermissionRelation::getFeatureId, param.getFeatureIds()) - .eq(SaasPgroupPermissionRelation::getType, NEW_FEATURE) - .list(); + List saasPgroupPermissionRelations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder() + .groupIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) + .featureIds(param.getFeatureIds()) + .type(NEW_FEATURE) + .tags(param.getPermissionTags()) + .terminal(param.getTerminal()) + .build()); if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { return Collections.emptyMap(); } - Map resourcePermissions = saasFeatureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() + Map resourcePermissions = saasFeatureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() .ids(Lists.transform(saasPgroupPermissionRelations, SaasPgroupPermissionRelation::getFeatureId)) .build()) .stream() - .map(e -> SaasPermissionRes.builder().id(e.getId()).featureCode(e.getFeatureCode()).build()) - .collect(Collectors.toMap(SaasPermissionRes::getId, Function.identity())); + .collect(Collectors.toMap(ResourcePermission::getId, Function.identity())); - Map> pgroupPermissions = saasPgroupPermissionRelations.stream() - .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId, - Collectors.mapping(SaasPgroupPermissionRelation::getFeatureId, Collectors.toList()))); + Map> pgroupPermissions = saasPgroupPermissionRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId)); return saasPgroupRoleRelations.stream() .map(e -> { - List permissionIds = pgroupPermissions.get(e.getGroupId()); - if (CollectionUtils.isEmpty(permissionIds)) { + List permissions = pgroupPermissions.get(e.getGroupId()); + if (CollectionUtils.isEmpty(permissions)) { return null; } - return permissionIds.stream() - .map(permissionId -> { - SaasPermissionRes saasPermissionRes = resourcePermissions.get(permissionId); - return SaasPermissionWrapper.from(e, saasPermissionRes); + return permissions.stream() + .map(permission -> { + ResourcePermission saasPermissionRes = resourcePermissions.get(permission.getFeatureId()); + return SaasPermissionWrapper.from(e, saasPermissionRes, permission); }) .filter(Objects::nonNull) .collect(Collectors.toList()); @@ -1582,7 +1583,12 @@ public class RoleServiceImpl extends ServiceImpl .filter(Objects::nonNull) .flatMap(Collection::stream) .collect(Collectors.groupingBy(SaasPermissionWrapper::getRoleId, - Collectors.mapping(e -> SaasPermissionRes.builder().id(e.getId()).featureCode(e.getFeatureCode()).build(), + Collectors.mapping(e -> SaasPermissionRes.builder() + .id(e.getId()) + .featureCode(e.getFeatureCode()) + .tags(e.getTags()) + .terminal(e.getTerminal()) + .build(), Collectors.toList()))); } @@ -1602,8 +1608,16 @@ public class RoleServiceImpl extends ServiceImpl private Long roleId; + private Set tags; + + /** + * 资源所属端 + */ + private String terminal; + public static SaasPermissionWrapper from(SaasPgroupRoleRelation saasPgroupRoleRelation, - SaasPermissionRes saasPermissionRes) { + ResourcePermission saasPermissionRes, + SaasPgroupPermissionRelation saasPgroupPermissionRelation) { if (saasPermissionRes == null) { return null; } @@ -1611,6 +1625,8 @@ public class RoleServiceImpl extends ServiceImpl .id(saasPermissionRes.getId()) .featureCode(saasPermissionRes.getFeatureCode()) .roleId(saasPgroupRoleRelation.getRoleId()) + .tags(saasPgroupPermissionRelation.getTags()) + .terminal(saasPermissionRes.getTerminal()) .build(); } } @@ -1660,9 +1676,11 @@ public class RoleServiceImpl extends ServiceImpl } Set newRoleIds = req.stream() - .map(FeatureRoleRelationReq.RelationRoleSettings::getRoleIds) + .map(FeatureRoleRelationReq.RelationRoleSettings::getRoles) .filter(Objects::nonNull) .flatMap(Collection::stream) + .map(FeatureRoleRelationReq.Role::getRoleId) + .filter(Objects::nonNull) .collect(Collectors.toSet()); List featureIds = req.stream() @@ -1694,7 +1712,7 @@ public class RoleServiceImpl extends ServiceImpl for (FeatureRoleRelationReq.RelationRoleSettings item : req) { saasFeatureResourceService.updateFeatureAuthType(item.getFeatureId(), item.getAuthType()); - if (CollectionUtil.isEmpty(item.getRoleIds()) || item.getAuthType() == 0) { + if (CollectionUtil.isEmpty(item.getRoles()) || item.getAuthType() == 0) { saasPgroupPermissionRelationDao.removeByPermissionPointIds(Collections.singletonList(item.getFeatureId())); // 记录操作日志 try { @@ -1703,35 +1721,57 @@ public class RoleServiceImpl extends ServiceImpl log.warn("save operate log error", e); } } else { - List existGroupIds = saasPgroupPermissionRelationDao.queryByFeatureIds(Collections.singletonList(item.getFeatureId())) - .stream().map(SaasPgroupPermissionRelation::getGroupId).collect(Collectors.toList()); + List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.queryByFeatureIds(Collections.singletonList(item.getFeatureId())); + Set existGroupIds = saasPgroupPermissionRelations.stream().map(SaasPgroupPermissionRelation::getGroupId).collect(Collectors.toSet()); - List groupIds = saasPgroupRoleRelationDao.findByRoleIds(item.getRoleIds()) - .stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toList()); - List insertGroupIds = groupIds.stream().filter(role -> !existGroupIds.contains(role)).collect(Collectors.toList()); + List roleIds = item.getRoles().stream() + .map(FeatureRoleRelationReq.Role::getRoleId) + .collect(Collectors.toList()); + List saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(roleIds); + Set groupIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toSet()); List deleteGroupIds = existGroupIds.stream().filter(role -> !groupIds.contains(role)).collect(Collectors.toList()); + + // 这里可能会导致featureId、groupId相同的记录有多条,原因是不同的角色可能有相同的权限集,原来使用的是list来解析新增的数据 + List insert = saasPgroupRoleRelations.stream() + .filter(e -> !existGroupIds.contains(e.getGroupId())) + .collect(Collectors.toList()); + Map roles = item.getRoles().stream() + .collect(Collectors.toMap(FeatureRoleRelationReq.Role::getRoleId, Function.identity(), (f, s) -> f)); + + Map existFeatureGroups = saasPgroupPermissionRelations.stream() + .collect(Collectors.toMap(SaasPgroupPermissionRelation::getGroupId, Function.identity())); + // 记录操作日志 try { - saveOperateLog(item.getFeatureId(), operatorId, item.getRoleIds(), req); + saveOperateLog(item.getFeatureId(), operatorId, roleIds, req); } catch (Exception e) { log.warn("save operate log error", e); } // 新增的 - if (CollectionUtils.isNotEmpty(insertGroupIds)) { - List insertRelation = new ArrayList<>(); - insertGroupIds.forEach(groupId -> { - SaasPgroupPermissionRelation relation = new SaasPgroupPermissionRelation(); - relation.setFeatureId(item.getFeatureId()); - relation.setGroupId(groupId); - relation.setCreateBy(operatorId); - relation.setFeatureType(item.getFeatureType()); - relation.setType(NEW_FEATURE); - relation.setTerminal(item.getTerminal()); - insertRelation.add(relation); - }); + if (CollectionUtils.isNotEmpty(insert)) { + + Set insertRelation = insert.stream() + .map(group -> { + FeatureRoleRelationReq.Role role = roles.get(group.getRoleId()); + + SaasPgroupPermissionRelation relation = new SaasPgroupPermissionRelation(); + relation.setFeatureId(item.getFeatureId()); + relation.setGroupId(group.getGroupId()); + relation.setCreateBy(operatorId); + relation.setFeatureType(item.getFeatureType()); + relation.setType(NEW_FEATURE); + relation.setTerminal(item.getTerminal()); + relation.setTags(Optional.ofNullable(role.getTags()) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED))); + return relation; + }) + .collect(Collectors.toSet()); saasPgroupPermissionRelationDao.saveBatch(insertRelation); } + // 都一起更新,以后可能会新增其他字段需要更新,让代码简单。也能看到更新时间 + updatePgroupPermissionRelation(operatorId, item, saasPgroupRoleRelations, existFeatureGroups, roles); + // 删除的 if (CollectionUtils.isNotEmpty(deleteGroupIds)) { saasPgroupPermissionRelationDao.removeByFeatureIdAndGroupIds(item.getFeatureId(), deleteGroupIds, operatorId); @@ -1773,6 +1813,40 @@ public class RoleServiceImpl extends ServiceImpl .build()); } + private void updatePgroupPermissionRelation(Long operatorId, + FeatureRoleRelationReq.RelationRoleSettings item, + List saasPgroupRoleRelations, + Map existFeatureGroups, + Map roles) { + List updateRelation = saasPgroupRoleRelations.stream() + .map(e -> { + SaasPgroupPermissionRelation old = existFeatureGroups.get(e.getGroupId()); + if (Objects.isNull(old)) { + return null; + } + FeatureRoleRelationReq.Role role = roles.get(e.getRoleId()); + SaasPgroupPermissionRelation relation = new SaasPgroupPermissionRelation(); + relation.setId(old.getId()); + relation.setFeatureId(item.getFeatureId()); + relation.setGroupId(e.getGroupId()); + relation.setCreateBy(operatorId); + relation.setFeatureType(item.getFeatureType()); + relation.setType(NEW_FEATURE); + relation.setTerminal(item.getTerminal()); + relation.setTags(Optional.ofNullable(role.getTags()) + .orElseGet(() -> Sets.newHashSet(RolePermissionTagEnum.JOINED))); + return relation; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(updateRelation)) { + return; + } + + saasPgroupPermissionRelationDao.updateBatchById(updateRelation); + } + @Override public FeatureRoleRelationResp queryFeatureRoleRelation(Long featureId) { SaasFeatureResource featureResource = saasFeatureResourceService.featureResourceById(featureId); @@ -1792,12 +1866,17 @@ public class RoleServiceImpl extends ServiceImpl return resp; } - private List validPermission(Set permissionIds) { - if (CollectionUtils.isEmpty(permissionIds)) { + private List validPermission(Set permissions) { + if (CollectionUtils.isEmpty(permissions)) { return Collections.emptyList(); } + + List permissionIds = permissions.stream() + .map(SaveOrUpdateRoleVO.Permission::getPermissionId) + .collect(Collectors.toList()); + List resourcePermissions = saasFeatureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder() - .ids(Lists.newArrayList(permissionIds)) + .ids(permissionIds) .build()); if (permissionIds.size() != resourcePermissions.size()) { permissionIds.removeAll(resourcePermissions.stream().map(ResourcePermission::getId).collect(Collectors.toSet())); @@ -1848,41 +1927,45 @@ public class RoleServiceImpl extends ServiceImpl return Collections.emptyMap(); } - List saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.lambdaQuery() - .in(SaasPgroupPermissionRelation::getGroupId, Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) - .in(CollectionUtils.isNotEmpty(param.getFeatureIds()), SaasPgroupPermissionRelation::getFeatureId, param.getFeatureIds()) - .eq(SaasPgroupPermissionRelation::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .eq(SaasPgroupPermissionRelation::getType, OLD_FEATURE) - .list(); + List saasPgroupPermissionRelations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder() + .groupIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getGroupId)) + .featureIds(param.getFeatureIds()) + .type(OLD_FEATURE) + .tags(param.getPermissionTags()) + .build()); if (CollectionUtils.isEmpty(saasPgroupPermissionRelations)) { return Collections.emptyMap(); } List featureIds = Lists.transform(saasPgroupPermissionRelations, SaasPgroupPermissionRelation::getFeatureId); - Map resourcePermissions = saasFeatureDao.listByIds(featureIds).stream() - .map(e -> SaasPermissionRes.builder() - .id(e.getId()) - .featureCode(e.getFeatureCode()) - .terminal(e.getTerminal()) - .build()) - .collect(Collectors.toMap(SaasPermissionRes::getId, Function.identity())); + Map resourcePermissions = saasFeatureDao.listByIds(featureIds).stream() + .collect(Collectors.toMap(SaasFeature::getId, Function.identity())); - Map> pgroupPermissions = saasPgroupPermissionRelations.stream() - .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId, - Collectors.mapping(SaasPgroupPermissionRelation::getFeatureId, Collectors.toList()))); + Map> pgroupPermissions = saasPgroupPermissionRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId)); return saasPgroupRoleRelations.stream() .map(e -> { - List permissionIds = pgroupPermissions.get(e.getGroupId()); - if (CollectionUtils.isEmpty(permissionIds)) { + List permissions = pgroupPermissions.get(e.getGroupId()); + if (CollectionUtils.isEmpty(permissions)) { return null; } - return permissionIds.stream() - .map(permissionId -> { - SaasPermissionRes saasPermissionRes = resourcePermissions.get(permissionId); - return SaasPermissionWrapper.from(e, saasPermissionRes); + return permissions.stream() + .map(permission -> { + SaasFeature saasFeature = resourcePermissions.get(permission.getFeatureId()); + + if (Objects.isNull(saasFeature)) { + return null; + } + return SaasPermissionWrapper.builder() + .id(saasFeature.getId()) + .featureCode(saasFeature.getFeatureCode()) + .roleId(e.getRoleId()) + .terminal(saasFeature.getTerminal()) + .tags(permission.getTags()) + .build(); }) .filter(Objects::nonNull) .collect(Collectors.toList()); @@ -1937,6 +2020,7 @@ public class RoleServiceImpl extends ServiceImpl .featureId(e.getFeatureId()) .type(e.getType()) .featureType(e.getFeatureType()) + .tags(e.getTags()) .build(), Collectors.toList()))); } @@ -1998,8 +2082,14 @@ public class RoleServiceImpl extends ServiceImpl private void saveOperateLog4RoleBindFeatureResource(SaveOrUpdateRoleVO saveOrUpdateRole) { SaasRole saasRole = saasRoleDao.getById(saveOrUpdateRole.getId()); List uniCodes = null; - if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getPermissionIds())) { - uniCodes = saasFeatureResourceDao.lambdaQuery().in(BaseEntity::getId, saveOrUpdateRole.getPermissionIds()).list().stream().map(SaasFeatureResource::getUniCode).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(saveOrUpdateRole.getPermissions())) { + uniCodes = saasFeatureResourceDao.lambdaQuery().in(BaseEntity::getId, saveOrUpdateRole.getPermissions().stream() + .map(SaveOrUpdateRoleVO.Permission::getPermissionId) + .collect(Collectors.toList())) + .list() + .stream() + .map(SaasFeatureResource::getUniCode) + .collect(Collectors.toList()); } RelationOperateLogRoleBindResourceDO operateAfter = RelationOperateLogRoleBindResourceDO.builder() @@ -2047,6 +2137,13 @@ public class RoleServiceImpl extends ServiceImpl */ private Integer featureType; + /** + * 权限点标签: + * 在职:JOINED + * 离场:LEAVE + */ + private Set tags; + public static SaasPermissionRelationWrapper from(SaasPgroupRoleRelation saasPgroupRoleRelation, SaasPgroupPermissionRelation permissionRelation) { if (permissionRelation == null) { @@ -2057,6 +2154,7 @@ public class RoleServiceImpl extends ServiceImpl .featureId(permissionRelation.getFeatureId()) .type(permissionRelation.getType()) .featureType(permissionRelation.getFeatureType()) + .tags(permissionRelation.getTags()) .build(); } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java index 9605bd48..7331e639 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasFeatureResourceServiceImpl.java @@ -15,6 +15,7 @@ import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.FeatureResourceStatus; import cn.axzo.tyr.client.common.enums.FeatureResourceType; import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum; +import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.model.enums.DelegatedType; import cn.axzo.tyr.client.model.permission.SaasFeatureBO; import cn.axzo.tyr.client.model.req.DeleteFeatureResourceReq; @@ -61,6 +62,7 @@ import cn.hutool.core.lang.Pair; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -249,7 +251,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl> listRoles(DetailFeatureResourceReq detailFeatureResourceReq, + private Map> listRoles(DetailFeatureResourceReq detailFeatureResourceReq, List descendants) { if (CollectionUtils.isEmpty(descendants) || BooleanUtils.isNotTrue(detailFeatureResourceReq.getNeedRole())) { return Collections.emptyMap(); @@ -257,6 +259,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl relations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder() .featureIds(Lists.transform(descendants, SaasFeatureResource::getId)) + .tags(detailFeatureResourceReq.getTags()) .build()); if (CollectionUtils.isEmpty(relations)) { return Collections.emptyMap(); @@ -269,16 +272,16 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl roles = roleService.list(ListRoleReq.builder() + Map> groupRoleMap = saasPgroupRoleRelations.stream() + .collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId, + Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList()))); + + Map roleMap = roleService.list(ListRoleReq.builder() .roleIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getRoleId)) .build()) .stream() .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); - Map> groupRoleMap = saasPgroupRoleRelations.stream() - .collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId, - Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList()))); - return relations.stream() .map(e -> { List roleIds = groupRoleMap.get(e.getGroupId()); @@ -287,8 +290,15 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl FeatureResourceTreeNode.Role.builder() + .roleId(f) + .tags(e.getTags()) + .roleType(Optional.ofNullable(roleMap.get(f)) + .map(role -> RoleTypeEnum.getRoleType(role.getRoleType())) + .orElse(null)) + .build()) .filter(Objects::nonNull) + .distinct() .collect(Collectors.toList())); }) .filter(Objects::nonNull) @@ -300,23 +310,29 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl descendants = featureResourceDao.lambdaQuery() + + LambdaQueryChainWrapper wrapper = featureResourceDao.lambdaQuery() .eq(BaseEntity::getIsDelete,0) - .eq(ObjectUtil.isNotNull(param.getFeatureType()), SaasFeatureResource::getFeatureType, param.getFeatureType()) - .apply("FIND_IN_SET('" + param.getFeatureId() + "', path)") - .list(); + .eq(ObjectUtil.isNotNull(param.getFeatureType()), SaasFeatureResource::getFeatureType, param.getFeatureType()); + + if (BooleanUtils.isTrue(param.getNeedChildren())) { + wrapper.apply("FIND_IN_SET('" + param.getFeatureId() + "', path)"); + } else { + wrapper.eq(BaseEntity::getId, param.getFeatureId()); + } + + List descendants = wrapper.list(); + if (CollectionUtil.isEmpty(descendants)) { return null; } - Map> roles = listRoles(param, descendants); + Map> roles = listRoles(param, descendants); List treeList = TreeUtil.buildTree(descendants.stream() .map(e -> { FeatureResourceTreeNode featureResourceTreeNode = SaasFeatureResourceConvert.INSTANCE.convert(e); - featureResourceTreeNode.setRoleIds(Optional.ofNullable(roles.get(featureResourceTreeNode.getId())) - .map(f -> f.stream().map(SaasRoleRes::getId).collect(Collectors.toSet())) - .orElse(null)); + featureResourceTreeNode.setRoles(roles.get(featureResourceTreeNode.getId())); return featureResourceTreeNode; }) .sorted(Comparator.comparing(FeatureResourceDTO::getDisplayOrder)) @@ -324,7 +340,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl allUniCodes = descendants.stream().map(SaasFeatureResource::getUniCode).filter(StringUtils::isNotBlank).collect(Collectors.toList()); - fillPageElement2PageFeatureResource(treeList, allUniCodes); + fillPageElement2PageFeatureResource(treeList, allUniCodes, param); return featureResourceTreeNode; } @@ -803,7 +819,13 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl featureResourceTreeNodes, List allUniCodes) { + private void fillPageElement2PageFeatureResource(List featureResourceTreeNodes, + List allUniCodes, + DetailFeatureResourceReq detailFeatureResourceReq) { + if (BooleanUtils.isNotTrue(detailFeatureResourceReq.getNeedPageElement())) { + return; + } + Map> uniCodeElementsMap = saasPageElementService.getByTerminalAndUniCodes(featureResourceTreeNodes.get(0).getTerminal(), allUniCodes) .stream().collect(Collectors.groupingBy(PageElementBasicDTO::getUniCode)); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java index a9a68965..4ef95240 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPageElementServiceImpl.java @@ -318,9 +318,15 @@ public class SaasPageElementServiceImpl extends ServiceImpl workspaceOuPairs = Lists.newArrayList(IdentityAuthReq.WorkspaceOuPair.builder() + .ouId(request.getOuId()) + .workspaceId(request.getWorkspaceId()) + .tags(request.getTags()) + .build()); + IdentityAuthRes res = tyrSaasAuthService.findIdentityAuthMix(IdentityAuthReq.builder() .personId(request.getPersonId()) - .workspaceOusPairs(Lists.newArrayList(IdentityAuthReq.WorkspaceOuPair.builder().ouId(request.getOuId()).workspaceId(request.getWorkspaceId()).build())) + .workspaceOusPairs(workspaceOuPairs) .terminal(Lists.newArrayList(request.getTerminal())) .featureCode(resultRelations.stream().map(SaasPageElementFeatureResourceRelation::getPageElementCode).collect(Collectors.toSet())) .build()); diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java index 92a3a2e3..dd979ced 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/service/impl/SaasPgroupPermissionRelationServiceImpl.java @@ -4,8 +4,8 @@ import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum; import cn.axzo.foundation.dao.support.converter.PageConverter; import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper; import cn.axzo.foundation.page.PageResp; -import cn.axzo.framework.auth.domain.TerminalInfo; import cn.axzo.tyr.client.common.enums.FeatureResourceType; +import cn.axzo.tyr.client.model.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.server.repository.dao.SaasPgroupPermissionRelationDao; import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; @@ -26,7 +26,9 @@ import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -71,6 +73,24 @@ public class SaasPgroupPermissionRelationServiceImpl if (CollectionUtils.isNotEmpty(deleteList)) { saasPgroupPermissionRelationDao.removeByIds(deleteList.stream().map(SaasPgroupPermissionRelation::getId).sorted().collect(Collectors.toList())); } + + Map existFeatureGroups = exists.stream() + .collect(Collectors.toMap(e -> e.getFeatureId() + "_" + e.getGroupId(), Function.identity())); + + List updates = relations.stream() + .map(e -> { + SaasPgroupPermissionRelation old = existFeatureGroups.get(e.getFeatureId() + "_" + e.getGroupId()); + if (Objects.isNull(old)) { + return null; + } + e.setId(old.getId()); + return e; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(updates)) { + saasPgroupPermissionRelationDao.updateBatchById(updates); + } } @Override @@ -84,10 +104,15 @@ public class SaasPgroupPermissionRelationServiceImpl // 目前只有新版本的CMS端产品配置时才冗余了terminal if (Objects.equals(NEW_FEATURE, param.getType()) && StringUtils.hasLength(param.getTerminal())) { - TerminalInfo terminalInfo = new TerminalInfo(param.getTerminal()); - if (terminalInfo.isCMS()) { - wrapper.eq("terminal", param.getTerminal()); - } + wrapper.eq("terminal", param.getTerminal()); + } + + if (CollectionUtils.isNotEmpty(param.getTags())) { + wrapper.and(j -> { + for (RolePermissionTagEnum tag : param.getTags()) { + j.or(k -> k.apply("json_contains(tags, '\"" + tag + "\"')")); + } + }); } IPage page = this.page(PageConverter.toMybatis(param, SaasPgroupPermissionRelation.class), wrapper); 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 c79a9a50..aaa71310 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 @@ -1,20 +1,17 @@ package cn.axzo.tyr.server.service.impl; -import cn.axzo.apollo.workspace.common.enums.TableIsDeleteEnum; import cn.axzo.basics.common.BeanMapper; import cn.axzo.framework.domain.ServiceException; import cn.axzo.pokonyan.util.TraceSupplier; import cn.axzo.thrones.client.saas.ServicePkgClient; import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct; import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes; -import cn.axzo.tyr.client.common.enums.FeatureResourceAuthType; import cn.axzo.tyr.client.common.enums.RoleTypeEnum; import cn.axzo.tyr.client.common.enums.WorkspaceJoinType; 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.enums.RolePermissionTagEnum; import cn.axzo.tyr.client.model.req.CheckIdentityPermissionReq; -import cn.axzo.tyr.client.model.req.FeatureIdPair; import cn.axzo.tyr.client.model.req.IdentityAuthReq; import cn.axzo.tyr.client.model.req.ListIdentityFromPermissionReq; import cn.axzo.tyr.client.model.req.ListPermissionFromFeatureReq; @@ -23,10 +20,7 @@ import cn.axzo.tyr.client.model.req.ListPermissionFromRoleGroupReq; import cn.axzo.tyr.client.model.req.ListRoleReq; import cn.axzo.tyr.client.model.req.OUWorkspacePair; import cn.axzo.tyr.client.model.req.PageElementFeatureResourceRelationReq; -import cn.axzo.tyr.client.model.req.PagePgroupPermissionRelationReq; import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq; -import cn.axzo.tyr.client.model.req.PermissionCheckReq; -import cn.axzo.tyr.client.model.req.QueryPermissionByIdsReq; import cn.axzo.tyr.client.model.req.WorkspacePermissionIdentityReq; import cn.axzo.tyr.client.model.res.IdentityAuthRes; import cn.axzo.tyr.client.model.res.ListIdentityFromPermissionResp; @@ -34,37 +28,26 @@ import cn.axzo.tyr.client.model.res.ListPermissionFromRoleGroupResp; import cn.axzo.tyr.client.model.res.QueryIdentityByPermissionResp; import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp; import cn.axzo.tyr.client.model.res.SaasRoleRes; -import cn.axzo.tyr.client.model.res.SimplePermissionPointResp; import cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserV2DTO; import cn.axzo.tyr.client.model.roleuser.req.ListRoleUserRelationParam; import cn.axzo.tyr.server.model.FilterRoleAuth; -import cn.axzo.tyr.server.model.PermissionCacheKey; -import cn.axzo.tyr.server.repository.dao.SaasFeatureDao; -import cn.axzo.tyr.server.repository.dao.SaasPgroupRoleRelationDao; import cn.axzo.tyr.server.repository.entity.ProductFeatureInfo; import cn.axzo.tyr.server.repository.entity.ProductFeatureQuery; import cn.axzo.tyr.server.repository.entity.RolePermission; import cn.axzo.tyr.server.repository.entity.SaasFeature; import cn.axzo.tyr.server.repository.entity.SaasFeatureResource; import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelation; -import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelation; -import cn.axzo.tyr.server.repository.entity.SaasPgroupRoleRelation; -import cn.axzo.tyr.server.repository.entity.SaasProductModuleFeatureRelation; -import cn.axzo.tyr.server.repository.entity.SaasRole; import cn.axzo.tyr.server.repository.entity.SaasRoleGroup; -import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation; import cn.axzo.tyr.server.repository.entity.SaasRoleWithUser; import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper; 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.PermissionTagService; import cn.axzo.tyr.server.service.ProductPermissionCacheService; import cn.axzo.tyr.server.service.RolePermissionCacheService; import cn.axzo.tyr.server.service.RoleService; import cn.axzo.tyr.server.service.SaasFeatureResourceService; import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService; -import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationService; import cn.axzo.tyr.server.service.SaasRoleGroupService; import cn.axzo.tyr.server.service.SaasRoleUserRelationService; import cn.axzo.tyr.server.service.TyrSaasAuthService; @@ -75,8 +58,6 @@ import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.utils.LogUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.StopWatch; -import cn.hutool.core.lang.Pair; -import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import com.google.common.collect.Lists; @@ -88,11 +69,11 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; 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; import org.springframework.util.CollectionUtils; @@ -131,34 +112,21 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { private final TyrSaasAuthMapper saasAuthMapper; private final RoleService roleService; - private final RoleUserService roleUserService; private final ServicePkgClient servicePkgClient; @Qualifier("authExecutor") @Autowired private Executor executor; - private final ProductFeatureRelationService productFeatureRelationService; private final PermissionPointService permissionPointService; - private final PermissionCacheService permissionCacheService; private final SaasRoleGroupService roleGroupService; private final SaasRoleUserRelationService saasRoleUserRelationService; - private final SaasFeatureDao saasFeatureDao; private final WorkspaceProductService workspaceProductService; private final SaasFeatureResourceService saasFeatureResourceService; private final SaasPageElementFeatureResourceRelationService saasPageElementFeatureResourceRelationService; - private final SaasPgroupPermissionRelationService saasPgroupPermissionRelationService; private final FeatureCodeUtil featureCodeUtil; - private final SaasPgroupRoleRelationDao saasPgroupRoleRelationDao; private final RolePermissionCacheService rolePermissionCacheService; private final SaasRoleUserRelationMapper saasRoleUserRelationMapper; - - @Value("${permission.from.db:true}") - private boolean PERMISSION_FROM_DB; - - @Override - public boolean permissionFromDB() { - return BooleanUtil.isTrue(PERMISSION_FROM_DB); - } + private final PermissionTagService permissionTagService; /** * 通过身份查询人员权限 @@ -451,6 +419,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { * 指定端的权限 */ private String terminal; + + private Set tags; } private Set checkFeatureCodes(ListPermissionUser param) { @@ -526,17 +496,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { @Override public ListIdentityFromPermissionResp listIdentityFromPermission(ListIdentityFromPermissionReq req) { - - if (this.permissionFromDB()) { - return listIdentityFromPermissionFromDB(req); - } - - try { - return listIdentityFromPermissionResp(req); - } catch (Exception ex) { - log.error("查询权限异常,执行降级处理"); - return listIdentityFromPermissionFromDB(req); - } + return listIdentityFromPermissionResp(req); } private ListIdentityFromPermissionResp listIdentityFromPermissionResp(ListIdentityFromPermissionReq req) { @@ -546,6 +506,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .ouId(req.getOuId()) .workspaceId(req.getWorkspaceId()) .terminal(req.getTerminal()) + .tags(req.getTags()) .build(); List userVOS = listPermissionUser(listPermissionUser); @@ -562,7 +523,12 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } private Set resolvePermissionAdminRole(List adminRoles, - List productPermissions) { + List productPermissions, + ListPermissionUser listPermissionUser) { + if (!CollectionUtils.isEmpty(listPermissionUser.getTags()) && !listPermissionUser.getTags().contains(RolePermissionTagEnum.JOINED)) { + return Collections.emptySet(); + } + Set cooperateTypes = productPermissions.stream() .map(ProductPermissionCacheService.PermissionDTO::getCooperateType) .collect(Collectors.toSet()); @@ -573,10 +539,67 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .collect(Collectors.toSet()); } - private Set resolvePermissionNormalRole(ListPermissionUser req, + private Set resolvePermissionAdminLeaveRole(List adminRoles, + List productPermissions, + ListPermissionUser listPermissionUser, + Set featureIds, + Map> allRolePermissionMap) { + + if (CollectionUtil.isEmpty(adminRoles)) { + log.info("no admin roles"); + return Collections.emptySet(); + } + + // 因为tag != LEAVE的权限,管理员的权限直接是产品匹配的权限 + if (CollectionUtils.isEmpty(listPermissionUser.getTags()) || !listPermissionUser.getTags().contains(RolePermissionTagEnum.LEAVE)) { + return Collections.emptySet(); + } + + Map> adminRolePermissionMap = adminRoles.stream() + .filter(e -> allRolePermissionMap.containsKey(e.getId())) + .collect(Collectors.toMap(SaasRoleRes::getId, e -> allRolePermissionMap.get(e.getId()))); + + Set adminRoleIds = adminRolePermissionMap.entrySet().stream() + .filter(e -> !CollectionUtils.isEmpty(e.getValue())) + .filter(e -> e.getValue().stream().anyMatch(p -> featureIds.contains(p.getFeatureId()))) + .filter(e -> StringUtils.isBlank(listPermissionUser.getTerminal()) + || e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), listPermissionUser.getTerminal()))) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + Map adminRoleMap = adminRoles.stream() + .filter(e -> adminRoleIds.contains(e.getId())) + .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); + + Map> featureCodeCooperateTypeMap = productPermissions.stream() + .collect(Collectors.groupingBy(ProductPermissionCacheService.PermissionDTO::getFeatureCode, + Collectors.mapping(ProductPermissionCacheService.PermissionDTO::getCooperateType, Collectors.toSet()))); + return adminRolePermissionMap.entrySet().stream() + .filter(e -> { + SaasRoleRes saasRoleRes = adminRoleMap.get(e.getKey()); + if (Objects.isNull(saasRoleRes)) { + return false; + } + + return e.getValue().stream() + .filter(f -> StringUtils.isBlank(listPermissionUser.getTerminal()) + || e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), listPermissionUser.getTerminal()))) + .anyMatch(f -> { + Set productCooperateTypes = featureCodeCooperateTypeMap.get(f.getFeatureCode()); + if (CollectionUtils.isEmpty(productCooperateTypes)) { + return false; + } + return productCooperateTypes.contains(String.valueOf(saasRoleRes.getProductUnitType())); + }); + }) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + } + + private Set resolvePermissionNormalRole(List allRoles, + ListPermissionUser req, List productPermissions, Set featureIds, - List allRoles) { + Map> allRolePermissionMap) { List normalRoles = allRoles.stream() .filter(e -> !RoleTypeEnum.isAdmin(e.getRoleType())) @@ -586,46 +609,35 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptySet(); } - RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() - .roleIds(normalRoles.stream().map(SaasRoleRes::getId).collect(Collectors.toSet())) - .featureCodes(productPermissions.stream() - .map(ProductPermissionCacheService.PermissionDTO::getFeatureCode) - .collect(Collectors.toSet())) - .build(); - Map> normalRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam); - - Set normalRoleIds = normalRolePermissionMap.entrySet().stream() - .filter(e -> !CollectionUtils.isEmpty(e.getValue())) - .filter(e -> e.getValue().stream().anyMatch(p -> featureIds.contains(p.getFeatureId()))) - .filter(e -> StringUtils.isBlank(req.getTerminal()) - || e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal()))) - .map(Map.Entry::getKey) - .collect(Collectors.toSet()); Map normalRoleMap = normalRoles.stream() - .filter(e -> normalRoleIds.contains(e.getId())) .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); Map> featureCodeCooperateTypeMap = productPermissions.stream() .collect(Collectors.groupingBy(ProductPermissionCacheService.PermissionDTO::getFeatureCode, Collectors.mapping(ProductPermissionCacheService.PermissionDTO::getCooperateType, Collectors.toSet()))); - return normalRolePermissionMap.entrySet().stream() - .filter(e -> { - SaasRoleRes saasRoleRes = normalRoleMap.get(e.getKey()); - if (Objects.isNull(saasRoleRes)) { - return false; - } - return e.getValue().stream() - .filter(f -> StringUtils.isBlank(req.getTerminal()) - || e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal()))) - .anyMatch(f -> { - Set productCooperateTypes = featureCodeCooperateTypeMap.get(f.getFeatureCode()); - if (CollectionUtils.isEmpty(productCooperateTypes)) { - return false; - } - return productCooperateTypes.contains(String.valueOf(saasRoleRes.getProductUnitType())); - }); - }) + Map> normalRolePermissionMap = normalRoleMap.entrySet().stream() + .filter(e -> allRolePermissionMap.containsKey(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, e -> allRolePermissionMap.get(e.getKey()))); + + return normalRolePermissionMap.entrySet().stream() + .filter(e -> !CollectionUtils.isEmpty(e.getValue())) + .filter(e -> e.getValue().stream().anyMatch(p -> featureIds.contains(p.getFeatureId()))) + .filter(e -> StringUtils.isBlank(req.getTerminal()) + || e.getValue().stream().anyMatch(p -> Objects.equals(p.getTerminal(), req.getTerminal()))) + .filter(e -> e.getValue().stream() + .anyMatch(f -> { + SaasRoleRes saasRoleRes = normalRoleMap.get(e.getKey()); + if (Objects.isNull(saasRoleRes)) { + return false; + } + + Set productCooperateTypes = featureCodeCooperateTypeMap.get(f.getFeatureCode()); + if (CollectionUtils.isEmpty(productCooperateTypes)) { + return false; + } + return productCooperateTypes.contains(String.valueOf(saasRoleRes.getProductUnitType())); + })) .map(Map.Entry::getKey) .collect(Collectors.toSet()); } @@ -646,22 +658,31 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { List allRoles = roleService.list(ListRoleReq.builder() .roleIds(Lists.newArrayList(allRoleIds)) .build()); - if (CollectionUtils.isEmpty(allRoles)) { return Collections.emptyList(); } + RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() + .roleIds(allRoleIds) + .featureCodes(productPermissions.stream() + .map(ProductPermissionCacheService.PermissionDTO::getFeatureCode) + .collect(Collectors.toSet())) + .build(); + Map> allRolePermissionMap = rolePermissionCacheService.list(listRolePermissionParam); + //超管和管理员 List adminRoles = allRoles.stream() .filter(e -> RoleTypeEnum.isAdmin(e.getRoleType())) .collect(Collectors.toList()); - Set adminPermissionRoleIds = resolvePermissionAdminRole(adminRoles, productPermissions); - Set normalPermissionRoleIds = resolvePermissionNormalRole(req, productPermissions, featureIds, allRoles); + Set adminPermissionRoleIds = resolvePermissionAdminRole(adminRoles, productPermissions, req); + Set normalPermissionRoleIds = resolvePermissionNormalRole(allRoles, req, productPermissions, featureIds, allRolePermissionMap); + Set adminLeavePermissionRoleIds = resolvePermissionAdminLeaveRole(adminRoles, productPermissions, req, featureIds, allRolePermissionMap); Set roleIds = Sets.newHashSet(); roleIds.addAll(adminPermissionRoleIds); roleIds.addAll(normalPermissionRoleIds); + roleIds.addAll(adminLeavePermissionRoleIds); if (CollectionUtil.isEmpty(roleIds)) { log.warn("no role matched product unit types"); @@ -683,6 +704,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptyList(); } + Map personTags = resolveTags(req, saasRoleUsers); + Set superAdminRoleIds = adminRoles.stream() .filter(r -> RoleTypeEnum.SUPER_ADMIN.getValue().equals(r.getRoleType())) .map(SaasRoleRes::getId) @@ -694,6 +717,29 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { // copy原代码 for (SaasRoleUserV2DTO relation : saasRoleUsers) { SaasRoleUserV2DTO.SaasRoleUser saasRoleUser = relation.getSaasRoleUser(); + + // 如果用户在岗位那边的状态没有当前权限点的标签的权限,则需要过滤掉 + PermissionTagService.ResolvePermissionDTO personTag = personTags.get(saasRoleUser.getPersonId()); + if (CollectionUtils.isEmpty(req.getTags()) + && Objects.nonNull(personTag) + && !CollectionUtils.isEmpty(personTag.getTags())) { + + List permissionDTOS = allRolePermissionMap.get(relation.getRoleId()); + + if (CollectionUtils.isEmpty(permissionDTOS)) { + continue; + } + + boolean matchedTags = permissionDTOS.stream() + .anyMatch(permission -> permission.getTags() + .stream() + .anyMatch(tag -> !Sets.intersection(permission.getTags(), personTag.getTags()).isEmpty())); + + if (BooleanUtils.isNotTrue(matchedTags)) { + continue; + } + } + String key = KeyUtil.buildKeyBySeparator(saasRoleUser.getOuId(), saasRoleUser.getIdentityId(), saasRoleUser.getIdentityType()); ListIdentityFromPermissionResp.UserVO user = distinctMap.get(key); if (user == null) { @@ -714,6 +760,24 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Lists.newArrayList(distinctMap.values()); } + private Map resolveTags(ListPermissionUser req, List saasRoleUsers) { + // 如果没有指定标签,需要根据查询出来的用户去找到当前的状态来过滤权限 + if (!CollectionUtils.isEmpty(req.getTags())) { + return Collections.emptyMap(); + } + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(saasRoleUsers.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(req.getWorkspaceId()) + .ouId(req.getOuId()) + .personId(e.getSaasRoleUser().getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + return permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(PermissionTagService.ResolvePermissionDTO::getPersonId, Function.identity())); + } + @Override public List batchListIdentityFromPermission(List reqList) { //异步处理 @@ -742,29 +806,57 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } + private void assembleTag(IdentityAuthReq req) { + + if (CollectionUtils.isEmpty(req.getWorkspaceOusPairs())) { + return; + } + + List needResolveTags = req.getWorkspaceOusPairs().stream() + .filter(e -> CollectionUtils.isEmpty(e.getTags())) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(needResolveTags)) { + return; + } + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(needResolveTags.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(req.getPersonId()) + .build()) + .collect(Collectors.toList())) + .build(); + Map resolvePermissions = permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); + + req.getWorkspaceOusPairs().forEach(e -> { + if (!CollectionUtils.isEmpty(e.getTags())) { + return; + } + + PermissionTagService.ResolvePermissionDTO resolvePermissionDTO = resolvePermissions.get(e.buildOuWorkspaceKey()); + if (Objects.isNull(resolvePermissionDTO)) { + return; + } + + e.setTags(resolvePermissionDTO.getTags()); + }); + } @Override public IdentityAuthRes findIdentityAuthMix(IdentityAuthReq req) { - List permissions = null; - //不走缓存的情况:关闭缓存开关 - 缓存临时禁用 - 请求指明不走缓存 - 角色预览操作 + + assembleTag(req); + //请求参数去重: ou-workspace req.distinctOUWorkspacePair(); req.setFeatureCode(featureCodeUtil.resolveFeatureCode(req.getFeatureCode())); - - boolean notUseCache = !req.isUseCache() - || CollectionUtil.isNotEmpty(req.getSpecifyRoleIds()) - || permissionCacheService.cacheDisable( - PermissionCacheKey.builder() - .personId(req.getPersonId()) - .identityId(req.getIdentityId()) - .identityType(req.getIdentityType()) - .build()); - if (notUseCache) { - permissions = findIdentityPermission(req); - } else { - permissions = findIdentityPermissionFromCache(req); - } + // 原来基于用户的缓存去掉,1、因为数据不实时更新,2、新的缓存性能已经够好了,且运行了几个月,3、新的换成有异常有做降级使用db处理 + List permissions = findIdentityAuthV2(req).getPermissions(); IdentityAuthRes result = new IdentityAuthRes(); result.setIdentity(req.getIdentityId()); @@ -806,71 +898,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return result; } - private List findIdentityPermission(IdentityAuthReq req) { - - if (this.permissionFromDB()) { - return findIdentityAuth(req).getPermissions(); - } - - try { - return findIdentityAuthV2(req).getPermissions(); - } catch (Exception ex) { - log.error("查询权限异常,执行降级处理,", ex); - return findIdentityAuth(req).getPermissions(); - } - } - - private List findIdentityPermissionFromCache(IdentityAuthReq req) { - List permissions = new ArrayList<>(); - List needQueryPairs = new ArrayList<>(); - - //从缓存取权限,并记录缓存中没有的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)) { - //有需要从数据库查询的数据 - 走原查询逻辑 并缓存结果 - req.setWorkspaceOusPairs(needQueryPairs); - List authPermission = findIdentityPermission(req); - permissions.addAll(authPermission); - //缓存结果 - 无权限的缓存空权限对象 - Map permissionMap = authPermission.stream() - .collect(Collectors.toMap(p -> p.getOuId() + "-" + p.getWorkspaceId(), Function.identity())); - needQueryPairs.forEach(p -> { - IdentityAuthRes.WorkspacePermission permission = permissionMap.getOrDefault(p.getOuId() + "-" + p.getWorkspaceId(), - IdentityAuthRes.WorkspacePermission.builder()//空权限对象 - .ouId(p.getOuId()) - .workspaceId(p.getWorkspaceId()) - .isSuperAdmin(false) - .permissionPoint(Collections.emptyList()) - .build()); - - permissionCacheService.cachePermission(PermissionCacheKey.builder() - .personId(req.getPersonId()) - .identityId(req.getIdentityId()) - .identityType(req.getIdentityType()) - .ouId(p.getOuId()) - .workspaceId(p.getWorkspaceId()) - .build(), permission); - }); - } - - return permissions; - } - @Override public List listAuthByResourceAndRoleGroup(ListPermissionFromRoleGroupReq listPermissionFromRoleGroupReq) { //确定角色group_id: code对应角色组及其下级 @@ -890,16 +917,59 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { if (!listPermissionFromRoleGroupReq.getFindFeatureInfo()) { return permissionInfo; } + + Map personPermissionTags = resolveTags(permissionInfo); + Map> authMap = filterAuthByRoleAndProduct(permissionInfo.stream().map(e -> FilterRoleAuth.builder() .roleId(NumberUtil.parseLong(e.getRoleId())) .workspaceId(e.getWorkspaceId()) .build()).collect(Collectors.toList())); - permissionInfo.forEach(e -> e.setFeatureInfos(authMap.get(NumberUtil.parseLong(e.getRoleId())))); - permissionInfo.forEach(e -> e.setSimpleFeatureInfos(org.apache.commons.collections4.CollectionUtils.emptyIfNull(authMap.get(NumberUtil.parseLong(e.getRoleId()))) - .stream().map(ListPermissionFromRoleGroupResp.FeatureInfo::getFeatureId).collect(Collectors.toSet()))); + return permissionInfo.stream() + .filter(e -> { + PermissionTagService.ResolvePermissionDTO resolvePermission = personPermissionTags.get(e.getPersonId() + "_" + e.getOuId() + "_" + e.getWorkspaceId()); + if (Objects.isNull(resolvePermission)) { + // 未解析到标签兼容历史情况 + return true; + } - return permissionInfo; + Set featureInfos = authMap.get(NumberUtil.parseLong(e.getRoleId())); + + return featureInfos.stream() + .anyMatch(permission -> permission.getTags() + .stream() + .anyMatch(tag -> !Sets.intersection(permission.getTags(), resolvePermission.getTags()).isEmpty())); + }) + .peek(e -> { + e.setFeatureInfos(authMap.get(NumberUtil.parseLong(e.getRoleId()))); + e.setSimpleFeatureInfos(org.apache.commons.collections4.CollectionUtils.emptyIfNull(authMap.get(NumberUtil.parseLong(e.getRoleId()))) + .stream().map(ListPermissionFromRoleGroupResp.FeatureInfo::getFeatureId).collect(Collectors.toSet())); + }) + .collect(Collectors.toList()); + } + + /** + * 解析用户在项目的标签: + * key:personId_ouId_workspaceId + * @param permissionInfo + * @return + */ + private Map resolveTags(List permissionInfo) { + + List personPermissions = permissionInfo.stream() + .map(e -> PermissionTagService.PersonPermission.builder() + .workspaceId(e.getWorkspaceId()) + .ouId(e.getOuId()) + .personId(e.getPersonId()) + .build()) + .distinct() + .collect(Collectors.toList()); + + PermissionTagService.ResolvePermissionTagParam resolvePermissionTagParam = PermissionTagService.ResolvePermissionTagParam.builder() + .personPermissions(personPermissions) + .build(); + return permissionTagService.resolvePermissionTag(resolvePermissionTagParam).stream() + .collect(Collectors.toMap(e -> e.getPersonId() + "_" + e.getOuId() + "_" + e.getWorkspaceId(), Function.identity())); } /** @@ -908,7 +978,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { * @param filterRoleAuths * @return KEY :role Id ; VALUE: feature id ; */ - public Map> filterAuthByRoleAndProduct(List filterRoleAuths) { + private Map> filterAuthByRoleAndProduct(List filterRoleAuths) { Set roleIds = filterRoleAuths.stream().map(FilterRoleAuth::getRoleId).collect(Collectors.toSet()); ListRoleReq listSaasRoleParam = ListRoleReq.builder() @@ -934,7 +1004,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { WorkspaceProductService.WorkspaceProductPermission::getProductPermissions)); // intersection auth from role and product - Map> map = filterRoleAuths.stream().collect(Collectors.toMap(FilterRoleAuth::getRoleId, e -> { + Map> map = filterRoleAuths.stream().collect(Collectors.toMap(FilterRoleAuth::getRoleId, e -> { Long roleId = e.getRoleId(); SaasRoleRes saasRole = roles.get(e.getRoleId()); if (null == saasRole) { @@ -942,11 +1012,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return Collections.emptySet(); } - Set rolePermissionIds = rolePermissions.get(roleId) - .stream() - .map(RolePermissionCacheService.PermissionDTO::getFeatureId) - .collect(Collectors.toSet()); - Set productPermissionIds = workspaceProductPermissions.get(e.getWorkspaceId()).stream() .map(WorkspaceProductService.ProductPermission::getPermissions) .flatMap(Collection::stream) @@ -954,22 +1019,23 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .map(ProductPermissionCacheService.PermissionDTO::getFeatureId) .collect(Collectors.toSet()); - return new HashSet<>(CollectionUtil.intersection(productPermissionIds, rolePermissionIds)); - - + return rolePermissions.get(roleId).stream() + .filter(rolePermission -> productPermissionIds.contains(rolePermission.getFeatureId())) + .collect(Collectors.toSet()); }, (oldFeatureLists, newFeatureLists) -> { oldFeatureLists.addAll(newFeatureLists); return oldFeatureLists; })); Map> featureMap = Maps.newHashMap(); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : map.entrySet()) { Set featureInfos = org.apache.commons.collections4.CollectionUtils.emptyIfNull(entry.getValue()).stream().map(e -> ListPermissionFromRoleGroupResp.FeatureInfo.builder() - .featureId(e) + .featureId(e.getFeatureId()) + .tags(e.getTags()) // 因为CMS、CMP端saas_feature_resouce表的id从100000开始自增 // 不会跟saas_feature有冲突,项企分离后,旧的saas_feature表不会再使用,所以这里直接根据featureId < 100000 // 来判断relationType是saas_feature还是saas_feature_resource,不增加到缓存里是减少io量 - .relationType(e < 100000 ? OLD_FEATURE : NEW_FEATURE) + .relationType(e.getFeatureId() < 100000 ? OLD_FEATURE : NEW_FEATURE) .build()).collect(Collectors.toSet()); featureMap.put(entry.getKey(), featureInfos); } @@ -994,439 +1060,33 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { @Override public List listWorkspacePermissionIdentity(WorkspacePermissionIdentityReq req) { - if (this.permissionFromDB()) { - return listWorkspacePermissionIdentityFromDB(req); + Set newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes())); + + Set featureCodes = Sets.newHashSet(req.getFeatureCodes()); + featureCodes.addAll(newFeatureCodes); + + ListPermissionUser listPermissionUser = ListPermissionUser.builder() + .featureCodes(featureCodes) + .workspaceId(req.getWorkspaceId()) + .tags(req.getTags()) + .build(); + List users = listPermissionUser(listPermissionUser); + + if (CollectionUtil.isEmpty(users)) { + return Collections.emptyList(); } - - try { - Set newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes())); - - Set featureCodes = Sets.newHashSet(req.getFeatureCodes()); - featureCodes.addAll(newFeatureCodes); - - ListPermissionUser listPermissionUser = ListPermissionUser.builder() - .featureCodes(featureCodes) + //按ou分组返回 + List result = new ArrayList<>(); + Map> userMap = users.stream() + .collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId)); + for (Map.Entry> entry : userMap.entrySet()) { + result.add(ListIdentityFromPermissionResp.builder() .workspaceId(req.getWorkspaceId()) - .build(); - List users = listPermissionUser(listPermissionUser); - - if (CollectionUtil.isEmpty(users)) { - return Collections.emptyList(); - } - //按ou分组返回 - List result = new ArrayList<>(); - Map> userMap = users.stream() - .collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId)); - for (Map.Entry> entry : userMap.entrySet()) { - result.add(ListIdentityFromPermissionResp.builder() - .workspaceId(req.getWorkspaceId()) - .ouId(entry.getKey()) - .users(entry.getValue()) - .build()); - } - return result; - } catch (Exception ex) { - log.error("查询权限异常,执行降级处理"); - return listWorkspacePermissionIdentityFromDB(req); + .ouId(entry.getKey()) + .users(entry.getValue()) + .build()); } - } - - private List listFeatureRoles(Set featureIds, Integer type) { - if (CollectionUtils.isEmpty(featureIds)) { - return Collections.emptyList(); - } - - List relations = saasPgroupPermissionRelationService.list(PagePgroupPermissionRelationReq.builder() - .featureIds(Lists.newArrayList(featureIds)) - .type(type) - .build()); - if (CollectionUtils.isEmpty(relations)) { - return Collections.emptyList(); - } - - List saasPgroupRoleRelations = saasPgroupRoleRelationDao.listByGroupIds(Lists.transform(relations, SaasPgroupPermissionRelation::getGroupId)); - - if (CollectionUtils.isEmpty(saasPgroupRoleRelations)) { - return Collections.emptyList(); - } - - return roleService.list(ListRoleReq.builder() - .roleIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getRoleId)) - .build()) - .stream() - .map(e -> { - SaasRole saasRole = new SaasRole(); - BeanUtils.copyProperties(e, saasRole); - return saasRole; - }) - .collect(Collectors.toList()); - } - - private List getWorkspaceUser(Long workspaceId, Long ouId, - List workspaceProducts) { - Set newProductTypes = workspaceProducts.stream() - .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) - .map(SaasProductModuleFeatureRelation::getDictCode) - .map(Integer::valueOf) - .collect(Collectors.toSet()); - - Set newMatchedFeatureIds = workspaceProducts.stream() - .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - - Set oldProductTypes = workspaceProducts.stream() - .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) - .map(SaasProductModuleFeatureRelation::getDictCode) - .map(Integer::valueOf) - .collect(Collectors.toSet()); - - Set oldMatchedFeatureIds = workspaceProducts.stream() - .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - - //超管和管理员 - List adminRoles = roleService.listAdmins(workspaceId, ouId); - if (CollectionUtil.isEmpty(adminRoles)) { - log.warn("no admin roles found for workspaceId:{}, ouId:{}", workspaceId, ouId); - } - - Set superAdmins = adminRoles.stream() - .filter(r -> RoleTypeEnum.SUPER_ADMIN.getValue().equals(r.getRoleType())) - .map(SaasRole::getId) - .collect(Collectors.toSet()); - - //普通角色 权限点查角色 -- 不考虑 角色权限集例外 - // 多版本只会存在一段时间,减少代码复杂度,所以查询多次 - List oldNormalSaasRoles = listFeatureRoles(oldMatchedFeatureIds, OLD_FEATURE); - List newNormalSaasRoles = listFeatureRoles(newMatchedFeatureIds, NEW_FEATURE); - - List roleIds = Lists.newArrayList(); - // 超管不用区分新老版本 - List adminRoleIds = adminRoles.stream() - .filter(r -> newProductTypes.contains(r.getProductUnitType()) || oldProductTypes.contains(r.getProductUnitType())) - .map(SaasRole::getId) - .collect(Collectors.toList()); - - List oldNormalRoleIds = oldNormalSaasRoles.stream() - .filter(r -> oldProductTypes.contains(r.getProductUnitType())) - .map(SaasRole::getId) - .collect(Collectors.toList()); - - List newNormalRoleIds = newNormalSaasRoles.stream() - .filter(r -> newProductTypes.contains(r.getProductUnitType())) - .map(SaasRole::getId) - .collect(Collectors.toList()); - - //匹配角色和产品标签 - roleIds.addAll(adminRoleIds); - roleIds.addAll(oldNormalRoleIds); - roleIds.addAll(newNormalRoleIds); - - if (CollectionUtil.isEmpty(roleIds)) { - log.warn("no role matched product unit types"); - return Collections.emptyList(); - } - - //角色查人 - List relations = roleUserService.listByRoleIds(roleIds, ouId, workspaceId); - if (CollectionUtil.isEmpty(relations)) { - log.warn("no user role relation found. roleIds:{}, ouId:{} workspaceId:{}", roleIds, ouId, workspaceId); - return Collections.emptyList(); - } - - //ouId -> resp : ou-identityId-identityType维度去重 - Map distinctMap = new HashMap<>(); - //组装去重 - for (SaasRoleUserRelation relation : relations) { - String key = KeyUtil.buildKeyBySeparator(relation.getOuId(), relation.getIdentityId(), relation.getIdentityType()); - ListIdentityFromPermissionResp.UserVO user = distinctMap.get(key); - if (user == null) { - user = ListIdentityFromPermissionResp.UserVO.builder() - .ouId(relation.getOuId()) - .identityId(relation.getIdentityId()) - .identityType(relation.getIdentityType()) - .personalId(relation.getNaturalPersonId()) - .build(); - } - if (superAdmins.contains(relation.getRoleId())) { - //超管 - user.setSuperAdmin(true); - } - distinctMap.put(key, user); - } - - return new ArrayList<>(distinctMap.values()); - } - - /** - * 基于saas_feature_resource的鉴权 - * @param req - * @return - */ - @Override - public boolean authNewPermission(PermissionCheckReq req) { - ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() - .featureCodes(Sets.newHashSet(req.getFeatureCodes())) - .terminal(req.getTerminal()) - .build(); - List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); - if (CollectionUtils.isEmpty(saasFeatureResources)) { - log.info("featureCode not found in featureResource:{}", req.getFeatureCodes()); - return false; - } - //用户角色关系,以及对应角色的权限点 - List saasRoleUserRelations = listRoleUserRelationsNew(req, saasFeatureResources); - if (CollectionUtils.isEmpty(saasRoleUserRelations)) { - return false; - } - - Set featureIds = saasFeatureResources.stream() - .map(SaasFeatureResourceResp::getId) - .collect(Collectors.toSet()); - - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) - .featureIdPairs(Lists.newArrayList( - FeatureIdPair.builder().featureIds(featureIds).type(NEW_FEATURE).build() - )) - .build(); - Set workspaceProductFeatures = workspaceProductService.listWorkspaceProductCached(workspaceProductParam).stream() - .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); - - if (CollectionUtils.isEmpty(workspaceProductFeatures)) { - log.info("product not found:{}", req.getWorkspaceId()); - return false; - } - - // 是否有免授权的权限码,且在租户开通了这个产品 - boolean matchedNoNeedAuthFeature = matchNoAuthFeatureNew(saasFeatureResources, workspaceProductFeatures); - if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { - log.info("has no need auth feature:{}", req.getWorkspaceId()); - return true; - } - - // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 - boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, workspaceProductFeatures); - if (BooleanUtil.isTrue(matchedAdminRole)) { - log.info("admin role has permission:{}", req.getWorkspaceId()); - return true; - } - return matchNormalRole(saasRoleUserRelations, workspaceProductFeatures); - } - - /** - * 基于saas_feature的鉴权,后续会去掉 - * @param req - * @return - */ - @Override - public boolean authPermission(PermissionCheckReq req) { - // saas_feature表会被废弃,所以直接查询,没提供统一的查询 - List saasFeatures = saasFeatureDao.lambdaQuery() - .in(SaasFeature::getFeatureCode, req.getFeatureCodes()) - .eq(SaasFeature::getIsDelete, TableIsDeleteEnum.NORMAL.value) - .eq(StringUtils.isNotBlank(req.getTerminal()), SaasFeature::getTerminal, req.getTerminal()) - .list(); - if (CollectionUtils.isEmpty(saasFeatures)) { - log.info("featureCode not found in saasFeature:{}", req.getFeatureCodes()); - return false; - } - - //用户角色关系,以及对应角色的权限点 - List saasRoleUserRelations = listRoleUserRelations(req, saasFeatures); - if (CollectionUtils.isEmpty(saasRoleUserRelations)) { - return false; - } - - Set featureIds = saasFeatures.stream() - .map(SaasFeature::getId) - .collect(Collectors.toSet()); - - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) - .featureIdPairs(Lists.newArrayList( - FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build() - )) - .build(); - Set workspaceProductFeatures = workspaceProductService.listWorkspaceProductCached(workspaceProductParam).stream() - .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); - if (CollectionUtils.isEmpty(workspaceProductFeatures)) { - log.info("product not found:{}", req.getWorkspaceId()); - return false; - } - - // 是否有免授权的权限码,且在租户开通了这个产品 - boolean matchedNoNeedAuthFeature = matchNoAuthFeature(saasFeatures, workspaceProductFeatures); - if (BooleanUtil.isTrue(matchedNoNeedAuthFeature)) { - log.info("has no need auth feature:{}", req.getWorkspaceId()); - return true; - } - // 是否有管理员角色,且租户开通了管理员角色的单位类型对应的产品权限码 - boolean matchedAdminRole = matchAdminRole(saasRoleUserRelations, workspaceProductFeatures); - if (BooleanUtil.isTrue(matchedAdminRole)) { - log.info("admin role has permission:{}", req.getWorkspaceId()); - return true; - } - return matchNormalRole(saasRoleUserRelations, workspaceProductFeatures); - } - - private boolean matchNormalRole(List saasRoleUserRelations, - Set permissionProducts) { - List normalRoles = saasRoleUserRelations.stream() - .filter(e -> !RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(normalRoles)) { - return false; - } - - // 权限点对应角色的单位类型要与权限点对应产品的单位类型一致才能算有权限 - Map> permissionProductMap = permissionProducts.stream() - .collect(Collectors.groupingBy(SaasProductModuleFeatureRelation::getFeatureId, - Collectors.mapping(SaasProductModuleFeatureRelation::getDictCode, Collectors.toList()))); - - for (SaasRoleUserV2DTO permissionRole : normalRoles) { - if (CollectionUtils.isEmpty(permissionRole.getSaasRole().getSaasPermissions())) { - continue; - } - - Set ouTypesOfProduct = permissionRole.getSaasRole().getSaasPermissions().stream() - .map(e -> permissionProductMap.get(e.getId())) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); - - if (CollectionUtils.isEmpty(ouTypesOfProduct)) { - continue; - } - - if (ouTypesOfProduct.contains(String.valueOf(permissionRole.getSaasRole().getProductUnitType()))) { - return true; - } - } - - return false; - } - - private boolean matchNoAuthFeatureNew(List saasFeatureResources, - Set permissionProducts) { - - Set noNeedAuthFeatureIds = saasFeatureResources.stream() - .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) - .map(SaasFeatureResourceResp::getId) - .collect(Collectors.toSet()); - - if (CollectionUtils.isEmpty(noNeedAuthFeatureIds)) { - log.info("not found no need auth featureCode"); - return false; - } - - return permissionProducts.stream() - .anyMatch(e -> noNeedAuthFeatureIds.contains(e.getFeatureId())); - } - - /** - * 租户开通的产品是否有不需要鉴权的权限码 - * - * @param saasFeatures - * @param permissionProducts - * @return - */ - private boolean matchNoAuthFeature(List saasFeatures, - Set permissionProducts) { - - Set noNeedAuthFeatureIds = saasFeatures.stream() - .filter(e -> Objects.equals(e.getDelegatedType(), DelegatedType.NO_NEED.getCode())) - .map(SaasFeature::getId) - .collect(Collectors.toSet()); - - if (CollectionUtils.isEmpty(noNeedAuthFeatureIds)) { - log.info("not found no need auth featureCode"); - return false; - } - - return permissionProducts.stream() - .anyMatch(e -> noNeedAuthFeatureIds.contains(e.getFeatureId())); - } - - /** - * 匹配管理员角色是否有权限点的权限 - * - * @param saasRoleUserRelations - * @param permissionProducts - * @return - */ - private boolean matchAdminRole(List saasRoleUserRelations, - Set permissionProducts) { - - List adminRoles = saasRoleUserRelations.stream() - .filter(e -> RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(adminRoles)) { - return false; - } - - Set ouTypes = permissionProducts.stream() - .map(SaasProductModuleFeatureRelation::getDictCode) - .collect(Collectors.toSet()); - - return adminRoles.stream() - .anyMatch(adminRole -> ouTypes.contains(String.valueOf(adminRole.getSaasRole().getProductUnitType()))); - } - - /** - * 兼容历史版本,全部切完后去掉 - * @param identityAuthReq - * @param saasFeatures - * @return - */ - private List listRoleUserRelations(PermissionCheckReq identityAuthReq, List saasFeatures) { - - List workspaceOuPairs = Lists.newArrayList( - ListRoleUserRelationParam.WorkspaceOuPair.builder() - .workspaceId(identityAuthReq.getWorkspaceId()) - .ouId(identityAuthReq.getOuId()) - .build() - ); - ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() - .personId(identityAuthReq.getPersonId()) - .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) - .needRole(true) - .needRolePermissionOld(true) - .featureIds(Lists.transform(saasFeatures, SaasFeature::getId)) - .build(); - return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() - .filter(e -> e.getSaasRole() != null) - .collect(Collectors.toList()); - } - - private List listRoleUserRelationsNew(PermissionCheckReq identityAuthReq, List saasFeatureResources) { - - List workspaceOuPairs = Lists.newArrayList( - ListRoleUserRelationParam.WorkspaceOuPair.builder() - .workspaceId(identityAuthReq.getWorkspaceId()) - .ouId(identityAuthReq.getOuId()) - .build() - ); - ListRoleUserRelationParam listRoleUserRelationParam = ListRoleUserRelationParam.builder() - .personId(identityAuthReq.getPersonId()) - .workspaceOuPairs(Lists.newArrayList(workspaceOuPairs)) - .needRole(true) - .needPermission(true) - .featureIds(Lists.transform(saasFeatureResources, SaasFeatureResourceResp::getId)) - .build(); - return saasRoleUserRelationService.listV2(listRoleUserRelationParam).stream() - .filter(e -> e.getSaasRole() != null) - .collect(Collectors.toList()); + return result; } private List mockRoleUserRelationV2(IdentityAuthReq identityAuthReq) { @@ -1494,6 +1154,40 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .collect(Collectors.toList()); } + /** + * 因为默认情况下管理员角色是不会配置角色权限的,但是会配置离场权限,所以用户在查询离场权限时,需要查询管理员的离场权限 + * @param identityAuthReq + * @param saasRoleUsers + * @return + */ + private Map> listAdminLeavePermission(IdentityAuthReq identityAuthReq, + List saasRoleUsers) { + Set levelWorkspaceOuPairs = identityAuthReq.getWorkspaceOusPairs().stream() + .filter(e -> !CollectionUtils.isEmpty(e.getTags()) && e.getTags().contains(RolePermissionTagEnum.LEAVE)) + .map(IdentityAuthReq.WorkspaceOuPair::buildOuWorkspaceKey) + .collect(Collectors.toSet()); + + if (CollectionUtils.isEmpty(levelWorkspaceOuPairs)) { + return Collections.emptyMap(); + } + + Set adminRoleIds = saasRoleUsers.stream() + .filter(e -> RoleTypeEnum.isAdmin(e.getSaasRole().getRoleType())) + .filter(e -> levelWorkspaceOuPairs.contains(e.getSaasRoleUser().buildOuWorkspaceKey())) + .map(SaasRoleUserV2DTO::getRoleId) + .collect(Collectors.toSet()); + if (CollectionUtils.isEmpty(adminRoleIds)) { + return Collections.emptyMap(); + } + + RolePermissionCacheService.ListRolePermissionParam listRolePermissionParam = RolePermissionCacheService.ListRolePermissionParam.builder() + .roleIds(adminRoleIds) + .featureCodes(identityAuthReq.getFeatureCode()) + .tags(Sets.newHashSet(RolePermissionTagEnum.LEAVE)) + .build(); + return rolePermissionCacheService.list(listRolePermissionParam); + } + /** * 出入参不变,方便切换, * 基于redis缓存角色权限、产品权限进行解析 @@ -1505,8 +1199,12 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { List saasRoleUsers = listRoleUserRelationsV2(identityAuthReq); + // 查询项目所有普通角色的权限,因为不同项目可能需要权限tags不一样,直接查询所有权限,后面根据不同项目的权限tags过滤 Map> rolePermissions = listRolePermission(identityAuthReq, saasRoleUsers); + // 管理员角色非在职的权限都会单独配置,目前只有离场标签这样配置,其他标签还不确定是否一致,所以这里只查询离场标签 + Map> adminLeavePermissions = listAdminLeavePermission(identityAuthReq, saasRoleUsers); + Map> workspaceRoles = saasRoleUsers.stream() .collect(Collectors.groupingBy(e -> e.getSaasRoleUser().buildOuWorkspaceKey(), Collectors.mapping(SaasRoleUserV2DTO::getSaasRole, Collectors.toList()))); @@ -1552,7 +1250,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .build(); } - return buildPermissionsV2(workspaceOuPair, productPermissions, saasRoles, rolePermissions, allFeatures); + return buildPermissionsV2(workspaceOuPair, productPermissions, saasRoles, rolePermissions, allFeatures, adminLeavePermissions); }) .collect(Collectors.toList()); @@ -1570,7 +1268,8 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { List productPermissions, List saasRoles, Map> rolePermissions, - List allFeatures) { + List allFeatures, + Map> adminLeavePermissions) { IdentityAuthRes.WorkspacePermission workspacePermission = IdentityAuthRes.WorkspacePermission.builder() .workspaceId(workspaceOuPair.getWorkspaceId()) @@ -1582,9 +1281,10 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } //超管和管理员权限 - Set adminPermissionPoints = buildAdminPermissionV2(productPermissions, saasRoles); + Set adminPermissionPoints = buildAdminPermissionV2(productPermissions, saasRoles, workspaceOuPair); Set noAuthPermissionPoints = buildNoAuthPermission(productPermissions, allFeatures); - Set normalPermissionPoints = buildNormalPermissionV2(productPermissions, saasRoles, rolePermissions); + Set normalPermissionPoints = buildNormalPermissionV2(productPermissions, saasRoles, rolePermissions, workspaceOuPair); + Set adminLeavePermissionPoints = buildAdminLeavePermission(productPermissions, saasRoles, adminLeavePermissions, workspaceOuPair); //组装返回值 @@ -1599,6 +1299,7 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { allPermissionPoints.addAll(adminPermissionPoints); allPermissionPoints.addAll(noAuthPermissionPoints); allPermissionPoints.addAll(normalPermissionPoints); + allPermissionPoints.addAll(adminLeavePermissionPoints); // 过滤掉已经删除的权限点 Set effectFeatureIds = allFeatures.stream() .map(SaasFeatureResourceService.SaasFeatureResourceCache::getFeatureId) @@ -1621,8 +1322,71 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { .collect(Collectors.toList()); } + private Set buildAdminLeavePermission(List productPermissions, + List saasRoles, + Map> adminLeavePermissions, + IdentityAuthReq.WorkspaceOuPair workspaceOuPair) { + //超管和管理员角色 + List adminRoles = Optional.ofNullable(saasRoles) + .map(e -> e.stream() + .filter(r -> RoleTypeEnum.isAdmin(r.getRoleType())) + .collect(Collectors.toList())) + .orElse(null); + if (CollectionUtil.isEmpty(adminRoles)) { + log.info("no admin roles"); + return Collections.emptySet(); + } + + // 因为tag != LEAVE的权限,管理员的权限直接是产品匹配的权限 + if (CollectionUtils.isEmpty(workspaceOuPair.getTags()) || !workspaceOuPair.getTags().contains(RolePermissionTagEnum.LEAVE)) { + return Collections.emptySet(); + } + + return adminRoles.stream() + .map(role -> { + Set rolePermissionFeatureCodes = Optional.ofNullable(adminLeavePermissions.get(role.getId())) + .map(e -> e.stream() + .filter(Objects::nonNull) + .map(RolePermissionCacheService.PermissionDTO::getFeatureCode) + .collect(Collectors.toSet())) + .orElseGet(Sets::newHashSet); + + if (CollectionUtils.isEmpty(rolePermissionFeatureCodes)) { + return null; + } + + return productPermissions.stream() + .filter(productPermission -> Objects.equals(productPermission.getCooperateType(), String.valueOf(role.getProductUnitType()))) + .filter(productPermission -> rolePermissionFeatureCodes.contains(productPermission.getFeatureCode())) + .map(e -> IdentityAuthRes.PermissionPoint.builder() + .featureCode(e.getFeatureCode()) + .featureId(e.getFeatureId()) + .terminal(e.getTerminal()) + .featureType(e.getFeatureType()) + .build()) + .collect(Collectors.toSet()); + + }) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + } + + /** + * 只有查询在职权限时才能直接根据管理员角色和产品去匹配 + * 因为离场权限,管理员角色会配置管理员角色对应的离场权限 + * @param productPermissions + * @param saasRoles + * @param workspaceOuPair + * @return + */ private Set buildAdminPermissionV2(List productPermissions, - List saasRoles) { + List saasRoles, + IdentityAuthReq.WorkspaceOuPair workspaceOuPair) { + if (!CollectionUtils.isEmpty(workspaceOuPair.getTags()) && !workspaceOuPair.getTags().contains(RolePermissionTagEnum.JOINED)) { + return Collections.emptySet(); + } + //超管和管理员角色 List adminRoles = Optional.ofNullable(saasRoles) .map(e -> e.stream() @@ -1684,8 +1448,9 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { } private Set buildNormalPermissionV2(List productPermissions, - List saasRoles, - Map> rolePermissionMap) { + List saasRoles, + Map> rolePermissionMap, + IdentityAuthReq.WorkspaceOuPair workspaceOuPair) { List normalRoles =Optional.ofNullable(saasRoles) .map(e -> e.stream() @@ -1702,6 +1467,17 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { Set rolePermissionFeatureCodes = Optional.ofNullable(rolePermissionMap.get(role.getId())) .map(e -> e.stream() .filter(Objects::nonNull) + .filter(rolePermission -> { + if (CollectionUtils.isEmpty(workspaceOuPair.getTags()) || CollectionUtils.isEmpty(rolePermission.getTags())) { + return true; + } + + if (Sets.intersection(workspaceOuPair.getTags(), rolePermission.getTags()).isEmpty()) { + return false; + } + + return true; + }) .map(RolePermissionCacheService.PermissionDTO::getFeatureCode) .collect(Collectors.toSet())) .orElseGet(Sets::newHashSet); @@ -1758,91 +1534,6 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { return rolePermissionCacheService.list(listRolePermissionParam); } - private IdentityAuthRes findIdentityAuth(IdentityAuthReq identityAuthReq) { - //用户角色关系 - List saasRoleUserRelations = listRoleUserRelations(identityAuthReq); - if (CollectionUtils.isEmpty(saasRoleUserRelations)) { - log.warn("no user role relations found"); - return identityAuthReq.toEmpty(); - } - - Set realWorkspaceId = saasRoleUserRelations.stream().map(SaasRoleUserV2DTO::getWorkspaceId).collect(Collectors.toSet()); - //工作台对应产品 key = workspaceId - CompletableFuture> workspacePermissionPointFuture = CompletableFuture - .supplyAsync(TraceSupplier.create(() -> { - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .workspaceIds(realWorkspaceId) - .build(); - return workspaceProductService.listWorkspaceProduct(workspaceProductParam); - }), executor); - //查询工作台下授予的角色和权限 - List owRoles = listRolesWithPermission(saasRoleUserRelations, identityAuthReq); - - Map workspaceProductPermissionMap = workspacePermissionPointFuture.join().stream() - .collect(Collectors.toMap(WorkspaceProductService.WorkspaceProduct::getWorkspaceId, Function.identity())); - - List> futureList = new ArrayList<>(); - for (OUWRoleInfo owRoleInfo : owRoles) { - // 工作台的产品权限点 - WorkspaceProductService.WorkspaceProduct workspaceProduct = workspaceProductPermissionMap.get(owRoleInfo.getWorkspaceId()); - //构建每个工作台的实际权限点 - futureList.add(CompletableFuture.supplyAsync(TraceSupplier.create(() -> buildPermissions(owRoleInfo, workspaceProduct)), executor) - .exceptionally(t -> { - LogUtil.error("获取角色对应权限失败", t); - throw new ServiceException(t); - })); - } - - //汇总结果 - IdentityAuthRes result = new IdentityAuthRes(); - result.setIdentity(identityAuthReq.getIdentityId()); - result.setIdentityType(identityAuthReq.getIdentityType()); - result.setPersonId(identityAuthReq.getPersonId()); - for (CompletableFuture future : futureList) { - result.getPermissions().add(future.join()); - } - return result; - } - - private List listRoleUserRelations(IdentityAuthReq identityAuthReq) { - if (CollectionUtil.isNotEmpty(identityAuthReq.getSpecifyRoleIds())) { - //指定了角色 则不需要去查用户角色关系 - log.info("mock specify roles relation"); - return mockRoleUserRelation(identityAuthReq); - } - return saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder() - .personId(identityAuthReq.getPersonId()) - .identityId(identityAuthReq.getIdentityId()) - .identityType(identityAuthReq.getIdentityType()) - .workspaceOuPairs(identityAuthReq.getWorkspaceOusPairs().stream() - .map(e -> ListRoleUserRelationParam.WorkspaceOuPair.builder() - .workspaceId(e.getWorkspaceId()) - .ouId(e.getOuId()) - .build()) - .collect(Collectors.toList())) - .build()); - } - - private List mockRoleUserRelation(IdentityAuthReq identityAuthReq) { - final List relations = new ArrayList<>(); - // mock 看做已有指定的角色 - for (IdentityAuthReq.WorkspaceOuPair ow : identityAuthReq.getWorkspaceOusPairs()) { - List mockRelations = identityAuthReq.getSpecifyRoleIds().stream().map(id -> { - SaasRoleUserV2DTO relation = SaasRoleUserV2DTO.builder().build(); - relation.setRoleId(id); - relation.setOuId(ow.getOuId()); - relation.setWorkspaceId(ow.getWorkspaceId()); - relation.setIdentityId(identityAuthReq.getIdentityId()); - relation.setIdentityType(identityAuthReq.getIdentityType().getCode()); - // 使用角色ID替代,不需要在查询一次 - relation.setId(id); - return relation; - }).collect(Collectors.toList()); - relations.addAll(mockRelations); - } - return relations; - } - @Data @Builder @NoArgsConstructor @@ -1855,443 +1546,4 @@ public class TyrSaasAuthServiceImpl implements TyrSaasAuthService { */ private Integer type; } - - private List listRolesWithPermission(List roleUserRelations, IdentityAuthReq identityAuthReq) { - - //拼装参数 - Set roleIds = new HashSet<>(); - //按ow分组角色ID: workspaceId-ouId --> roleIds - Map> owRoleIdMap = new HashMap<>(); - for (SaasRoleUserV2DTO relation : roleUserRelations) { - roleIds.add(relation.getRoleId()); - String key = KeyUtil.buildKeyBySeparator(relation.getWorkspaceId(), relation.getOuId()); - Set owRoleIds = owRoleIdMap.getOrDefault(key, new HashSet<>()); - owRoleIds.add(relation.getRoleId()); - owRoleIdMap.put(key, owRoleIds); - } - //获取角色和关联权限信息 - ListRoleReq listSaasRoleParam = ListRoleReq.builder() - .roleIds(Lists.newArrayList(roleIds)) - .needPermissionRelation(true) - .build(); - Map saasRoleRes = roleService.list(listSaasRoleParam).stream() - .collect(Collectors.toMap(SaasRoleRes::getId, Function.identity())); - - //按ow组装拥有的角色 - List owRoleMap = new ArrayList<>(); - for (IdentityAuthReq.WorkspaceOuPair ow : identityAuthReq.getWorkspaceOusPairs()) { - OUWRoleInfo owRoleInfo = OUWRoleInfo.builder() - .workspaceId(ow.getWorkspaceId()) - .ouId(ow.getOuId()) - .build(); - String key = KeyUtil.buildKeyBySeparator(ow.getWorkspaceId(), ow.getOuId()); - Set owRoleIds = owRoleIdMap.get(key); - if (CollectionUtil.isEmpty(owRoleIds)) { - log.info("no roles found for ow:{}", key); - owRoleInfo.setRoles(Collections.emptySet()); - } else { - owRoleInfo.setRoles(owRoleIds.stream() - .map(saasRoleRes::get) - // 有saas_role_user_relation有记录,但是对应的saas_role不存在的情况 - .filter(Objects::nonNull) - .collect(Collectors.toSet())); - } - owRoleMap.add(owRoleInfo); - } - - return owRoleMap; - } - - private IdentityAuthRes.WorkspacePermission buildPermissions(OUWRoleInfo ouwRoleInfo, WorkspaceProductService.WorkspaceProduct workspaceProduct) { - - IdentityAuthRes.WorkspacePermission resultPermission = IdentityAuthRes.WorkspacePermission.builder() - .workspaceId(ouwRoleInfo.getWorkspaceId()) - .ouId(ouwRoleInfo.getOuId()) - .build(); - - if (Objects.isNull(workspaceProduct) || CollectionUtil.isEmpty(workspaceProduct.getSaasProductModuleFeatureRelations())) { - log.warn("no product features found for workspace :{}", ouwRoleInfo.getWorkspaceId()); - return resultPermission; - } - - Set roles = ouwRoleInfo.getRoles(); - if (CollectionUtil.isEmpty(roles)) { - log.warn("no roles for ou:{} workspace:{}", ouwRoleInfo.getOuId(), ouwRoleInfo.getWorkspaceId()); - return resultPermission; - } - - List productFeatures = workspaceProduct.getSaasProductModuleFeatureRelations(); - // 因为存在同时有saas_feature和saas_feature_resource的权限,所以要返回type,根据type解析code - //超管和管理员权限 - Pair> adminPermissions = buildAdminPermission(ouwRoleInfo, productFeatures); - //标准角和自定义角色权限 - Set normalPermissions = buildNormalPermission(ouwRoleInfo, productFeatures); - Set allPermissions = Sets.newHashSet(); - allPermissions.addAll(adminPermissions.getValue()); - allPermissions.addAll(normalPermissions); - - //查询权限点及父级权限点 - List allOldPermissionPoint = listOldFeatures(allPermissions); - - List newPermissionPoints = listNewFeatures(allPermissions); - - //组装返回值 - //是否超管 - resultPermission.setSuperAdmin(BooleanUtil.isTrue(adminPermissions.getKey())); - //权限数据 - resultPermission.getPermissionPoint().addAll(allOldPermissionPoint.stream() - .map(permissionPointTreeNode -> IdentityAuthRes.PermissionPoint.builder() - .featureCode(permissionPointTreeNode.getCode()) - .featureId(permissionPointTreeNode.getId()) - .terminal(permissionPointTreeNode.getTerminal()) - .build()) - .collect(Collectors.toList())); - - resultPermission.getPermissionPoint().addAll(newPermissionPoints); - return resultPermission; - } - - private Pair> buildAdminPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { - Boolean superAdmin = false; - //超管和管理员角色 - List adminRoles = userRoleInfoMap.getRoles().stream() - .filter(r -> RoleTypeEnum.isAdmin(r.getRoleType())) - .collect(Collectors.toList()); - if (CollectionUtil.isEmpty(adminRoles)) { - log.info("no admin roles"); - return Pair.of(superAdmin, Collections.emptySet()); - } - - log.info("build admin permission for ou:{}, workspace:{}", userRoleInfoMap.getOuId(), userRoleInfoMap.getWorkspaceId()); - - //聚合超管和管理员的权限点: 直接取角色标签和产品标签相匹配的权限点 - Set permissions = Sets.newHashSet(); - for (SaasRoleRes adminRole : adminRoles) { - //超管:查询工作台对应产品,获取权限点, ( 权限点通过单位类型过滤) - if (RoleTypeEnum.SUPER_ADMIN.getValue().equals(adminRole.getRoleType())) { - superAdmin = true; - } - //角色标签类型匹配产品标签类型 - Set permission = productFeatures.stream() - .filter(productFeatureRelationVO -> Objects.equals(productFeatureRelationVO.getDictCode(), - String.valueOf(adminRole.getProductUnitType()))) - .map(e -> FeatureWrapper.builder() - .featureId(e.getFeatureId()) - .type(e.getType()) - .build()) - .collect(Collectors.toSet()); - - if (CollectionUtil.isEmpty(permission)) { - log.warn("empty permission for admin role:{}", adminRole.getId()); - continue; - } - log.info("add all permissions for role:{}", adminRole.getId()); - permissions.addAll(permission); - } - - return Pair.of(superAdmin, permissions); - } - - private Set buildNormalPermission(OUWRoleInfo userRoleInfoMap, List productFeatures) { - - log.info("build permission for ou:{}, workspace:{}", userRoleInfoMap.getOuId(), userRoleInfoMap.getWorkspaceId()); - Set allMatchedProductFeatures = new HashSet<>(); - Set allAuthFeatures = new HashSet<>(); - - //聚合实际授权的权限:角色权限和产品权限交集 - for (SaasRoleRes role : userRoleInfoMap.getRoles()) { - //跳过超管和管理员 - if (RoleTypeEnum.SUPER_ADMIN.getValue().equals(role.getRoleType()) - || RoleTypeEnum.ADMIN.getValue().equals(role.getRoleType())) { - continue; - } - log.info("build permission for role:{}", role.getId()); - - Set rolePermissions = Optional.ofNullable(role.getPermissionRelations()) - .map(e -> e.stream() - .filter(Objects::nonNull) - .map(f -> FeatureWrapper.builder() - .featureId(f.getFeatureId()) - .type(f.getType()) - .build()) - .collect(Collectors.toSet())) - .orElseGet(Sets::newHashSet); - //角色标签类型匹配产品标签类型 - Set productPermissions = productFeatures.stream() - .filter(productFeatureRelationVO -> Objects.equals(productFeatureRelationVO.getDictCode(), String.valueOf(role.getProductUnitType()))) - .map(e -> FeatureWrapper.builder() - .featureId(e.getFeatureId()) - .type(e.getType()) - .build()) - .collect(Collectors.toSet()); - allMatchedProductFeatures.addAll(productPermissions); - // 产品对应权限点 与 角色权限点 取交集 - Collection resultHashAuthPointId = CollectionUtil.intersection(productPermissions, rolePermissions); - if (CollectionUtil.isNotEmpty(resultHashAuthPointId)) { - log.info("add auth permission for role:{}", role.getId()); - allAuthFeatures.addAll(resultHashAuthPointId); - } - } - if (CollectionUtil.isEmpty(allMatchedProductFeatures)) { - log.info("no normal roles found"); - return allAuthFeatures; - } - - Set newFeatureNoAuth = listNoAuthFeatureResources(allMatchedProductFeatures); - - Set oldFeatureNoAuth = listNoAuthFeatures(allMatchedProductFeatures); - allAuthFeatures.addAll(newFeatureNoAuth); - allAuthFeatures.addAll(oldFeatureNoAuth); - return allAuthFeatures; - } - - private Set listNoAuthFeatures(Set featureWrappers) { - List featureIds = featureWrappers.stream() - .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) - .map(FeatureWrapper::getFeatureId) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(featureIds)) { - return Collections.emptySet(); - } - - return permissionPointService.queryList(PermissionPointListQueryRequest.builder() - .ids(featureIds) - .delegatedType(DelegatedType.NO_NEED.getCode()) - .build()) - .stream() - .map(e -> FeatureWrapper.builder() - .featureId(e.getPermissionPointId()) - .type(OLD_FEATURE) - .build()) - .collect(Collectors.toSet()); - } - - private Set listNoAuthFeatureResources(Set featureWrappers) { - List featureIds = featureWrappers.stream() - .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) - .map(FeatureWrapper::getFeatureId) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(featureIds)) { - return Collections.emptySet(); - } - - PageSaasFeatureResourceReq pageSaasFeatureResourceReq = PageSaasFeatureResourceReq.builder() - .ids(featureIds) - .authType(FeatureResourceAuthType.ALL_ROLE.getCode()) - .build(); - return saasFeatureResourceService.list(pageSaasFeatureResourceReq).stream() - .map(e -> FeatureWrapper.builder() - .featureId(e.getId()) - .type(NEW_FEATURE) - .build()) - .collect(Collectors.toSet()); - } - - private List listNewFeatures(Set featureWrappers) { - List featureIds = featureWrappers.stream() - .filter(e -> Objects.equals(e.getType(), NEW_FEATURE)) - .map(FeatureWrapper::getFeatureId) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(featureIds)) { - return Collections.emptyList(); - } - - // 因为新版本配置权限点的时候,会在选中某个权限节点时,把所有父节点也冗余到权限里,所以只需要查询权限点信息 - return saasFeatureResourceService.list(PageSaasFeatureResourceReq.builder() - .ids(featureIds) - .needFeatureCodes(true) - .build()) - .stream() - .filter(e -> !CollectionUtils.isEmpty(e.getFeatureCodes())) - .map(e -> - // 兼容历史情况,根据featureCode组装数据 - e.getFeatureCodes().stream() - .map(featureCode -> IdentityAuthRes.PermissionPoint.builder() - .featureCode(featureCode) - .featureId(e.getId()) - .terminal(e.getTerminal()) - .build()) - .collect(Collectors.toList())) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - } - - private List listOldFeatures(Set featureWrappers) { - Set featureIds = featureWrappers.stream() - .filter(e -> Objects.equals(e.getType(), OLD_FEATURE)) - .map(FeatureWrapper::getFeatureId) - .collect(Collectors.toSet()); - - if (CollectionUtils.isEmpty(featureIds)) { - return Collections.emptyList(); - } - - return permissionPointService.listPermissionByIds( - QueryPermissionByIdsReq.builder() - .ids(featureIds) - .includeParent(true) - .build()); - } - - public ListIdentityFromPermissionResp listIdentityFromPermissionFromDB(ListIdentityFromPermissionReq req) { - ListIdentityFromPermissionResp result = new ListIdentityFromPermissionResp(); - result.setOuId(req.getOuId()); - result.setWorkspaceId(req.getWorkspaceId()); - - Set newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCode())); - - //code查询权限点信息 - List features = permissionPointService.listNodeWithChildrenByCodes(Lists.newArrayList(newFeatureCodes), req.getTerminal()); - - // 兼容新老版本,需要通过featureCode查询新版本的features,原逻辑是查询当前菜单资源的所有子数据 - ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() - .featureCodes(newFeatureCodes) - .terminal(req.getTerminal()) - .build(); - List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); - - if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) { - log.warn("no features data found for:{}", req.getFeatureCode()); - return result; - } - //是否免授权权限点 - Optional freeFeature = features.stream() - .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) - .findAny(); - - Optional freeFeatureResource = saasFeatureResources.stream() - .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) - .findFirst(); - - if (freeFeature.isPresent() || freeFeatureResource.isPresent()) { - log.warn("free feature found : featureId:{}, featureResourceId:{}", - freeFeature.map(SaasFeature::getId).orElse(null), - freeFeatureResource.map(SaasFeatureResourceResp::getId).orElse(null)); - throw new ServiceException("不能查询免授权权限点人员"); - } - - Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - Set newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet()); - - List featureIdPairs = Lists.newArrayList(); - if (!CollectionUtils.isEmpty(featureIds)) { - featureIdPairs.add(FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build()); - } - - if (!CollectionUtils.isEmpty(newFeatureIds)) { - featureIdPairs.add(FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build()); - } - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) - .featureIdPairs(featureIdPairs) - .build(); - List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam) - .stream() - .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - if (CollectionUtil.isEmpty(workspaceProducts)) { - log.warn("no matched product feature in workspace"); - return result; - } - - List matchedUsers = getWorkspaceUser(req.getWorkspaceId(), req.getOuId(), workspaceProducts); - if (CollectionUtil.isEmpty(matchedUsers)) { - return result; - } - result.setUsers(matchedUsers); - return result; - } - - public List listWorkspacePermissionIdentityFromDB(WorkspacePermissionIdentityReq req) { - - Set newFeatureCodes = featureCodeUtil.resolveFeatureCode(Sets.newHashSet(req.getFeatureCodes())); - req.setFeatureCodes(Lists.newArrayList(newFeatureCodes)); - - //code查询权限点信息 - List features = permissionPointService.listNodeWithChildrenByCodes(req.getFeatureCodes(), null); - - // 兼容新老版本,需要通过featureCode查询新版本的features,原逻辑是查询当前菜单资源的所有子数据 - ListSaasFeatureResourceParam listSaasFeatureResourceParam = ListSaasFeatureResourceParam.builder() - .featureCodes(Sets.newHashSet(req.getFeatureCodes())) - .build(); - List saasFeatureResources = listSaasFeatureResource(listSaasFeatureResourceParam); - - if (CollectionUtil.isEmpty(features) && CollectionUtils.isEmpty(saasFeatureResources)) { - log.warn("no features data found for:{}", req.getFeatureCodes()); - return Collections.emptyList(); - } - Set featureIds = features.stream().map(SaasFeature::getId).collect(Collectors.toSet()); - Set newFeatureIds = saasFeatureResources.stream().map(SaasFeatureResourceResp::getId).collect(Collectors.toSet()); - List featureIdPairs = Lists.newArrayList(); - - if (!CollectionUtils.isEmpty(featureIds)) { - featureIdPairs.add(FeatureIdPair.builder().featureIds(featureIds).type(OLD_FEATURE).build()); - } - - if (!CollectionUtils.isEmpty(newFeatureIds)) { - featureIdPairs.add(FeatureIdPair.builder().featureIds(newFeatureIds).type(NEW_FEATURE).build()); - } - WorkspaceProductService.WorkspaceProductParam workspaceProductParam = WorkspaceProductService.WorkspaceProductParam.builder() - .workspaceIds(Sets.newHashSet(req.getWorkspaceId())) - .featureIdPairs(featureIdPairs) - .build(); - List workspaceProducts = workspaceProductService.listWorkspaceProduct(workspaceProductParam) - .stream() - .map(WorkspaceProductService.WorkspaceProduct::getSaasProductModuleFeatureRelations) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - if (CollectionUtil.isEmpty(workspaceProducts)) { - log.warn("no matched feature in workspace product"); - return Collections.emptyList(); - } - - //是否免授权权限点 - Set matchedOldFeatureIds = workspaceProducts.stream() - .filter(e -> Objects.equals(OLD_FEATURE, e.getType())) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - Optional freeFeature = features.stream() - .filter(f -> matchedOldFeatureIds.contains(f.getId())) - .filter(f -> DelegatedType.NO_NEED.sameCode(f.getDelegatedType())) - .findAny(); - - Set matchedNewFeatureIds = workspaceProducts.stream() - .filter(e -> Objects.equals(NEW_FEATURE, e.getType())) - .map(SaasProductModuleFeatureRelation::getFeatureId) - .collect(Collectors.toSet()); - - Optional freeFeatureResource = saasFeatureResources.stream() - .filter(f -> matchedNewFeatureIds.contains(f.getId())) - .filter(e -> SaasFeatureResource.AuthType.isAllRole(e.getAuthType())) - .findFirst(); - if (freeFeature.isPresent() || freeFeatureResource.isPresent()) { - throw new ServiceException("免授权权限点调用查人接口"); - } - - //从相关角色查询用户-超管和普通角色 - List users = getWorkspaceUser(req.getWorkspaceId(), null, workspaceProducts); - if (CollectionUtil.isEmpty(users)) { - return Collections.emptyList(); - } - //按ou分组返回 - List result = new ArrayList<>(); - Map> userMap = users.stream() - .collect(Collectors.groupingBy(ListIdentityFromPermissionResp.UserVO::getOuId)); - for (Map.Entry> entry : userMap.entrySet()) { - result.add(ListIdentityFromPermissionResp.builder() - .workspaceId(req.getWorkspaceId()) - .ouId(entry.getKey()) - .users(entry.getValue()) - .build()); - } - return result; - } } diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java index edda0de6..9e4b58aa 100644 --- a/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java +++ b/tyr-server/src/main/java/cn/axzo/tyr/server/utils/RpcInternalUtil.java @@ -82,6 +82,26 @@ public class RpcInternalUtil { return result; } + public static ApiListResult rpcApiListResultProcessor(Supplier> supplier, String operationType, Object... param) { + + return rpcApiListResultProcessorMayThrow(supplier, operationType, (commonResponse) -> { + throw new ServiceException(commonResponse.getMsg()); + }, param); + } + + public static ApiListResult rpcApiListResultProcessorMayThrow(Supplier> supplier, String operationType, Consumer> throwConsumer, Object... param) { + AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空"); + log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param)); + ApiListResult result = supplier.get(); + log.info(operationType + "-Result: " + JSONUtil.toJsonStr(result)); + Assert.notNull(result, "服务调用异常"); + // 200自定义处理 + if (HttpStatus.HTTP_OK != result.getCode()) { + throwConsumer.accept(result); + } + return result; + } + public static T checkAndGetData(ApiResult result) { if (result.isError()) { throw new BizException(result.getRespCode(), result.getMsg()); diff --git a/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml b/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml index 709bfb38..b5c71a6c 100644 --- a/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml +++ b/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml @@ -16,7 +16,7 @@