Merge branch 'release/20241127' into 'master'

Release/20241127

See merge request universal/infrastructure/backend/tyr!327
This commit is contained in:
李龙 2024-11-27 07:32:11 +00:00
commit 87f375f2dc
58 changed files with 1427 additions and 1909 deletions

View File

@ -101,6 +101,7 @@ public interface TyrSaasAuthApi {
/**
*
* 通过资源ID资源类型角色分类 查询权限
* 该分类下不能有管理员角色原始代码没有实现管理员角色的权限
* @param listPermissionFromRoleGroupReq
* @return
*/

View File

@ -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<List<SaasRoleUserV2DTO>> roleUserListV2(@RequestBody @Valid ListRoleUserRelationParam param);
/**
* 用户角色page接口
* @param request
* @return
*/
@PostMapping("/api/saasRoleUser/page")
ApiResult<PageResp<SaasRoleUserV2DTO>> page(@RequestBody PageRoleUserRelationParam request);
/**
* 批量查询超管, 只能批量获取单个工作台台下的超管业务系统需要根据返回的identityId和identityType查询identityProfile查询用户明细信息
*/

View File

@ -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<RolePermissionTagEnum> tags;
public String buildKey() {
return ouId + "_" + workspaceId;
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -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<Long> roleIds;
private Set<Role> roles;
/** 授权类型 0-全部角色 1-指定角色 **/
private Integer authType;
private String terminal;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Role {
private Long roleId;
/**
* 权限标签默认为JOINED
*/
private Set<RolePermissionTagEnum> tags;
}
}

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -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<IdentityAuthRes.WorkspacePermission> 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<RolePermissionTagEnum> tags;
public String buildOuWorkspaceKey() {
return this.getOuId() + "_" + this.getWorkspaceId();
}

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -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;
}

View File

@ -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;
/**
* 通过角色分组及分类查询人员的权限

View File

@ -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<RolePermissionTagEnum> permissionTags;
/**
* 是否需要角色对应的角色分组信息
*/

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -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<FeatureIdPair> featureIdPairs;
@CriteriaField(ignore = true)
private Set<RolePermissionTagEnum> tags;
}

View File

@ -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和cmpcm端没有给端给了会有问题
*/
private String terminal;
/**
* 权限标签
*/
private Set<RolePermissionTagEnum> tags;
}

View File

@ -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;
}

View File

@ -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<String> featureCodes;
private Set<RolePermissionTagEnum> tags;
}

View File

@ -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<String> roleCodes;
private Set<Long> roleIds;
/**
* 兼容
*/
private List<Role> roles;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Role {
private Long roleId;
private String roleCode;
private Set<RolePermissionTagEnum> tags;
private RoleTypeEnum roleType;
}
@JsonIgnore
@Override

View File

@ -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;
/** 0saas_feature,1:saas_feature_resource **/
private Integer relationType;
private Set<RolePermissionTagEnum> tags;
}
public String buildOuWorkspaceKey() {
return this.getOuId() + "_" + this.getWorkspaceId();
}
}

View File

@ -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;
}

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -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<RolePermissionTagEnum> tags;
}

View File

@ -78,4 +78,6 @@ public class SaasRoleUserRelationDTO {
private String roleType;
private String roleCode;
private String roleName;
}

View File

@ -34,6 +34,8 @@ public class PageRoleUserRelationReq{
private Boolean includeDelete;
@NotEmpty(message = "roleIds不能为空")
// @NotEmpty(message = "roleIds不能为空")
private Set<Long> roleIds;
private Set<Long> personIds;
}

View File

@ -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<Long> selectedPPIds;
/**
* 新的oms权限
* 角色对应的权限
* selectedPPIdspermissionIdspermissions只能选一个
*/
private Set<Long> permissionIds;
private Set<Permission> permissions;
/**
* '角色编码'
@ -103,4 +105,14 @@ public class SaveOrUpdateRoleVO {
*/
private String workspaceTypeCode;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Permission {
private Long permissionId;
private Set<RolePermissionTagEnum> tags;
}
}

View File

