2021与蓝度共同重构项目,服务端
chenjiantian
2022-01-18 68fe223129de00d5370e5ab88e96be80d708a85f
权限管理
已添加3个文件
已修改7个文件
314 ■■■■ 文件已修改
dao/src/main/java/com/sandu/ximon/dao/domain/RoleDetail.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/RoleMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/RoleMapper.xml 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/RoleController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/RoleParam.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/security/PermissionConfig.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/security/SecurityUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleMenuRelationService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleService.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/RoleDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.sandu.ximon.dao.domain;
import lombok.Data;
import java.util.List;
@Data
public class RoleDetail extends Role {
    private List<Long> menuIdList;
}
dao/src/main/java/com/sandu/ximon/dao/mapper/RoleMapper.java
@@ -2,7 +2,10 @@
import com.sandu.ximon.dao.domain.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sandu.ximon.dao.domain.RoleDetail;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @Entity com.sandu.ximon.dao.domain.Role
@@ -10,6 +13,7 @@
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
    List<RoleDetail> listRole(List<Long> roleIdList);
}
dao/src/main/resources/mapper/RoleMapper.xml
@@ -5,18 +5,35 @@
<mapper namespace="com.sandu.ximon.dao.mapper.RoleMapper">
    <resultMap id="BaseResultMap" type="com.sandu.ximon.dao.domain.Role">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="level" column="level" jdbcType="INTEGER"/>
            <result property="permission" column="permission" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
        <id property="id" column="id" jdbcType="BIGINT"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="remark" column="remark" jdbcType="VARCHAR"/>
        <result property="level" column="level" jdbcType="INTEGER"/>
        <result property="permission" column="permission" jdbcType="VARCHAR"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,name,remark,
        level,permission,create_time,
        update_time
    </sql>
    <resultMap id="RoleDetail" type="com.sandu.ximon.dao.domain.RoleDetail" extends="BaseResultMap">
        <collection property="menuIdList" columnPrefix="menu_" ofType="java.lang.Long">
            <constructor>
                <arg column="menu_id" javaType="long"/>
            </constructor>
        </collection>
    </resultMap>
    <select id="listRole" resultMap="RoleDetail">
        SELECT t1.*,
               t2.menu_id AS menu_menu_id
        FROM role t1
        LEFT JOIN role_menu_relation t2 ON t1.id = t2.role_id
        <where>
            t1.id IN
            <foreach collection="roleIdList" separator="," item="roleId" open="(" close=")">
                #{roleId}
            </foreach>
        </where>
    </select>
</mapper>
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.enums.AdminStatusStatus;
import com.sandu.common.enums.ResponseStatusEnums;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.object.BaseConditionVO;
@@ -28,15 +29,13 @@
import com.sandu.ximon.dao.enums.AdministratorEnums;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -68,10 +67,11 @@
        if (!passwordEncoder.matches(loginParam.getPassword(), admin.getPassword())) {
            return ResponseUtil.error(ResponseStatusEnums.BAD_CREDENTIALS.getCode(), ResponseStatusEnums.BAD_CREDENTIALS.getMessage());
        }
        UserDetails userJwtUser = new AdminJwtUser(admin, roleService.mapToGrantedAuthorities(admin.getId()));
        if (!userJwtUser.isEnabled()) {
        if (AdminStatusStatus.DISABLE.getCode().equals(admin.getStatus())) {
            return ResponseUtil.error(ResponseStatusEnums.DISABLE_ACCOUNT.getCode(), ResponseStatusEnums.DISABLE_ACCOUNT.getMessage());
        }
        Collection<GrantedAuthority> grantedAuthorities = roleService.mapToGrantedAuthorities(admin.getId());
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        loginUserInfo.setUserId(admin.getId());
@@ -80,9 +80,8 @@
        loginUserInfo.setStatus(admin.getStatus());
        loginUserInfo.setIp(IpUtil.getRealIp());
        loginUserInfo.setAdministratorType(AdministratorEnums.ADMIN.getCode());
        loginUserInfo.setPermission("tenant");
        loginUserInfo.setPermission(grantedAuthorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(",")));
        // ç”Ÿæˆä»¤ç‰Œ
        String token = tokenProvider.createToken(loginUserInfo);
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/RoleController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.sandu.ximon.admin.controller;
import com.github.pagehelper.PageHelper;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.param.RoleParam;
import com.sandu.ximon.admin.service.RoleService;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.domain.RoleDetail;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author chenjiantian
 * @date 2021/4/27 18:47
 */
