diff --git a/src/main/java/top/suyiiyii/sims/common/AuthAccess.java b/src/main/java/top/suyiiyii/sims/common/AuthAccess.java index 65ad38f..9ec5ccd 100644 --- a/src/main/java/top/suyiiyii/sims/common/AuthAccess.java +++ b/src/main/java/top/suyiiyii/sims/common/AuthAccess.java @@ -14,4 +14,5 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AuthAccess { + String[] allowRoles() default {}; } diff --git a/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java b/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java index 5becb7b..ee3e9ac 100644 --- a/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java +++ b/src/main/java/top/suyiiyii/sims/common/InterceptorConfig.java @@ -1,16 +1,10 @@ package top.suyiiyii.sims.common; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import top.suyiiyii.sims.service.RoleService; -import top.suyiiyii.sims.service.UserService; -import top.suyiiyii.sims.utils.JwtUtils; /** * @Author tortoise @@ -20,63 +14,28 @@ import top.suyiiyii.sims.utils.JwtUtils; * @Description: TODO 拦截器配置 * @Version 1.0 */ - @Configuration - public class InterceptorConfig extends WebMvcConfigurationSupport { +@Configuration +public class InterceptorConfig extends WebMvcConfigurationSupport { @Autowired - private RoleService roleService; + private RoleService roleService; + @Autowired + private JwtInterceptor jwtInterceptor; + @Autowired + private RbacInterceptor rbacInterceptor; - //UserService userService; - @Override - protected void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(jwtInterceptor()) - .addPathPatterns("/**") - .excludePathPatterns("/user/login") // 排除不需要验证的路径 - .excludePathPatterns("/user/register") - .excludePathPatterns("/v3/api-docs/**"); + @Override + protected void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(jwtInterceptor) + .addPathPatterns("/**") + .excludePathPatterns("/v3/api-docs/**"); + registry.addInterceptor(rbacInterceptor) + .excludePathPatterns("/v3/api-docs/**");; - // 注册AdminInterceptor,只拦截以admin/开头的路径 - registry.addInterceptor(new AdminInterceptor()) - .addPathPatterns("/admin/**"); - super.addInterceptors(registry); - } - - @Bean - public JwtInterceptor jwtInterceptor() { - return new JwtInterceptor(); - } - - // AdminInterceptor的实现 - public class AdminInterceptor implements HandlerInterceptor { - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - String path = request.getRequestURI(); - if (path.startsWith("/admin/") && !hasAdminPermission(request)) { - // 如果用户没有管理员权限,返回403 Forbidden - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - return false; - } - return true; - } - - private boolean hasAdminPermission(HttpServletRequest request) { - // 这里应该实现检查用户权限的逻辑 - // 例如,从session、token或者数据库中获取用户信息并判断权限 - // 以下仅为示例 - String token = (String) request.getAttribute("token"); - //非空 - if (token == null) { - return false; - } - try { - Integer userId = Integer.valueOf(JwtUtils.extractUserId(token)); - return roleService.isRoleNameAdmin(userId); - } catch (Exception e) { - // 处理令牌解析过程中可能出现的异常 - return false; - } - } - } + super.addInterceptors(registry); } + +} + diff --git a/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java b/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java index a946758..e7333ac 100644 --- a/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java +++ b/src/main/java/top/suyiiyii/sims/common/JwtInterceptor.java @@ -1,16 +1,15 @@ package top.suyiiyii.sims.common; -import cn.hutool.core.util.StrUtil; -import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.web.method.HandlerMethod; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; -import top.suyiiyii.sims.entity.User; import top.suyiiyii.sims.exception.ServiceException; -import top.suyiiyii.sims.mapper.UserMapper; import top.suyiiyii.sims.utils.JwtUtils; +import java.util.Objects; + /** * @Author tortoise * @Date 2024/8/12 11:33 @@ -20,49 +19,36 @@ import top.suyiiyii.sims.utils.JwtUtils; * @Version 1.0 */ +@Component public class JwtInterceptor implements HandlerInterceptor { - @Resource - UserMapper userMapper; + @Value("${jwt.secret}") + private String secret; + @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if ("/error".equals(request.getRequestURI())) { + return true; + } // 从 Authorization 头中获取 token String token = request.getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { - token = token.substring(7); // 去除 "Bearer " 前缀 + token = token.substring(7); } else { - // 如果 Authorization 头中没有 token,则尝试从请求参数中获取 - token = request.getParameter("token"); - } - // 如果不是映射到方法直接通过 - if (handler instanceof HandlerMethod) { - AuthAccess annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthAccess.class); - if (annotation != null) { - return true; - } - } - // 执行认证 - if (StrUtil.isBlank(token)) { - //权限错误 - throw new ServiceException("401", "请登录"); - } - // 获取 token 中的 user id - String userId= JwtUtils.extractUserId(token); - if (userId == null) { - throw new ServiceException("401", "请登录"); - } - - User user = userMapper.selectById(Integer.parseInt(userId)); - if (user == null) { - throw new ServiceException("401", "请登录"); + // 如果没有有效的token,设置userId为-1,表示未登录 + request.setAttribute("userId", -1); + return true; } // 验证 token 的有效性 - if (!JwtUtils.verifyToken(token, user.getPassword())) { - throw new ServiceException("401", "请登录"); + if (!JwtUtils.verifyToken(token, secret) || JwtUtils.extractUserId(token) == null) { + throw new ServiceException("401", "登录已过期,请重新登录"); } - // 验证token后,如果一切正常,将token存储到request的属性中 - request.setAttribute("token", token); + + // 获取 token 中的 user id + Integer userId = Integer.parseInt(Objects.requireNonNull(JwtUtils.extractUserId(token))); + + request.setAttribute("userId", userId); return true; } } diff --git a/src/main/java/top/suyiiyii/sims/common/RbacInterceptor.java b/src/main/java/top/suyiiyii/sims/common/RbacInterceptor.java new file mode 100644 index 0000000..35ec723 --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/common/RbacInterceptor.java @@ -0,0 +1,64 @@ +package top.suyiiyii.sims.common; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import top.suyiiyii.sims.entity.Role; +import top.suyiiyii.sims.exception.ServiceException; +import top.suyiiyii.sims.service.RbacService; + +import java.util.List; + +/** + * Rbac 拦截器 + * 从请求对象中获取用户信息,然后判断用户是否有权限访问当前路径 + */ +@Component +public class RbacInterceptor implements HandlerInterceptor { + + @Autowired + RbacService rbacService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + if ("/error".equals(request.getRequestURI())) { + return true; + } + // 获取用户角色 + List roles = getUserRole(request).stream().map(Role::getRoleName).toList(); + + List allowRoles = null; + + // 获取当前请求的方法上的 AuthAccess 注解,从而获取允许访问的角色 + if (handler instanceof HandlerMethod) { + AuthAccess annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthAccess.class); + if (annotation != null) { + allowRoles = List.of(annotation.allowRoles()); + } + } + + if (allowRoles != null && !allowRoles.isEmpty()) { + if (allowRoles.contains("guest")) { + return true; + } + for (String role : roles) { + if (allowRoles.contains(role)) { + return true; + } + } + } + throw new ServiceException("403", "权限不足"); + } + + private List getUserRole(HttpServletRequest request) { + Integer UserId = (Integer) request.getAttribute("userId"); + if (UserId == null || UserId == -1) { + return List.of(Role.guest()); + } + return rbacService.getRolesByUserId(UserId); + } + +} diff --git a/src/main/java/top/suyiiyii/sims/controller/AdminController.java b/src/main/java/top/suyiiyii/sims/controller/AdminController.java index 3beb4bd..7b1b17b 100644 --- a/src/main/java/top/suyiiyii/sims/controller/AdminController.java +++ b/src/main/java/top/suyiiyii/sims/controller/AdminController.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import top.suyiiyii.sims.common.AuthAccess; import top.suyiiyii.sims.common.Result; import top.suyiiyii.sims.entity.User; import top.suyiiyii.sims.service.RoleService; @@ -27,12 +28,14 @@ public class AdminController { @Autowired private UserService userService; + @AuthAccess(allowRoles = {"admin"}) @GetMapping("/findAllUsersWithRoles") public Result findAllUsersWithRoles() { List userList = roleService.findAllUsersWithRoles(); return Result.success(userList); } + @AuthAccess(allowRoles = {"admin"}) @GetMapping("/selectAll") public Result selectAll() { List users = userService.selectAll(); diff --git a/src/main/java/top/suyiiyii/sims/controller/HealthzController.java b/src/main/java/top/suyiiyii/sims/controller/HealthzController.java index e3724b2..34010a3 100644 --- a/src/main/java/top/suyiiyii/sims/controller/HealthzController.java +++ b/src/main/java/top/suyiiyii/sims/controller/HealthzController.java @@ -5,14 +5,17 @@ import lombok.Data; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; +import top.suyiiyii.sims.common.AuthAccess; @RestController public class HealthzController { + @AuthAccess(allowRoles = {"guest"}) @GetMapping("/healthz") public String healthz() { return "ok"; } + @AuthAccess(allowRoles = {"guest"}) @PostMapping("/healthz") public HealthzResponse healthzPost() { return new HealthzResponse("health"); diff --git a/src/main/java/top/suyiiyii/sims/controller/HelloController.java b/src/main/java/top/suyiiyii/sims/controller/HelloController.java deleted file mode 100644 index 9962cad..0000000 --- a/src/main/java/top/suyiiyii/sims/controller/HelloController.java +++ /dev/null @@ -1,27 +0,0 @@ -package top.suyiiyii.sims.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; -import top.suyiiyii.sims.common.Result; - -import java.util.List; - -@RestController -public class HelloController { - - @GetMapping("/hello") - public String hello(String username) { - return "Hello " + username; - } - @PostMapping("/hello") - public List helloPost(String username , Integer age) { - List list = List.of(username,age.toString()); - return list; - } - @GetMapping("/helloResult") - public Result healthz() { - return Result.success("Hello World"); - } - -} diff --git a/src/main/java/top/suyiiyii/sims/controller/RecordController.java b/src/main/java/top/suyiiyii/sims/controller/RecordController.java index 52e18ea..40b5ffc 100644 --- a/src/main/java/top/suyiiyii/sims/controller/RecordController.java +++ b/src/main/java/top/suyiiyii/sims/controller/RecordController.java @@ -10,6 +10,7 @@ import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import top.suyiiyii.sims.common.AuthAccess; import top.suyiiyii.sims.common.Result; import top.suyiiyii.sims.dto.CommonResponse; import top.suyiiyii.sims.dto.RecordDto; @@ -44,6 +45,7 @@ RecordController { @Autowired ModelMapper modelMapper; + @AuthAccess(allowRoles = {"admin"}) @Operation(summary = "获取所有奖惩记录") @GetMapping("/admin/record") public Result> adminRecord( @@ -61,6 +63,7 @@ RecordController { return Result.success(recordDtos); } + @AuthAccess(allowRoles = {"user"}) @Operation(summary = "获取自己的奖惩记录") @GetMapping("/record") public Result> record(@RequestParam(defaultValue = "0") int page, @@ -84,6 +87,7 @@ RecordController { } + @AuthAccess(allowRoles = {"admin"}) @Operation(summary = "更新单个奖惩记录") @PutMapping("/admin/record/{id}") public Result adminUpdateRecord(@PathVariable Integer id, @RequestBody RecordDto recordDto) { @@ -92,6 +96,7 @@ RecordController { return Result.msg("修改成功"); } + @AuthAccess(allowRoles = {"admin"}) @Operation(summary = "删除单个奖惩记录") @DeleteMapping("/admin/record/{id}") public Result adminDeleteRecord(@PathVariable Integer id) { @@ -100,6 +105,7 @@ RecordController { } + @AuthAccess(allowRoles = {"admin"}) @Operation(summary = "添加奖惩记录") @PostMapping("/admin/record") public Result adminAddRecord(@RequestBody RecordDto recordDto) { diff --git a/src/main/java/top/suyiiyii/sims/controller/UserController.java b/src/main/java/top/suyiiyii/sims/controller/UserController.java index c9e0362..80c34a3 100644 --- a/src/main/java/top/suyiiyii/sims/controller/UserController.java +++ b/src/main/java/top/suyiiyii/sims/controller/UserController.java @@ -38,14 +38,7 @@ public class UserController { RoleService roleService; - @AuthAccess - @GetMapping("/") - public Result hello() { - - return Result.success("success"); - - } - + @AuthAccess(allowRoles = {"guest"}) @PostMapping("/user/login") public Result login(@RequestBody LoginRequest request, HttpServletRequest httpServletRequest) { log.info("login request:{}", request); @@ -63,6 +56,7 @@ public class UserController { return Result.success(response); } + @AuthAccess(allowRoles = {"guest"}) @PostMapping("/user/register") public Result register(@RequestBody RegisterRequest request) { log.info("register request:{}", request); @@ -73,18 +67,13 @@ public class UserController { if (request.getPassword() == null || request.getPassword().length() < 3) { throw new ServiceException("密码长度不能小于3位"); } - User user = new User(); - user.setUsername(request.getUsername()); - user.setPassword(request.getPassword()); - user.setEmail(request.getEmail()); - user.setGrade(request.getGrade()); - user.setUserGroup(request.getGroup()); - userService.register(user); + userService.register(request); return Result.success(CommonResponse.factory("注册成功")); } @Operation(description = "删除单个用户") + @AuthAccess(allowRoles = {"admin"}) @DeleteMapping("/admin/user/{id}") public Result adminDelete(@PathVariable Integer id) { log.info("delete request:{}", id); @@ -93,6 +82,7 @@ public class UserController { } @Operation(description = "获取所有用户信息") + @AuthAccess(allowRoles = {"admin"}) @GetMapping("/admin/user") public Result> adminGet() { List allUsers = userService.findAllUsers(); @@ -100,6 +90,7 @@ public class UserController { } @Operation(description = "根据 id 获取用户信息") + @AuthAccess(allowRoles = {"admin"}) @GetMapping("/admin/user/{id}") public Result adminGetById(@PathVariable Integer id) { log.info("selectById request:{}", id); @@ -108,6 +99,7 @@ public class UserController { } @Operation(description = "获取当前用户信息") + @AuthAccess(allowRoles = {"user"}) @GetMapping("/user/me") public Result getSelf() { UserDto user = userService.findUser(0); @@ -119,9 +111,10 @@ public class UserController { public static class RegisterRequest { private String username; private String password; + private Integer studentId; private String email; private String grade; - private String group; + private String userGroup; } @Data diff --git a/src/main/java/top/suyiiyii/sims/entity/Role.java b/src/main/java/top/suyiiyii/sims/entity/Role.java index 78897ed..63e7f84 100644 --- a/src/main/java/top/suyiiyii/sims/entity/Role.java +++ b/src/main/java/top/suyiiyii/sims/entity/Role.java @@ -1,7 +1,8 @@ package top.suyiiyii.sims.entity; import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; +import com.tangzc.autotable.annotation.ColumnNotNull; +import com.tangzc.mpe.autotable.annotation.ColumnId; import com.tangzc.mpe.autotable.annotation.Table; import lombok.AllArgsConstructor; import lombok.Data; @@ -20,10 +21,14 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor public class Role { - @TableId("id") + @ColumnId(mode = IdType.AUTO,comment = "id主键") private Integer id; - private Integer roleId; //管理员,普通用户,组员,组长,队长 + @ColumnNotNull private String roleName; + private String tag; + public static Role guest() { + return new Role(-1, "guest",""); + } } diff --git a/src/main/java/top/suyiiyii/sims/entity/RolePermission.java b/src/main/java/top/suyiiyii/sims/entity/RolePermission.java index f838187..96b9593 100644 --- a/src/main/java/top/suyiiyii/sims/entity/RolePermission.java +++ b/src/main/java/top/suyiiyii/sims/entity/RolePermission.java @@ -3,6 +3,8 @@ package top.suyiiyii.sims.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.tangzc.autotable.annotation.ColumnNotNull; +import com.tangzc.mpe.autotable.annotation.ColumnId; import com.tangzc.mpe.autotable.annotation.Table; import lombok.AllArgsConstructor; import lombok.Data; @@ -23,8 +25,10 @@ import java.security.Permission; @AllArgsConstructor @NoArgsConstructor public class RolePermission { - @TableId("id") + @ColumnId(mode = IdType.AUTO,comment = "id主键") private Integer id; + @ColumnNotNull private Integer roleId; + @ColumnNotNull private Integer permissionId; } diff --git a/src/main/java/top/suyiiyii/sims/entity/User.java b/src/main/java/top/suyiiyii/sims/entity/User.java index d7bed55..000364d 100644 --- a/src/main/java/top/suyiiyii/sims/entity/User.java +++ b/src/main/java/top/suyiiyii/sims/entity/User.java @@ -1,6 +1,8 @@ package top.suyiiyii.sims.entity; -import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.IdType; +import com.tangzc.mpe.autotable.annotation.Column; +import com.tangzc.mpe.autotable.annotation.ColumnId; import com.tangzc.mpe.autotable.annotation.Table; import lombok.AllArgsConstructor; import lombok.Data; @@ -19,12 +21,18 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor public class User { - @TableId("id") + @ColumnId(mode = IdType.AUTO,comment = "id主键") private Integer id; + @Column(comment = "学生id",notNull = true) private Integer studentId; + @Column(comment = "用户名",notNull = true) private String username; + @Column(comment = "密码",notNull = true) private String password; + @Column(comment = "邮箱",notNull = true) private String email; + @Column(comment = "年级",notNull = true) private String grade; + @Column(comment = "用户所属团队",notNull = true) private String userGroup; } diff --git a/src/main/java/top/suyiiyii/sims/entity/UserRole.java b/src/main/java/top/suyiiyii/sims/entity/UserRole.java index 323df76..85f20ae 100644 --- a/src/main/java/top/suyiiyii/sims/entity/UserRole.java +++ b/src/main/java/top/suyiiyii/sims/entity/UserRole.java @@ -2,6 +2,8 @@ package top.suyiiyii.sims.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import com.tangzc.autotable.annotation.ColumnNotNull; +import com.tangzc.mpe.autotable.annotation.ColumnId; import com.tangzc.mpe.autotable.annotation.Table; import lombok.AllArgsConstructor; import lombok.Data; @@ -20,8 +22,10 @@ import lombok.NoArgsConstructor; @AllArgsConstructor @NoArgsConstructor public class UserRole { - @TableId("id") + @ColumnId(mode = IdType.AUTO,comment = "id主键") private Integer id; + @ColumnNotNull private Integer userId; + @ColumnNotNull private Integer roleId; } diff --git a/src/main/java/top/suyiiyii/sims/exception/GlobalException.java b/src/main/java/top/suyiiyii/sims/exception/GlobalException.java index fc85068..4645453 100644 --- a/src/main/java/top/suyiiyii/sims/exception/GlobalException.java +++ b/src/main/java/top/suyiiyii/sims/exception/GlobalException.java @@ -1,5 +1,6 @@ package top.suyiiyii.sims.exception; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @@ -13,11 +14,15 @@ import top.suyiiyii.sims.common.Result; * @Description: TODO * @Version 1.0 */ +@Slf4j @ControllerAdvice public class GlobalException { @ExceptionHandler(ServiceException.class) @ResponseBody - public Result ServiceException(ServiceException e){ - return Result.error(e.getCode(),e.getMessage()); + public Result ServiceException(ServiceException e) { + log.warn("ServiceException:{}", e.getMessage()); + // 打印错误调用栈 + log.warn("ServiceException:", e); + return Result.error(e.getCode(), e.getMessage()); } } diff --git a/src/main/java/top/suyiiyii/sims/mapper/MpRoleMapper.java b/src/main/java/top/suyiiyii/sims/mapper/MpRoleMapper.java new file mode 100644 index 0000000..70d3bd4 --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/mapper/MpRoleMapper.java @@ -0,0 +1,7 @@ +package top.suyiiyii.sims.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import top.suyiiyii.sims.entity.Role; + +public interface MpRoleMapper extends BaseMapper { +} diff --git a/src/main/java/top/suyiiyii/sims/mapper/MpUserRoleMapper.java b/src/main/java/top/suyiiyii/sims/mapper/MpUserRoleMapper.java new file mode 100644 index 0000000..759242d --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/mapper/MpUserRoleMapper.java @@ -0,0 +1,7 @@ +package top.suyiiyii.sims.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import top.suyiiyii.sims.entity.UserRole; + +public interface MpUserRoleMapper extends BaseMapper { +} diff --git a/src/main/java/top/suyiiyii/sims/mapper/UserMapper.java b/src/main/java/top/suyiiyii/sims/mapper/UserMapper.java index 1aef24f..7346c84 100644 --- a/src/main/java/top/suyiiyii/sims/mapper/UserMapper.java +++ b/src/main/java/top/suyiiyii/sims/mapper/UserMapper.java @@ -22,7 +22,7 @@ public interface UserMapper extends BaseMapper { * @param user 新用户对象 * @return 影响的行数 */ - @Insert("insert INTO user (id,student_id, username, password, name, email, userGroup) VALUES (#{id},#{studentId}, #{username}, #{password}, #{name}, #{email}, #{userGroup})") + @Insert("insert INTO user (id,student_id, username, password, username, email, user_group) VALUES (#{id},#{studentId}, #{username}, #{password}, #{name}, #{email}, #{userGroup})") int addUser(User user); /** @@ -41,10 +41,10 @@ public interface UserMapper extends BaseMapper { @Update("UPDATE user SET " + "student_id = #{userId}, " + "username = #{username}, " + - "name = #{name}, " + + "username = #{name}, " + "email = #{email}, " + "grade = #{grade}, " + - "userGroup = #{group} " + + "user_group = #{group} " + "WHERE id = #{id}") int updateUser(User user); @@ -53,7 +53,7 @@ public interface UserMapper extends BaseMapper { * @param * @return 用户对象 */ - @Select("SELECT id, student_id, username, password, name, email,grade,user_group from user WHERE student_id = #{id}") + @Select("SELECT id, student_id, username, password, username, email,grade,user_group from user WHERE student_id = #{id}") User selectByUserId(Integer id); /** @@ -61,13 +61,13 @@ public interface UserMapper extends BaseMapper { * @param * @return 用户对象 */ - @Select("SELECT id, student_id, username, password, name, email,grade, user_group from user WHERE id = #{id}") + @Select("SELECT id, student_id, username, password, username, email,grade, user_group from user WHERE id = #{id}") User selectById(Integer id); /** * 查询所有用户信息 * @return 用户列表 */ - @Select("SELECT id, student_id, username, password, name, email, grade, user_group FROM user") + @Select("SELECT id, student_id, username, password, username, email, grade, user_group FROM user") List selectAll(); @Select("select * from user where username = #{username}") diff --git a/src/main/java/top/suyiiyii/sims/service/RbacService.java b/src/main/java/top/suyiiyii/sims/service/RbacService.java new file mode 100644 index 0000000..5cab939 --- /dev/null +++ b/src/main/java/top/suyiiyii/sims/service/RbacService.java @@ -0,0 +1,55 @@ +package top.suyiiyii.sims.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import top.suyiiyii.sims.entity.Role; +import top.suyiiyii.sims.entity.UserRole; +import top.suyiiyii.sims.mapper.MpRoleMapper; +import top.suyiiyii.sims.mapper.MpUserMapper; +import top.suyiiyii.sims.mapper.MpUserRoleMapper; + +import java.util.List; + +@Slf4j +@Service +public class RbacService { + + @Autowired + MpUserMapper userMapper; + + @Autowired + MpUserRoleMapper userRoleMapper; + + @Autowired + MpRoleMapper roleMapper; + + /** + * 根据用户id获取用户的角色 + * + * @param userId 用户id + * @return 用户的角色列表 + */ + public List getRolesByUserId(int userId) { + // 根据用户id获取用户的角色id,使用mp的条件构造器 + List userRoles = userRoleMapper.selectList(new QueryWrapper().eq("user_id", userId)); + // 根据角色id获取角色 + return roleMapper.selectBatchIds(userRoles.stream().map(UserRole::getRoleId).toList()); + } + + public boolean addRoleWithUserId(int userId, String roleName) { + Role role = roleMapper.selectOne(new QueryWrapper().eq("role_name", roleName)); + if (role == null) { + Role newRole = new Role(); + newRole.setRoleName(roleName); + roleMapper.insert(newRole); + role = roleMapper.selectOne(new QueryWrapper().eq("role_name", roleName)); + } + UserRole userRole = new UserRole(); + userRole.setUserId(userId); + userRole.setRoleId(role.getId()); + return userRoleMapper.insert(userRole) > 0; + } + +} diff --git a/src/main/java/top/suyiiyii/sims/service/UserService.java b/src/main/java/top/suyiiyii/sims/service/UserService.java index f870e76..d9ca0ff 100644 --- a/src/main/java/top/suyiiyii/sims/service/UserService.java +++ b/src/main/java/top/suyiiyii/sims/service/UserService.java @@ -2,21 +2,22 @@ package top.suyiiyii.sims.service; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import top.suyiiyii.sims.controller.UserController; import top.suyiiyii.sims.dto.UserDto; import top.suyiiyii.sims.entity.*; import top.suyiiyii.sims.exception.ServiceException; -import top.suyiiyii.sims.mapper.PermissionsMapper; -import top.suyiiyii.sims.mapper.RoleMapper; -import top.suyiiyii.sims.mapper.UserMapper; +import top.suyiiyii.sims.mapper.*; import top.suyiiyii.sims.utils.JwtUtils; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +import java.util.*; /** * @Author tortoise @@ -31,9 +32,17 @@ public class UserService { @Autowired UserMapper userMapper; @Autowired + MpUserMapper mpUserMapper; + @Autowired RoleMapper roleMapper; @Autowired PermissionsMapper permissionsMapper; + @Value("${jwt.secret}") + private String secret; + @Autowired + private RbacService rbacService; + @Autowired + private ModelMapper modelMapper; public void addUser(User user) { userMapper.addUser(user); @@ -60,53 +69,37 @@ public class UserService { if (!dbUser.getPassword().equals(password)) { throw new ServiceException("密码或用户名错误"); } - HashSet permissionsSet = new HashSet<>(); - Integer id = dbUser.getId(); - List roles = roleMapper.selectRolesById(id); - for (Role role : roles) { - //根据roleid找所有permissionId - List rolePerminsion = permissionsMapper.getRolePerminsionByRoleId(role.getRoleId()); - for (RolePermission rolePermission : rolePerminsion) { - Integer permissionId = rolePermission.getPermissionId(); - //根据permissionId找permission - Permissions permissions = permissionsMapper.selectById(permissionId); - permissionsSet.add(permissions); - } + return JwtUtils.createToken(dbUser.getId().toString(), secret); + } + + + public void register(UserController.RegisterRequest req) { + + User dbUser = userMapper.selectByUserId(req.getStudentId()); + + if (req.getUsername() == null || req.getUsername().equals("")) { + throw new ServiceException("用户名不能为空"); } - - String token = JwtUtils.createToken(dbUser.getId().toString(), dbUser.getPassword()); - - - return token; - - } - - - public User register(User user) { - - User dbUser = userMapper.selectByUserId(user.getStudentId()); - - if (user.getUsername() == null || user.getUsername().equals("")) { - throw new ServiceException("用户名不能为空"); - } if (dbUser != null) { throw new ServiceException("账号已经存在"); } - if (user.getStudentId() == null || user.getStudentId().equals("")) { - throw new ServiceException("用户id不能为空"); + if (req.getStudentId() == null || req.getStudentId().equals("")) { + throw new ServiceException("学号不能为空"); } - if( user.getPassword() == null || user.getPassword().equals("")) { + if (req.getPassword() == null || req.getPassword().equals("")) { throw new ServiceException("密码不能为空"); } - if (user.getEmail() == null || user.getEmail().equals("")) { + if (req.getEmail() == null || req.getEmail().equals("")) { throw new ServiceException("邮箱不能为空"); } - if (user.getUserGroup() == null || user.getUserGroup().equals("")) { + if (req.getUserGroup() == null || req.getUserGroup().equals("")) { throw new ServiceException("组别不能为空"); } + User user =modelMapper.map(req, User.class); - userMapper.addUser(user); - return user; + mpUserMapper.insert(user); + user = mpUserMapper.selectOne(new LambdaQueryWrapper().eq(User::getUsername, req.getUsername())); + rbacService.addRoleWithUserId(user.getId(), "user"); } public User selectByUsername(String username) { return userMapper.selectByUserName(username); @@ -128,7 +121,7 @@ public class UserService { Integer id = user.getId(); List roles = roleMapper.selectRolesById(id); for (Role role : roles) { - Integer roleId = role.getRoleId(); + Integer roleId = role.getId(); // 获取一个角色的名称列表 List roleNameList = roleMapper.selectRoleNamesByRoleId(roleId); // 累加角色名称到用户的角色列表中 @@ -149,7 +142,7 @@ public class UserService { UserDto.setRoles(new ArrayList<>()); List roles = roleMapper.selectRolesById(id); for (Role role : roles) { - Integer roleId = role.getRoleId(); + Integer roleId = role.getId(); // 获取一个角色的名称列表 List roleNameList = roleMapper.selectRoleNamesByRoleId(roleId); // 累加角色名称到用户的角色列表中 diff --git a/src/main/resources/application-test.yaml b/src/main/resources/application-test.yaml index b73be74..978a6f0 100644 --- a/src/main/resources/application-test.yaml +++ b/src/main/resources/application-test.yaml @@ -5,4 +5,5 @@ spring: username: password: - +jwt: + secret: SuyiiyiiiiiiyiiiiTTTTTTTTTTTestttttttttttttt diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 2b0fca7..4b7599a 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -11,4 +11,7 @@ spring: auto-table: enable: true - model-package: top.suyiiyii.sims.entity \ No newline at end of file + model-package: top.suyiiyii.sims.entity + +jwt: + secret: ${JWT_SECRET} \ No newline at end of file diff --git a/src/test/java/top/suyiiyii/sims/mapper/UserMapperTest.java b/src/test/java/top/suyiiyii/sims/mapper/UserMapperTest.java deleted file mode 100644 index bb51181..0000000 --- a/src/test/java/top/suyiiyii/sims/mapper/UserMapperTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package top.suyiiyii.sims.mapper; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import top.suyiiyii.sims.entity.User; - -@SpringBootTest -@ActiveProfiles("test") -public class UserMapperTest { - - @Autowired - private MpUserMapper userMapper; - - @Test - public void testAddUser() { - User user = new User(); - user.setStudentId(1); - user.setUsername("test"); - user.setPassword("test"); - user.setEmail("test"); - user.setGrade("test"); - user.setUserGroup("test"); - - - - int result = userMapper.insert(user); - Assertions.assertEquals(1, result); - } - -} \ No newline at end of file diff --git a/src/test/java/top/suyiiyii/sims/service/RbacServiceTest.java b/src/test/java/top/suyiiyii/sims/service/RbacServiceTest.java new file mode 100644 index 0000000..b06cec6 --- /dev/null +++ b/src/test/java/top/suyiiyii/sims/service/RbacServiceTest.java @@ -0,0 +1,35 @@ +package top.suyiiyii.sims.service; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import top.suyiiyii.sims.entity.Role; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@ActiveProfiles("test") +class RbacServiceTest { + + @Autowired + private RbacService rbacService; + + @Test + void addRoleWithUserId() { + int userId = 1; // mock userId + String roleName = "ROLE"; // mock roleName + boolean result = rbacService.addRoleWithUserId(userId, roleName); + assertTrue(result); + } + @Test + void getRolesByUserId() { + int userId = 1; // mock userId + List roles = rbacService.getRolesByUserId(userId); + assertNotNull(roles); + assert roles.stream().map(Role::getRoleName).toList().contains("ROLE"); // mock roleName + } + +} \ No newline at end of file