@ -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<Void> refreshPgroupPermissionRelation(@Validated @RequestBody RefreshPgroupPermissionRelationParam request) {

View File

@ -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,6 +671,100 @@ public class PrivateRoleController {
return "ok";
}
@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<SaasRoleRes> allSuperAdminRoles = roleService.list(listRoleReq);
if (CollectionUtils.isEmpty(allSuperAdminRoles)) {
return "ok";
}
Set<Long> hasRoleIds = saasPgroupRoleRelationDao.lambdaQuery()
.in(SaasPgroupRoleRelation::getRoleId, Lists.transform(allSuperAdminRoles, SaasRoleRes::getId))
.list()
.stream()
.map(SaasPgroupRoleRelation::getRoleId)
.collect(Collectors.toSet());
List<SaasRoleRes> initRoles = allSuperAdminRoles.stream()
.filter(role -> !hasRoleIds.contains(role.getId()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(initRoles)) {
return "ok";
}
List<SaasPermissionGroup> 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<SaasPgroupRoleRelation> 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<SaasPgroupPermissionRelation> relations = saasPgroupPermissionRelationService.lambdaQuery()
.eq(SaasPgroupPermissionRelation::getType, NEW_FEATURE)
.in(SaasPgroupPermissionRelation::getTerminal, Lists.newArrayList("NT_CMS_WEB_GENERAL", "NT_CMP_APP_GENERAL"))
.list();
List<Long> 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

View File

@ -97,7 +97,6 @@ public class PermissionQueryController implements PermissionQueryApi {
@Override
public ApiResult<List<ListPermissionFeatureResp>> listPermission(ListPermissionFeatureReq req) {
return ApiResult.ok(permissionService.listPermission(req));
}
}

View File

@ -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();
}

View File

@ -192,6 +192,11 @@ public class RoleUserController implements TyrSaasRoleUserApi {
return ApiResult.ok(saasRoleUserRelationService.listV2(param));
}
@Override
public ApiResult<PageResp<SaasRoleUserV2DTO>> page(PageRoleUserRelationParam param) {
return ApiResult.ok(saasRoleUserRelationService.page(param));
}
@Override
public ApiResult<Void> createSuperAdminRole(CreateSuperAdminRoleParam param) {
saasRoleUserService.createSuperAdminRole(param);
@ -343,7 +348,12 @@ public class RoleUserController implements TyrSaasRoleUserApi {
}
return saasRoleUserRelationService.listV2(ListRoleUserRelationParam.builder()
.roleIds(Lists.newArrayList(param.getRoleIds()))
.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())

View File

@ -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<Long> 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<Long> roleIds = roleService.list(listSaasRoleParam).stream()
.map(SaasRoleRes::getId)

View File

@ -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<Long> 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<Long> roleIds = roleService.list(listSaasRoleParam).stream()
.map(SaasRoleRes::getId)

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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<Long> 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);
}
}

View File