@AllArgsConstructor
@RestController
@RequestMapping("/v1/role")
public class RoleController {
    private final RoleService roleService;
    /**
     * èŽ·å–ç®¡ç†å‘˜çš„è§’è‰²
     */
    @GetMapping("/getRoleListByAdmin/{adminId}")
    public ResponseVO<Object> getRoleListByAdmin(@PathVariable Long adminId) {
        List<Role> roles = roleService.listByAdminId(adminId);
        return ResponseUtil.success(roles);
    }
    @GetMapping("/list")
    public ResponseVO<Object> listRole(BaseConditionVO conditionVO) {
        List<RoleDetail> roleDetails = roleService.listRole(conditionVO.getPageNo(), conditionVO.getPageSize());
        return ResponseUtil.success(roleDetails);
    }
    @PostMapping("/add")
    public ResponseVO<Object> addRole(@Validated @RequestBody RoleParam param) {
        boolean result = roleService.addRole(param);
        if (result) {
            return ResponseUtil.success("添加成功");
        } else {
            return ResponseUtil.success("添加失败");
        }
    }
    @PostMapping("/update/{roleId}")
    public ResponseVO<Object> updateRole(@PathVariable Long roleId, @Validated @RequestBody RoleParam param) {
        boolean result = roleService.updateRole(roleId, param);
        if (result) {
            return ResponseUtil.success("编辑成功");
        } else {
            return ResponseUtil.success("编辑失败");
        }
    }
    @PostMapping("/del/{roleId}")
    public ResponseVO<Object> delRole(@PathVariable Long roleId) {
        boolean result = roleService.delRole(roleId);
        if (result) {
            return ResponseUtil.success("删除成功");
        } else {
            return ResponseUtil.success("删除失败");
        }
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/param/RoleParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.sandu.ximon.admin.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
 * @author chenjiantian
 * @date 2022/1/18 11:38
 */
@Data
public class RoleParam {
    /**
     * åç§°
     */
    @NotBlank(message = "角色名称不能为空")
    private String name;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    private List<Long> menuIdList;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/security/PermissionConfig.java
@@ -1,5 +1,6 @@
package com.sandu.ximon.admin.security;
import com.sandu.common.security.LoginUserInfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
@@ -12,14 +13,18 @@
 * @date 2021/8/27 18:28
 * æƒé™æŽ§åˆ¶
 */
@Service(value = "p")
@Service(value = "el")
public class PermissionConfig {
//    public Boolean check(String... permissions) {
//
//        // èŽ·å–å½“å‰ç”¨æˆ·çš„æ‰€æœ‰æƒé™
//        List<String> elPermissions = SecurityUtils.getUserDetails().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
//        // åˆ¤æ–­å½“前用户的所有权限是否包含接口上定义的权限
//        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
//    }
    public Boolean check(String... permissions) {
        LoginUserInfo loginUserInfo = SecurityUtils.getUserDetails();
        if (loginUserInfo == null || loginUserInfo.getPermission() == null) {
            return false;
        }
        String[] split = loginUserInfo.getPermission().split(",");
        // èŽ·å–å½“å‰ç”¨æˆ·çš„æ‰€æœ‰æƒé™
        List<String> elPermissions = Arrays.stream(split).collect(Collectors.toList());
        // åˆ¤æ–­å½“前用户的所有权限是否包含接口上定义的权限
        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/security/SecurityUtils.java
@@ -18,7 +18,7 @@
    /**
     * èŽ·å–å½“å‰ç™»å½•ç”¨æˆ·ä¿¡æ¯
     */
    private static LoginUserInfo getUserDetails() {
    public static LoginUserInfo getUserDetails() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new BusinessException(ResponseStatusEnums.TOKEN_INVALID.getCode(), ResponseStatusEnums.TOKEN_INVALID.getMessage());
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleMenuRelationService.java
@@ -1,9 +1,14 @@
package com.sandu.ximon.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.dao.domain.RoleMenuRelation;
import com.sandu.ximon.dao.mapper.RoleMenuRelationMapper;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
 * @author chenjiantian
@@ -11,4 +16,20 @@
 */
@Service
public class RoleMenuRelationService extends BaseServiceImpl<RoleMenuRelationMapper, RoleMenuRelation> {
    public boolean addRoleMenuList(Long roleId, List<Long> menuIdList) {
        if (CollectionUtil.isNotEmpty(menuIdList)) {
            List<RoleMenuRelation> roleMenuRelationList = new ArrayList<>();
            for (Long menuId : menuIdList) {
                RoleMenuRelation roleMenuRelation = new RoleMenuRelation();
                roleMenuRelation.setMenuId(menuId);
                roleMenuRelation.setRoleId(roleId);
                roleMenuRelationList.add(roleMenuRelation);
            }
            if (!saveBatch(roleMenuRelationList)) {
                throw new BusinessException("编辑角色菜单失败");
            }
        }
        return true;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleService.java
@@ -3,22 +3,22 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.execption.EntityExistException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.dao.domain.AdminRoleRelation;
import com.sandu.ximon.dao.domain.Menu;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.domain.RoleMenuRelation;
import com.sandu.common.util.BeanConvertUtil;
import com.sandu.ximon.admin.param.RoleParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.dao.domain.*;
import com.sandu.ximon.dao.mapper.RoleMapper;
import lombok.AllArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -73,8 +73,83 @@
        List<AdminRoleRelation> list = adminRoleRelationService.list(Wrappers.lambdaQuery(AdminRoleRelation.class).eq(AdminRoleRelation::getAdminId, adminId).select(AdminRoleRelation::getRoleId));
        List<Long> roleIdList = list.stream().map(AdminRoleRelation::getRoleId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(roleIdList)) {
            throw new BusinessException("当前用户没有角色");
            return null;
        }
        return listByIds(roleIdList);
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean addRole(RoleParam param) {
        Role role = new Role();
        role.setName(param.getName());
        role.setRemark(param.getRemark());
        role.setLevel(2);
        if(!save(role)){
            throw new BusinessException("添加角色失败");
        }
        roleMenuRelationService.addRoleMenuList(role.getId(),param.getMenuIdList());
        return true;
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Long roleId, RoleParam param) {
        Role role = getById(roleId);
        if (role == null) {
            throw new BusinessException("找不到角色信息");
        }
        assertLevels(role.getLevel());
        Role update = new Role();
        update.setName(param.getName());
        update.setRemark(param.getRemark());
        if(!updateById(update)){
            throw new BusinessException("编辑角色失败");
        }
        roleMenuRelationService.remove(Wrappers.lambdaQuery(RoleMenuRelation.class).eq(RoleMenuRelation::getRoleId,roleId));
        roleMenuRelationService.addRoleMenuList(role.getId(),param.getMenuIdList());
        return true;
    }
    private int assertLevels(Integer level) {
        Long userId = SecurityUtils.getUserId();
        List<Role> roles = listByAdminId(userId);
        if(CollectionUtil.isEmpty(roles)){
            throw new BusinessException("当前用户没有角色");
        }
        List<Integer> levels = roles.stream().map(Role::getLevel).collect(Collectors.toList());
        int min = Collections.min(levels);
        if (level != null) {
            if (level < min) {
                throw new BusinessException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + level);
            }
        }
        return min;
    }
    public boolean delRole(Long roleId) {
        Role role = getById(roleId);
        if (role == null) {
            throw new BusinessException("找不到角色");
        }
        assertLevels(role.getLevel());
        List<AdminRoleRelation> list = adminRoleRelationService.list(Wrappers.lambdaQuery(AdminRoleRelation.class).eq(AdminRoleRelation::getRoleId, role));
        if(CollectionUtil.isNotEmpty(list)){
            throw new BusinessException("当前角色有管理员使用,无法删除");
        }
        roleMenuRelationService.remove(Wrappers.lambdaQuery(RoleMenuRelation.class).eq(RoleMenuRelation::getRoleId,roleId));
        return removeById(roleId);
    }
    public List<RoleDetail> listRole(int pageNo, int pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<Long> roleIdList = list().stream().map(Role::getId).collect(Collectors.toList());
        if(CollectionUtil.isEmpty(roleIdList)){
            return null;
        }
        return baseMapper.listRole(roleIdList);
    }
}