改造开源框架guns增加对数据内容访问权限的相关实现
使用guns框架已经有一段时间了,前端时间发现stylefeng发布了7.1.2的版本,对比之前的版本做了重大的改变,新架构的思想看起来很先进,刚好有新项目要做,所以决定用这个新版本来进行。
做了一部分之后发现,新版本的guns中好像未对数据内容的访问权限进行实现,只能自己研究实现了。
以下是实现步骤,在此做记录。
- 在kernel-d-auth中增加类,cn.stylefeng.roses.kernel.auth.api.util.DataScopePropertyUtil
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.enums.DataScopeTypeEnum;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.Set;
@Slf4j
public class DataScopePropertyUtil {
/**
* 设置查看权限属性
* @param object
*/
public static void setDataScopParam(Object object,SessionManagerApi sessionManagerApi){
String token = null;
try {
token = LoginContext.me().getToken();
} catch (Exception e) {
// 不做处理,因为本接口可能是不需要鉴权
}
LoginUser user = sessionManagerApi.getSession(token);
boolean isManage = user.getSuperAdmin();
if(!isManage){
try{
if(user.getDataScopeTypeEnums().contains(DataScopeTypeEnum.SELF)) {
Method method = object.getClass().getMethod("setDataScopeUserIds", Set.class);
if (method != null) {
method.invoke(object, new Object[]{user.getDataScopeUserIds()});
}
}
if(user.getDataScopeTypeEnums().contains(DataScopeTypeEnum.DEPT) || user.getDataScopeTypeEnums().contains(DataScopeTypeEnum.DEPT_WITH_CHILD)
|| user.getDataScopeTypeEnums().contains(DataScopeTypeEnum.DEFINE)) {
Method method = object.getClass().getMethod("setDataScopeOrganizationIds", Set.class);
if (method != null) {
if(user.getDataScopeOrganizationIds() != null)
method.invoke(object, new Object[]{user.getDataScopeOrganizationIds()});
}
}
}catch (Exception e){
log.error("setDataScopParam error. ",e);
}
}
}
}
- 增加属性,SysUserRequest HrOrganizationRequest
/**
* 用户数据范围用户信息
*/
@ChineseDescription("用户数据范围用户信息")
private Set<Long> dataScopeUserIds;
/**
* 用户数据范围组织信息
*/
@ChineseDescription("用户数据范围组织信息")
private Set<Long> dataScopeOrganizationIds;
- 修改HrOrganizationController
1). 增加成员变量
@Resource
private SessionManagerApi sessionManagerApi;
2). 增加访问权限赋值 DataScopePropertyUtil.setDataScopParam(hrOrganizationRequest,sessionManagerApi);
/**
* 获取全部系统组织机构树(用于新增,编辑组织机构时选择上级节点,用于获取用户管理界面左侧组织机构树)
*
* @author chenjinlong
* @date 2021/01/05 15:55
*/
@GetResource(name = "获取全部系统组织机构树", path = "/hrOrganization/tree", responseClass = OrganizationTreeNode.class)
public ResponseData organizationTree(HrOrganizationRequest hrOrganizationRequest) {
DataScopePropertyUtil.setDataScopParam(hrOrganizationRequest,sessionManagerApi);
return new SuccessResponseData(hrOrganizationService.organizationTree(hrOrganizationRequest));
}
/**
* 分页查询系统组织机构
*
* @author fengshuonan
* @date 2020/11/04 11:05
*/
@GetResource(name = "分页查询系统组织机构", path = "/hrOrganization/page", responseClass = HrOrganization.class)
public ResponseData page(HrOrganizationRequest hrOrganizationRequest) {
DataScopePropertyUtil.setDataScopParam(hrOrganizationRequest,sessionManagerApi);
return new SuccessResponseData(hrOrganizationService.findPage(hrOrganizationRequest));
}
- 修改HrOrganizationServiceImpl.java
/**
* 根据数据范围获取组织机构列表
*
* @author fengshuonan
* @date 2021/2/8 20:22
*/
private List<HrOrganization> findListByDataScope(HrOrganizationRequest hrOrganizationRequest) {
LambdaQueryWrapper<HrOrganization> queryWrapper = this.createWrapper(hrOrganizationRequest);
// 数据范围过滤
// 如果是超级管理员,或者数据范围权限是所有,则不过滤数据范围
boolean needToDataScope = true;
Set<DataScopeTypeEnum> dataScopeTypes = LoginContext.me().getLoginUser().getDataScopeTypeEnums();
if (LoginContext.me().getSuperAdminFlag() || (dataScopeTypes != null && dataScopeTypes.contains(DataScopeTypeEnum.ALL))) {
needToDataScope = false;
}
// 过滤数据范围的SQL拼接
if (needToDataScope) {
// 获取用户数据范围信息
Set<Long> dataScope = LoginContext.me().getLoginUser().getDataScopeOrganizationIds();
log.warn("##### "+Arrays.toString(dataScope.toArray()));
// 如果数据范围为空,则返回空数组
if (ObjectUtil.isEmpty(dataScope)) {
return new ArrayList<>();
}
// 根据组织机构数据范围的上级组织,用于展示完整的树形结构
//Set<Long> allLevelParentIdsByOrganizations = this.findAllLevelParentIdsByOrganizations(dataScope);
// 拼接查询条件
//queryWrapper.in(HrOrganization::getOrgId, allLevelParentIdsByOrganizations);
}
return this.list(queryWrapper);
}
@Override
public List<OrganizationTreeNode> organizationTree(HrOrganizationRequest hrOrganizationRequest) {
// 定义返回结果
List<OrganizationTreeNode> treeNodeList = CollectionUtil.newArrayList();
// 组装节点
List<HrOrganization> hrOrganizationList = this.findListByDataScope(hrOrganizationRequest);
// 最上层的父ID设置为-1
int pidsLen = -1;
HrOrganization p= null;
for (HrOrganization hrOrganization : hrOrganizationList) {
if(pidsLen == -1 || pidsLen > hrOrganization.getOrgPids().getBytes().length){
pidsLen = hrOrganization.getOrgPids().getBytes().length;
p = hrOrganization;
}
}
if(p != null){
p.setOrgParentId(-1l);
p.setOrgPids("[-1],");
}
for (HrOrganization hrOrganization : hrOrganizationList) {
OrganizationTreeNode treeNode = OrganizationFactory.parseOrganizationTreeNode(hrOrganization);
treeNodeList.add(treeNode);
}
// 设置树节点上,用户绑定的组织机构数据范围
if (hrOrganizationRequest.getUserId() != null) {
List<Long> orgIds = userServiceApi.getUserBindDataScope(hrOrganizationRequest.getUserId());
if (ObjectUtil.isNotEmpty(orgIds)) {
for (OrganizationTreeNode organizationTreeNode : treeNodeList) {
for (Long orgId : orgIds) {
if (organizationTreeNode.getId().equals(orgId)) {
organizationTreeNode.setSelected(true);
}
}
}
}
}
// 构建树并返回
return new DefaultTreeBuildFactory<OrganizationTreeNode>().doTreeBuild(treeNodeList);
}
/**
* 创建组织架构的通用条件查询wrapper
*
* @author fengshuonan
* @date 2020/11/6 10:16
*/
private LambdaQueryWrapper<HrOrganization> createWrapper(HrOrganizationRequest hrOrganizationRequest) {
LambdaQueryWrapper<HrOrganization> queryWrapper = new LambdaQueryWrapper<>();
// 查询未删除状态的
queryWrapper.eq(HrOrganization::getDelFlag, YesOrNotEnum.N.getCode());
// 根据排序升序排列,序号越小越在前
queryWrapper.orderByAsc(HrOrganization::getOrgSort);
if (ObjectUtil.isEmpty(hrOrganizationRequest)) {
return queryWrapper;
}
String orgName = hrOrganizationRequest.getOrgName();
String orgCode = hrOrganizationRequest.getOrgCode();
Long orgParentId = hrOrganizationRequest.getOrgParentId();
Long orgId = hrOrganizationRequest.getOrgId();
// 拼接组织机构名称条件
queryWrapper.like(ObjectUtil.isNotEmpty(orgName), HrOrganization::getOrgName, orgName);
// 拼接组织机构编码条件
queryWrapper.eq(ObjectUtil.isNotEmpty(orgCode), HrOrganization::getOrgCode, orgCode);
// 拼接父机构id查询条件
if (ObjectUtil.isNotEmpty(orgParentId)) {
queryWrapper.and(qw -> {
qw.eq(HrOrganization::getOrgId, orgParentId).or().like(HrOrganization::getOrgPids, orgParentId);
});
}
// 拼接机构id查询条件
queryWrapper.eq(ObjectUtil.isNotEmpty(orgId), HrOrganization::getOrgId, orgId);
if(hrOrganizationRequest.getOrgId() != null){
queryWrapper.inSql(HrOrganization::getOrgId,"select org_id from hr_organization where org_pids like '%"+hrOrganizationRequest.getOrgId()+"%' or org_id = "+hrOrganizationRequest.getOrgId());
}
if(hrOrganizationRequest.getDataScopeUserIds() != null){
queryWrapper.in(HrOrganization::getCreateUser,hrOrganizationRequest.getDataScopeUserIds());
}
if(hrOrganizationRequest.getDataScopeOrganizationIds() != null){
queryWrapper.in(HrOrganization::getOrgId,hrOrganizationRequest.getDataScopeOrganizationIds());
}
return queryWrapper;
}
- 修改 SysUserController
1). 增加成员
@Resource
private SessionManagerApi sessionManagerApi;
2).增加访问权限赋值 DataScopePropertyUtil.setDataScopParam(hrOrganizationRequest,sessionManagerApi);
/**
* 查询系统用户
*
* @author luojie
* @date 2020/11/6 13:49
*/
@GetResource(name = "系统用户_查询", path = "/sysUser/page",responseClass = SysUserDTO.class)
public ResponseData page(SysUserRequest sysUserRequest) {
DataScopePropertyUtil.setDataScopParam(sysUserRequest,sessionManagerApi);
return new SuccessResponseData(sysUserService.findPage(sysUserRequest));
}
- 修改SysUserMapper.mapper
SysUserMapper.xml
<!--用户列表 oracle版本-->
<!--用户列表sql-->
<sql id="user_list_mysql">
select
suser.user_id as userId,
suser.account as account,
suser.nick_name as nickName,
suser.real_name as realName,
suser.avatar as avatar,
suser.birthday as birthday,
suser.sex as sex,
suser.email as email,
suser.phone as phone,
suser.tel as tel,
suser.status_flag as statusFlag,
suorg.org_id as orgId,
suorg.position_id as positionId,
hpos.position_name as positionName
from sys_user suser
left join sys_user_org suorg on suser.user_id = suorg.user_id
left join hr_position hpos on suorg.position_id = hpos.position_id
<where>
<if test="sysUserRequest.realName != null and sysUserRequest.realName != ''">
and suser.real_name like concat('%',#{sysUserRequest.realName},'%')
</if>
<if test="sysUserRequest.account != null and sysUserRequest.account != ''">
and suser.account like concat('%',#{sysUserRequest.account},'%')
</if>
<if test="sysUserRequest.statusFlag != null and sysUserRequest.statusFlag != ''">
and suser.status_flag like concat('%',#{sysUserRequest.statusFlag},'%')
</if>
<if test="sysUserRequest.orgId != null and sysUserRequest.orgId != ''">
and suorg.org_id in (select org_id from hr_organization where org_pids like CONCAT('%$[',#{sysUserRequest.orgId},'$]%') escape '$' or org_id=#{sysUserRequest.orgId} )
</if>
<if test="sysUserRequest.dataScopeUserIds != null and sysUserRequest.dataScopeUserIds != ''">
and suser.user_id in
<foreach collection="sysUserRequest.dataScopeUserIds" open="(" separator="," close=")" item="item">
${item}
</foreach>
</if>
<if test="sysUserRequest.dataScopeOrganizationIds != null and sysUserRequest.dataScopeOrganizationIds != ''">
and suorg.org_id in
<foreach collection="sysUserRequest.dataScopeOrganizationIds" open="(" separator="," close=")" item="item">
${item}
</foreach>
</if>
and suser.del_flag = 'N'
order by suser.create_time desc
</where>
</sql>
<!--用户列表 oracle版本-->
<sql id="user_list_oracle">
select
suser.user_id as userId,
suser.account as account,
suser.nick_name as nickName,
suser.real_name as realName,
suser.avatar as avatar,
suser.birthday as birthday,
suser.sex as sex,
suser.email as email,
suser.phone as phone,
suser.tel as tel,
suser.status_flag as statusFlag,
suorg.org_id as orgId,
suorg.position_id as positionId,
hpos.position_name as positionName
from sys_user suser
left join sys_user_org suorg on suser.user_id = suorg.user_id
left join hr_position hpos on suorg.position_id = hpos.position_id
<where>
<if test="sysUserRequest.realName != null and sysUserRequest.realName != ''">
and suser.real_name like '%' || #{sysUserRequest.realName} || '%'
</if>
<if test="sysUserRequest.account != null and sysUserRequest.account != ''">
and suser.account like '%' || #{sysUserRequest.account} || '%'
</if>
<if test="sysUserRequest.statusFlag != null and sysUserRequest.statusFlag != ''">
and suser.status_flag like '%' || #{sysUserRequest.statusFlag} || '%'
</if>
<if test="sysUserRequest.orgId != null and sysUserRequest.orgId != ''">
and suorg.org_id in(select org_id from hr_organization where org_pids like '%' || #{sysUserRequest.orgId} || '%' or org_id = #{sysUserRequest.orgId})
</if>
<if test="sysUserRequest.dataScopeUserIds != null and sysUserRequest.dataScopeUserIds != ''">
and suser.user_id in
<foreach collection="sysUserRequest.dataScopeUserIds" open="(" separator="," close=")" item="item">
${item}
</foreach>
</if>
<if test="sysUserRequest.dataScopeOrganizationIds != null and sysUserRequest.dataScopeOrganizationIds != ''">
and suorg.org_id in
<foreach collection="sysUserRequest.dataScopeOrganizationIds" open="(" separator="," close=")" item="item">
${item}
</foreach>
</if>
and suser.del_flag = 'N'
order by suser.create_time desc
</where>
</sql>
- 其他自定义业务内容处理步骤.
1).在request增加数据权限相关属性
2).controller中进行权限值赋值
3).service 或者mapper中查询语句拼接修改.
guns的官网地址为:[https://www.stylefeng.cn/]