@ -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<Long> 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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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<SaasPgroupPermissionRelation> {
public static final Integer OLD_FEATURE = 0;
@ -70,6 +76,12 @@ public class SaasPgroupPermissionRelation extends BaseEntity<SaasPgroupPermissio
*/
private String terminal;
/**
* 标签
*/
@TableField(value = "tags", typeHandler = TagTypeHandler.class)
private Set<RolePermissionTagEnum> tags;
/**
* 获取主键值
*
@ -87,5 +99,28 @@ public class SaasPgroupPermissionRelation extends BaseEntity<SaasPgroupPermissio
SaasPgroupPermissionRelation that = (SaasPgroupPermissionRelation) o;
return Objects.equals(groupId, that.groupId) && Objects.equals(featureId, that.featureId);
}
@MappedTypes({Object.class})
@MappedJdbcTypes({JdbcType.VARCHAR})
public static class TagTypeHandler extends AbstractJsonTypeHandler<Object> {
private Class<Object> type;
public TagTypeHandler(Class<Object> 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);
}
}
}

View File

@ -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数据结构
* redisKeyfeatureCode
* redisValue: roleId
* @param param
*/
void cachePermissionRole(CachePermissionRoleParam param);
/**
* 根据权限码查询对应的角色信息
* @param param
* @return
*/
List<PermissionRole> listPermissionRole(ListPermissionRoleParam param);
/**
* 缓存权限码跟产品和单位类型的信息采用set数据结构
* redisKey: featureCode
* redisValue: 产品信息
* @param param
*/
void cachePermissionProduct(CachePermissionProductParam param);
/**
* 根据权限码查询对应的产品信息
* 一个权限点对应的产品数据比较少一般10多个所以没有聚合返回方便排查哪些权限点已经在redis中不用从数据库中查询
* @param param
* @return
*/
List<PermissionProduct> listPermissionProduct(ListPermissionProductParam param);
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class HasPermissionRoleParam {
private List<String> featureCodes;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class ListPermissionRoleParam {
private List<String> featureCodes;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class CachePermissionRoleParam {
private List<PermissionRole> permissionRoles;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class PermissionRole {
/**
* 权限码
*/
private String featureCode;
/**
* 角色id
*/
private List<Long> roleIds;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class ListPermissionProductParam {
private List<String> featureCodes;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class CachePermissionProductParam {
private List<PermissionProduct> permissionProducts;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class PermissionProduct {
/**
* 权限码
*/
private String featureCode;
/**
* 产品信息
*/
private List<Product> products;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class Product {
/**
* 产品id
*/
private Long productId;
/**
* 单位类型
*/
private Integer ouType;
}
}

View File

@ -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<ResolvePermissionDTO> resolvePermissionTag(ResolvePermissionTagParam param);
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class ResolvePermissionTagParam {
private List<PersonPermission> 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<RolePermissionTagEnum> tags;
}
}

View File

@ -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<Long> roleIds;
private Set<String> featureCodes;
private Set<RolePermissionTagEnum> tags;
}
@Data
@ -70,5 +73,12 @@ public interface RolePermissionCacheService {
private String terminal;
private Integer featureType;
/**
* 权限点标签
* 在职:JOINED
* 离场:LEAVE
*/
private Set<RolePermissionTagEnum> tags;
}
}

View File

@ -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<RolePermissionTagEnum> tags;
}
}

View File

@ -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<ListPermissionFromRoleGroupResp> 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();
}

View File

@ -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<Long, List<String>> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds);
Map<Long, List<FeatureResourceTreeNode.Role>> featureResourceRoleCodeMap = getFeatureResourceRoleCodeMap(allFeatureResourceIds);
List<FeatureResourceTreeNode> dtoList = BeanMapper.copyList(resourceList, FeatureResourceTreeNode.class);
dtoList.forEach(e -> e.setRoleCodes(featureResourceRoleCodeMap.get(e.getId())));
dtoList.forEach(e -> {
List<FeatureResourceTreeNode.Role> 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<String> roleCodes,
Long operatorId, Set<Long> syncedRoleFeatureResourceIds) {
private RelationOperateLogResourceBindRoleDO doFeatureResourceRole(SaasFeatureResource featureResource,
FeatureResourceTreeNode treeNode,
Long operatorId,
Set<Long> 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<String> roleCodes = CollectionUtils.emptyIfNull(treeNode.getRoles()).stream()
.map(FeatureResourceTreeNode.Role::getRoleCode)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(roleCodes)) {
return logResourceBindRoleDO;
}
// List<String> existRoleCodes = getFeatureResourceRoleCodeMap(Lists.newArrayList(featureResource.getId()))
// .get(featureResource.getId());
//
// if (CollectionUtils.isNotEmpty(existRoleCodes)) {
// roleCodes.removeAll(existRoleCodes);
// }
// if (CollectionUtils.isEmpty(roleCodes)) {
// return;
// }
List<SaasRole> saasRoles = saasRoleDao.listByRoleCodes(roleCodes);
if (CollectionUtils.isEmpty(saasRoles)) {
return logResourceBindRoleDO;
}
Map<String, FeatureResourceTreeNode.Role> sourceRoleMap = treeNode.getRoles().stream()
.collect(Collectors.toMap(FeatureResourceTreeNode.Role::getRoleCode, Function.identity(), (f, s) -> s));
List<SaasPgroupRoleRelation> saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(saasRoles.stream().map(BaseEntity::getId).collect(Collectors.toList()));
Map<Long, SaasPgroupRoleRelation> pgroupRoleMap = saasPgroupRoleRelations.stream()
.collect(Collectors.toMap(SaasPgroupRoleRelation::getGroupId, Function.identity()));
Map<Long, SaasRole> localRoleMap = saasRoles.stream()
.collect(Collectors.toMap(SaasRole::getId, Function.identity()));
Set<Long> groupIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toSet());
List<Long> 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<Long, List<String>> getFeatureResourceRoleCodeMap(List<Long> allFeatureResourceIds) {
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
private static class PermissionGroupRoleWrapper {
private Long featureId;
private String roleCode;
private Set<RolePermissionTagEnum> tags;
}
private Map<Long, List<FeatureResourceTreeNode.Role>> getFeatureResourceRoleCodeMap(List<Long> allFeatureResourceIds) {
allFeatureResourceIds = allFeatureResourceIds.stream().distinct().collect(Collectors.toList());
List<SaasPgroupPermissionRelation> permissionRelations = saasPgroupPermissionRelationDao.lambdaQuery()
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value)
@ -414,9 +456,6 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic
return Collections.emptyMap();
}
Map<Long, List<Long>> featureIdToGroupIdsMap = permissionRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getFeatureId,
Collectors.mapping(SaasPgroupPermissionRelation::getGroupId, Collectors.toList())));
Map<Long, List<Long>> groupIdToRoleIdsMap = roleRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId,
@ -429,18 +468,35 @@ public class FeatureResourceSyncServiceImpl implements FeatureResourceSyncServic
}
}
Map<Long, List<String>> featureRoleMap = new HashMap<>();
featureIdToGroupIdsMap.forEach((featureId, groupIds) -> {
List<String> roleCodes = groupIds.stream()
.flatMap(groupId -> groupIdToRoleIdsMap.getOrDefault(groupId, Collections.emptyList()).stream())
.map(roleIdToRoleCodeMap::get)
.filter(StringUtils::isNotBlank)
return permissionRelations.stream()
.map(e -> {
List<Long> 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();
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
featureRoleMap.put(featureId, roleCodes);
});
return featureRoleMap;
})
.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())));
}

View File

@ -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<Object>() {
@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<PermissionRole> listPermissionRole(ListPermissionRoleParam param) {
if (CollectionUtils.isEmpty(param.getFeatureCodes())) {
return Collections.emptyList();
}
List<Object> redisValues = redisTemplate.executePipelined(new SessionCallback<Object>() {
@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<Object>() {
@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<PermissionProduct> listPermissionProduct(ListPermissionProductParam param) {
if (CollectionUtils.isEmpty(param.getFeatureCodes())) {
return Collections.emptyList();
}
List<Object> redisValues = redisTemplate.executePipelined(new SessionCallback<Object>() {
@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);
}
}

View File

@ -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<String> notAuthUniCodes;
@ -151,8 +132,14 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
}
List<Long> featureIds = permissions.stream()
.map(PermissionDO::getFeatureIds)
.filter(Objects::nonNull)
.flatMap(Set::stream)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(featureIds)) {
return Collections.emptyList();
}
//反查资源信息-仅页面
List<SaasFeatureResource> resourceList = featureResourceService.listNavByIds(featureIds, FeatureResourceType.pageTypes());
//查所有上级菜单
@ -206,19 +193,8 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
}
}
if (USE_OLD_AUTH) {
log.info("user old auth");
return hasPermissionV2(req);
}
log.info("user new auth");
List<CompletableFuture<Boolean>> 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);
}
//权限编码转ID
List<ResourcePermission> resourcePermissions = featureResourceService.permissionQuery(
ResourcePermissionQueryDTO.builder().featureCodes(req.getFeatureCodes()).build());
@ -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<Long> 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<SaasRoleUserV2DTO> listUserPermission(TreePermissionReq treePermissionReq, List<Long> featureIds) {
List<ListRoleUserRelationParam.WorkspaceOuPair> 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<Long> listUserPermissionFeatureIdsFromDB(TreePermissionReq treePermissionReq) {
List<Long> featureIds = resolveFeatureIds(treePermissionReq);
if (CollectionUtils.isNotEmpty(treePermissionReq.getUniCodes()) && CollectionUtils.isEmpty(featureIds)) {
return Collections.emptySet();
}
List<SaasRoleUserV2DTO> saasRoleUserV2DTOS = listUserPermission(treePermissionReq, featureIds);
// 用户可能没有角色
if (CollectionUtils.isEmpty(saasRoleUserV2DTOS)) {
return Collections.emptySet();
}
List<WorkspaceProductService.WorkspaceProduct> workspaceProducts = listWorkspaceProducts(treePermissionReq, featureIds);
//免授权
Set<Long> authFreeFeatureIds = listNotAuthFeatures(treePermissionReq);
//取交集确定权限
return mixFeatureIds(saasRoleUserV2DTOS, workspaceProducts, authFreeFeatureIds);
}
private Set<Long> mixFeatureIds(List<SaasRoleUserV2DTO> saasRoleUsers,
List<WorkspaceProductService.WorkspaceProduct> workspaceProducts,
Set<Long> authFreeFeatureIds) {
Map<Long, WorkspaceProductService.WorkspaceProduct> 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<WorkspaceProductService.WorkspaceProduct> listWorkspaceProducts(TreePermissionReq treePermissionReq,
List<Long> featureIds) {
//查询租户产品权限点
Set<Long> 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<TreePermissionResp> treePermission(TreePermissionReq req) {
Set<Long> allFeatureIds = Sets.newHashSet();
Set<Long> featureIds = resovlePermission(req);
Set<Long> featureIds = listUserPermissionFeatureIds(req);
Set<Long> defaultFeatureIds = listNotAuthFeatureIds(req);
allFeatureIds.addAll(featureIds);
@ -557,20 +421,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
.collect(Collectors.toList());
}
private Set<Long> resovlePermission(TreePermissionReq req) {
if (tyrSaasAuthService.permissionFromDB()) {
return listUserPermissionFeatureIdsFromDB(req);
}
try {
return listUserPermissionFeatureIds(req);
} catch (Exception ex) {
log.error("查询权限异常,执行降级处理");
return listUserPermissionFeatureIdsFromDB(req);
}
}
private List<SaasFeatureResourceResp> filterFeature(List<SaasFeatureResourceResp> 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<WorkspaceOUPair> 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<String, PermissionTagService.ResolvePermissionDTO> 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<Long> listUserPermissionFeatureIds(TreePermissionReq treePermissionReq) {
List<SaasFeatureResourceService.SaasFeatureResourceCache> allFeatureResources = listAllFeatureResources(treePermissionReq);
@ -875,7 +770,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
return Collections.emptySet();
}
List<SaasRoleUserV2DTO> saasRoleUsers = listUserPermission(treePermissionReq);
assembleTag(treePermissionReq);
List<SaasRoleUserV2DTO> saasRoleUsers = listUserRole(treePermissionReq);
if (CollectionUtils.isEmpty(saasRoleUsers)) {
return Collections.emptySet();
}
@ -890,7 +787,14 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
//免授权
Set<Long> authFreeFeatureIds = allFeatureResources.stream()
.filter(e -> BooleanUtils.isTrue(e.isNotAuth()))
.map(SaasFeatureResourceService.SaasFeatureResourceCache::getFeatureId)
.flatMap(e -> {
Set<Long> parentIds = e.getParentIds();
if (CollectionUtils.isEmpty(parentIds)) {
return Sets.newHashSet(e.getFeatureId()).stream();
}
parentIds.add(e.getFeatureId());
return parentIds.stream();
})
.collect(Collectors.toSet());
Set<Long> allFeatureIds = allFeatureResources.stream()
@ -906,16 +810,6 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
allFeatureIds);
}
private Set<Long> 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<WorkspaceProductService.WorkspaceProductFeatureSource> listWorkspaceProducts(TreePermissionReq treePermissionReq) {
//查询租户产品权限点
Set<Long> workspaceIds = treePermissionReq.getWorkspaceOUPairs().stream()
@ -931,7 +825,7 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
return workspaceProductService.listWorkspaceProductFeatureResourceCached(listWorkspaceProductFeatureSourceCacheParam);
}
private List<SaasRoleUserV2DTO> listUserPermission(TreePermissionReq treePermissionReq) {
private List<SaasRoleUserV2DTO> listUserRole(TreePermissionReq treePermissionReq) {
List<ListRoleUserRelationParam.WorkspaceOuPair> 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<String, WorkspaceOUPair> workspaceOuPairs = treePermissionReq.getWorkspaceOUPairs().stream()
.collect(Collectors.toMap(WorkspaceOUPair::buildKey, Function.identity(), (f, s) -> f));
return saasRoleUsers.stream()
.map(roleUser -> {
List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> productFeatureSources = workspaceProductMap.get(roleUser.getSaasRoleUser().getWorkspaceId())
@ -998,15 +895,32 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
SaasRoleUserV2DTO.SaasRole saasRole = roleUser.getSaasRole();
Set<Long> adminFeatureIds = resolveAdminRole(productFeatureSources, saasRole);
Set<Long> notAuthFeatureIds = resolveNotAuthFeatureIds(productFeatureSources, authFreeFeatureIds);
WorkspaceOUPair workspaceOUPair = workspaceOuPairs.get(roleUser.getSaasRoleUser().buildOuWorkspaceKey());
if (Objects.isNull(workspaceOUPair)) {
return null;
}
Set<Long> adminFeatureIds = resolveAdminRole(productFeatureSources, saasRole, workspaceOUPair);
Set<Long> notAuthFeatureIds = resolveNotAuthFeatureIds(productFeatureSources, authFreeFeatureIds);
List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO> 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<RolePermissionTagEnum> 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<Long> resolveAdminRole(List<ProductSaasFeatureResourceCacheService.FeatureResourceDTO> 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<Long> 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<Long> resolveNormalRole(WorkspaceProductService.WorkspaceProduct workspaceProduct,
SaasRoleUserV2DTO.SaasRole saasRole,
Set<Long> authFreeFeatureIds) {
//普通角色角色同类型的租户产品权限已分配 且角色上已分配 + 免授权
Set<Long> 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());
}
}

View File

@ -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<OrgUserStatusEnum, RolePermissionTagEnum> ORG_USER_TAGS = Maps.newHashMap();
static {
// 除了用户在项目下是离场状态要取离场权限其他为了兼容都取在场权限因为人岗架可能会新增状态其他删除这些状态会删除用户角色
ORG_USER_TAGS.put(OrgUserStatusEnum.LEAVE, RolePermissionTagEnum.LEAVE);
}
@Override
public List<ResolvePermissionDTO> resolvePermissionTag(ResolvePermissionTagParam param) {
if (CollectionUtils.isEmpty(param.getPersonPermissions())) {
return Collections.emptyList();
}
List<Long> personIds = param.getPersonPermissions().stream()
.map(PersonPermission::getPersonId)
.collect(Collectors.toList());
List<WorkspaceOuPair> 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> orgUserRes = RpcInternalUtil.rpcApiListResultProcessor(() -> orgUserApi.listOrgUser(orgUserListReq),
"查询人员在项目的状态", orgUserListReq).getData();
if (CollectionUtils.isEmpty(orgUserRes)) {
return Collections.emptyList();
}
Set<String> 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());
}
}

View File

@ -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<RolePermissionCacheService.PermissionDTO> 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());
})

View File

@ -162,6 +162,7 @@ public class RoleSaasFeatureResourceCacheServiceImpl implements RoleSaasFeatureR
.featureType(featureResource.getFeatureType())
.terminal(featureResource.getTerminal())
.uniCode(featureResource.getUniCode())
.tags(permissionRelation.getTags())
.build());
List<RoleSaasFeatureResourceCacheService.SaasFeatureResourceDTO> 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)

View File

@ -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<SaasRoleMapper, SaasRole>
List<SaveOrUpdateRoleVO.GroupInfoVO> 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<SaasRoleMapper, SaasRole>
// TODO 旧的权限,待权限切完后就下掉
List<SaasFeature> saasFeatures = validFeature(saveOrUpdateRole.getSelectedPPIds());
// 新的权限
List<ResourcePermission> saasFeatureResources = validPermission(saveOrUpdateRole.getPermissionIds());
List<ResourcePermission> saasFeatureResources = validPermission(saveOrUpdateRole.getPermissions());
saasRoleDao.saveOrUpdate(saasRole);
// 新增或者保存分组和角色映射关系
@ -590,8 +590,8 @@ public class RoleServiceImpl extends ServiceImpl<SaasRoleMapper, SaasRole>
private void saveOperateLog4RoleBindFeature(SaveOrUpdateRoleVO saveOrUpdateRole) {
SaasRole saasRole = saasRoleDao.getById(saveOrUpdateRole.getId());
List<String> 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<SaasRoleMapper, SaasRole>
private void saveSaasFeatureResourcePermission(SaveOrUpdateRoleVO saveOrUpdateRole,
List<ResourcePermission> resourcePermissions,
SaasPermissionGroup saasPermissionGroup) {
if (CollectionUtils.isEmpty(saveOrUpdateRole.getPermissionIds())) {
if (CollectionUtils.isEmpty(saveOrUpdateRole.getPermissions())) {
return;
}
@ -630,17 +630,19 @@ public class RoleServiceImpl extends ServiceImpl<SaasRoleMapper, SaasRole>
.collect(Collectors.toMap(ResourcePermission::getId, Function.identity()));
// 保存权限集和权限点映射关系
List<SaasPgroupPermissionRelation> pgpRelations = saveOrUpdateRole.getPermissionIds().stream()
.map(ppId -> {
ResourcePermission resourcePermission = resourcePermissionMap.get(ppId);
List<SaasPgroupPermissionRelation> 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<SaasRoleMapper, SaasRole>
return Collections.emptyMap();
}
List<SaasPgroupPermissionRelation> 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<SaasPgroupPermissionRelation> 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<Long, SaasPermissionRes> resourcePermissions = saasFeatureResourceService.permissionQuery(ResourcePermissionQueryDTO.builder()
Map<Long, ResourcePermission> 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<Long, List<Long>> pgroupPermissions = saasPgroupPermissionRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId,
Collectors.mapping(SaasPgroupPermissionRelation::getFeatureId, Collectors.toList())));
Map<Long, List<SaasPgroupPermissionRelation>> pgroupPermissions = saasPgroupPermissionRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId));
return saasPgroupRoleRelations.stream()
.map(e -> {
List<Long> permissionIds = pgroupPermissions.get(e.getGroupId());
if (CollectionUtils.isEmpty(permissionIds)) {
List<SaasPgroupPermissionRelation> 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<SaasRoleMapper, SaasRole>
.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<SaasRoleMapper, SaasRole>
private Long roleId;
private Set<RolePermissionTagEnum> 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<SaasRoleMapper, SaasRole>
.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<SaasRoleMapper, SaasRole>
}
Set<Long> 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<Long> featureIds = req.stream()
@ -1694,7 +1712,7 @@ public class RoleServiceImpl extends ServiceImpl<SaasRoleMapper, SaasRole>
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<SaasRoleMapper, SaasRole>
log.warn("save operate log error", e);
}
} else {
List<Long> existGroupIds = saasPgroupPermissionRelationDao.queryByFeatureIds(Collections.singletonList(item.getFeatureId()))
.stream().map(SaasPgroupPermissionRelation::getGroupId).collect(Collectors.toList());
List<SaasPgroupPermissionRelation> saasPgroupPermissionRelations = saasPgroupPermissionRelationDao.queryByFeatureIds(Collections.singletonList(item.getFeatureId()));
Set<Long> existGroupIds = saasPgroupPermissionRelations.stream().map(SaasPgroupPermissionRelation::getGroupId).collect(Collectors.toSet());
List<Long> groupIds = saasPgroupRoleRelationDao.findByRoleIds(item.getRoleIds())
.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toList());
List<Long> insertGroupIds = groupIds.stream().filter(role -> !existGroupIds.contains(role)).collect(Collectors.toList());
List<Long> roleIds = item.getRoles().stream()
.map(FeatureRoleRelationReq.Role::getRoleId)
.collect(Collectors.toList());
List<SaasPgroupRoleRelation> saasPgroupRoleRelations = saasPgroupRoleRelationDao.findByRoleIds(roleIds);
Set<Long> groupIds = saasPgroupRoleRelations.stream().map(SaasPgroupRoleRelation::getGroupId).collect(Collectors.toSet());
List<Long> deleteGroupIds = existGroupIds.stream().filter(role -> !groupIds.contains(role)).collect(Collectors.toList());
// 这里可能会导致featureIdgroupId相同的记录有多条原因是不同的角色可能有相同的权限集原来使用的是list来解析新增的数据
List<SaasPgroupRoleRelation> insert = saasPgroupRoleRelations.stream()
.filter(e -> !existGroupIds.contains(e.getGroupId()))
.collect(Collectors.toList());
Map<Long, FeatureRoleRelationReq.Role> roles = item.getRoles().stream()
.collect(Collectors.toMap(FeatureRoleRelationReq.Role::getRoleId, Function.identity(), (f, s) -> f));
Map<Long, SaasPgroupPermissionRelation> 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<SaasPgroupPermissionRelation> insertRelation = new ArrayList<>();
insertGroupIds.forEach(groupId -> {
if (CollectionUtils.isNotEmpty(insert)) {
Set<SaasPgroupPermissionRelation> insertRelation = insert.stream()
.map(group -> {
FeatureRoleRelationReq.Role role = roles.get(group.getRoleId());
SaasPgroupPermissionRelation relation = new SaasPgroupPermissionRelation();
relation.setFeatureId(item.getFeatureId());
relation.setGroupId(groupId);
relation.setGroupId(group.getGroupId());
relation.setCreateBy(operatorId);
relation.setFeatureType(item.getFeatureType());
relation.setType(NEW_FEATURE);
relation.setTerminal(item.getTerminal());
insertRelation.add(relation);
});
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<SaasRoleMapper, SaasRole>
.build());
}
private void updatePgroupPermissionRelation(Long operatorId,
FeatureRoleRelationReq.RelationRoleSettings item,
List<SaasPgroupRoleRelation> saasPgroupRoleRelations,
Map<Long, SaasPgroupPermissionRelation> existFeatureGroups,
Map<Long, FeatureRoleRelationReq.Role> roles) {
List<SaasPgroupPermissionRelation> 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<SaasRoleMapper, SaasRole>
return resp;
}
private List<ResourcePermission> validPermission(Set<Long> permissionIds) {
if (CollectionUtils.isEmpty(permissionIds)) {
private List<ResourcePermission> validPermission(Set<SaveOrUpdateRoleVO.Permission> permissions) {
if (CollectionUtils.isEmpty(permissions)) {
return Collections.emptyList();
}
List<Long> permissionIds = permissions.stream()
.map(SaveOrUpdateRoleVO.Permission::getPermissionId)
.collect(Collectors.toList());
List<ResourcePermission> 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<SaasRoleMapper, SaasRole>
return Collections.emptyMap();
}
List<SaasPgroupPermissionRelation> 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<SaasPgroupPermissionRelation> 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<Long> featureIds = Lists.transform(saasPgroupPermissionRelations, SaasPgroupPermissionRelation::getFeatureId);
Map<Long, SaasPermissionRes> 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<Long, SaasFeature> resourcePermissions = saasFeatureDao.listByIds(featureIds).stream()
.collect(Collectors.toMap(SaasFeature::getId, Function.identity()));
Map<Long, List<Long>> pgroupPermissions = saasPgroupPermissionRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId,
Collectors.mapping(SaasPgroupPermissionRelation::getFeatureId, Collectors.toList())));
Map<Long, List<SaasPgroupPermissionRelation>> pgroupPermissions = saasPgroupPermissionRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupPermissionRelation::getGroupId));
return saasPgroupRoleRelations.stream()
.map(e -> {
List<Long> permissionIds = pgroupPermissions.get(e.getGroupId());
if (CollectionUtils.isEmpty(permissionIds)) {
List<SaasPgroupPermissionRelation> 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<SaasRoleMapper, SaasRole>
.featureId(e.getFeatureId())
.type(e.getType())
.featureType(e.getFeatureType())
.tags(e.getTags())
.build(),
Collectors.toList())));
}
@ -1998,8 +2082,14 @@ public class RoleServiceImpl extends ServiceImpl<SaasRoleMapper, SaasRole>
private void saveOperateLog4RoleBindFeatureResource(SaveOrUpdateRoleVO saveOrUpdateRole) {
SaasRole saasRole = saasRoleDao.getById(saveOrUpdateRole.getId());
List<String> 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<SaasRoleMapper, SaasRole>
*/
private Integer featureType;
/**
* 权限点标签
* 在职:JOINED
* 离场:LEAVE
*/
private Set<RolePermissionTagEnum> tags;
public static SaasPermissionRelationWrapper from(SaasPgroupRoleRelation saasPgroupRoleRelation,
SaasPgroupPermissionRelation permissionRelation) {
if (permissionRelation == null) {
@ -2057,6 +2154,7 @@ public class RoleServiceImpl extends ServiceImpl<SaasRoleMapper, SaasRole>
.featureId(permissionRelation.getFeatureId())
.type(permissionRelation.getType())
.featureType(permissionRelation.getFeatureType())
.tags(permissionRelation.getTags())
.build();
}
}

View File

@ -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<SaasFeatureResou
}
private Map<Long, List<SaasRoleRes>> listRoles(DetailFeatureResourceReq detailFeatureResourceReq,
private Map<Long, List<FeatureResourceTreeNode.Role>> listRoles(DetailFeatureResourceReq detailFeatureResourceReq,
List<SaasFeatureResource> descendants) {
if (CollectionUtils.isEmpty(descendants) || BooleanUtils.isNotTrue(detailFeatureResourceReq.getNeedRole())) {
return Collections.emptyMap();
@ -257,6 +259,7 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl<SaasFeatureResou
List<SaasPgroupPermissionRelation> 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<SaasFeatureResou
return Collections.emptyMap();
}
Map<Long, SaasRoleRes> roles = roleService.list(ListRoleReq.builder()
Map<Long, List<Long>> groupRoleMap = saasPgroupRoleRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId,
Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList())));
Map<Long, SaasRoleRes> roleMap = roleService.list(ListRoleReq.builder()
.roleIds(Lists.transform(saasPgroupRoleRelations, SaasPgroupRoleRelation::getRoleId))
.build())
.stream()
.collect(Collectors.toMap(SaasRoleRes::getId, Function.identity()));
Map<Long, List<Long>> groupRoleMap = saasPgroupRoleRelations.stream()
.collect(Collectors.groupingBy(SaasPgroupRoleRelation::getGroupId,
Collectors.mapping(SaasPgroupRoleRelation::getRoleId, Collectors.toList())));
return relations.stream()
.map(e -> {
List<Long> roleIds = groupRoleMap.get(e.getGroupId());
@ -287,8 +290,15 @@ public class SaasFeatureResourceServiceImpl extends ServiceImpl<SaasFeatureResou
}
return Pair.of(e.getFeatureId(), roleIds.stream()
.map(roles::get)
.map(f -> 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<SaasFeatureResou
@Override
public FeatureResourceTreeNode getTreeFeatureDescendant(DetailFeatureResourceReq param) {
List<SaasFeatureResource> descendants = featureResourceDao.lambdaQuery()
LambdaQueryChainWrapper<SaasFeatureResource> 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<SaasFeatureResource> descendants = wrapper.list();
if (CollectionUtil.isEmpty(descendants)) {
return null;
}
Map<Long, List<SaasRoleRes>> roles = listRoles(param, descendants);
Map<Long, List<FeatureResourceTreeNode.Role>> roles = listRoles(param, descendants);
List<FeatureResourceTreeNode> 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<SaasFeatureResou
FeatureResourceTreeNode featureResourceTreeNode = treeList.get(0);
List<String> 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<SaasFeatureResou
return parent.getPath();
}
private void fillPageElement2PageFeatureResource(List<FeatureResourceTreeNode> featureResourceTreeNodes, List<String> allUniCodes) {
private void fillPageElement2PageFeatureResource(List<FeatureResourceTreeNode> featureResourceTreeNodes,
List<String> allUniCodes,
DetailFeatureResourceReq detailFeatureResourceReq) {
if (BooleanUtils.isNotTrue(detailFeatureResourceReq.getNeedPageElement())) {
return;
}
Map<String, List<PageElementBasicDTO>> uniCodeElementsMap = saasPageElementService.getByTerminalAndUniCodes(featureResourceTreeNodes.get(0).getTerminal(), allUniCodes)
.stream().collect(Collectors.groupingBy(PageElementBasicDTO::getUniCode));

View File

@ -318,9 +318,15 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
}
// 过滤用户有权限的featureCodes
List<IdentityAuthReq.WorkspaceOuPair> 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());

View File

@ -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<String, SaasPgroupPermissionRelation> existFeatureGroups = exists.stream()
.collect(Collectors.toMap(e -> e.getFeatureId() + "_" + e.getGroupId(), Function.identity()));
List<SaasPgroupPermissionRelation> 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());
}
if (CollectionUtils.isNotEmpty(param.getTags())) {
wrapper.and(j -> {
for (RolePermissionTagEnum tag : param.getTags()) {
j.or(k -> k.apply("json_contains(tags, '\"" + tag + "\"')"));
}
});
}
IPage<SaasPgroupPermissionRelation> page = this.page(PageConverter.toMybatis(param, SaasPgroupPermissionRelation.class), wrapper);

View File

@ -82,6 +82,26 @@ public class RpcInternalUtil {
return result;
}
public static <T> ApiListResult<T> rpcApiListResultProcessor(Supplier<ApiListResult<T>> supplier, String operationType, Object... param) {
return rpcApiListResultProcessorMayThrow(supplier, operationType, (commonResponse) -> {
throw new ServiceException(commonResponse.getMsg());
}, param);
}
public static <T> ApiListResult<T> rpcApiListResultProcessorMayThrow(Supplier<ApiListResult<T>> supplier, String operationType, Consumer<ApiListResult<T>> throwConsumer, Object... param) {
AssertUtil.notNull(throwConsumer, "自定义的异常处理不可为空");
log.info(operationType + "-Param: " + JSONUtil.toJsonStr(param));
ApiListResult<T> 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> T checkAndGetData(ApiResult<T> result) {
if (result.isError()) {
throw new BizException(result.getRespCode(), result.getMsg());

View File

@ -16,7 +16,7 @@
</select>
<select id="pageRoleUserRelation" resultType="cn.axzo.tyr.client.model.roleuser.dto.SaasRoleUserRelationDTO">
SELECT t1.*,t2.role_code,t2.role_type
SELECT t1.*,t2.role_code,t2.role_type,t2.name as roleName
FROM
saas_role_user_relation t1
left join
@ -61,6 +61,13 @@
</foreach>
</if>
<if test="param.personIds != null and param.personIds.size()>0">
AND t1.natural_person_id IN
<foreach collection="param.personIds" open="(" close=")" separator="," index="index" item="item">
#{item}
</foreach>
</if>
</where>
</select>