From a161a8302376b324e2240156f2f06601251387f5 Mon Sep 17 00:00:00 2001 From: ailanyin Date: Tue, 16 May 2023 17:28:43 +0800 Subject: [PATCH] add --- pom.xml | 10 +- qiaoba-apis/pom.xml | 2 +- .../com/qiaoba/api/system/entity/SysDept.java | 11 +- .../com/qiaoba/api/system/entity/SysPost.java | 31 +++- .../api/system/entity/dto/LoginDto.java | 35 ++++ .../api/system/entity/param/SysDeptParam.java | 3 + .../api/system/entity/param/SysPostParam.java | 4 + .../api/system/service/SysDeptApiService.java | 4 +- .../api/system/service/SysMenuApiService.java | 2 + .../api/system/service/SysRoleApiService.java | 3 +- .../api/system/service/SysUserApiService.java | 8 + .../src/main/resources/application.yml | 18 +- qiaoba-auth/pom.xml | 36 ++++ .../auth/config/SpringSecurityConfig.java | 96 ++++++++++ .../auth/constants/SecurityConstant.java | 81 +++++++++ .../com/qiaoba/auth/entity/LoginUser.java | 172 ++++++++++++++++++ .../filters/JwtAuthenticationTokenFilter.java | 62 +++++++ .../auth/handler/AccessDeniedHandler.java | 31 ++++ .../qiaoba/auth/handler/LogoutHandler.java | 26 +++ .../auth/properties/AuthConfigProperties.java | 24 +++ .../com/qiaoba/auth/utils/SecurityUtil.java | 74 ++++++++ .../java/com/qiaoba/auth/utils/TokenUtil.java | 70 +++++++ .../spring-configuration-metadata.json | 17 ++ .../main/resources/META-INF/spring.factories | 6 + qiaoba-commons/pom.xml | 1 - qiaoba-commons/qiaoba-common-base/pom.xml | 4 + .../qiaoba/common/base}/utils/TenantUtil.java | 2 +- .../database/config/MybatisPlusConfig.java | 2 +- .../common/database/entity/PageQuery.java | 21 +-- .../filters/DynamicDataSourceFilter.java | 3 +- .../main/resources/META-INF/spring.factories | 2 - qiaoba-commons/qiaoba-common-redis/pom.xml | 6 +- .../redis/service/impl/RedisServiceImpl.java | 98 +++++----- qiaoba-commons/qiaoba-common-security/pom.xml | 21 --- .../common/security/utils/SecurityUtil.java | 30 --- .../common/web/advice/ExceptionAdvice.java | 29 ++- .../system/controller/SysDeptController.java | 27 ++- .../system/controller/SysLoginController.java | 27 ++- .../system/controller/SysPostController.java | 50 ++--- .../system/controller/SysUserController.java | 4 +- .../module/system/mapper/SysDeptMapper.java | 16 ++ .../module/system/mapper/SysMenuMapper.java | 9 + .../module/system/mapper/SysPostMapper.java | 4 +- .../system/mapper/SysUserPostMapper.java | 9 + .../system/mapper/SysUserRoleMapper.java | 3 +- .../system/service/SysLoginService.java | 38 ++++ .../module/system/service/SysMenuService.java | 9 + .../system/service/SysUserPostService.java | 8 + .../system/service/SysUserRoleService.java | 3 +- .../module/system/service/SysUserService.java | 1 + .../service/impl/SysDeptServiceImpl.java | 14 +- .../service/impl/SysLoginServiceImpl.java | 146 +++++++++++++++ .../service/impl/SysMenuServiceImpl.java | 6 + .../service/impl/SysPostServiceImpl.java | 27 ++- .../service/impl/SysRoleServiceImpl.java | 3 +- .../impl/SysUserDetailsServiceImpl.java | 48 +++++ .../service/impl/SysUserPostServiceImpl.java | 5 + .../service/impl/SysUserRoleServiceImpl.java | 4 +- .../service/impl/SysUserServiceImpl.java | 14 +- .../main/resources/mapper/SysDeptMapper.xml | 8 + .../main/resources/mapper/SysMenuMapper.xml | 24 ++- .../main/resources/mapper/SysPostMapper.xml | 8 +- .../resources/mapper/SysUserPostMapper.xml | 12 ++ .../resources/mapper/SysUserRoleMapper.xml | 7 +- 64 files changed, 1367 insertions(+), 212 deletions(-) create mode 100644 qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java create mode 100644 qiaoba-auth/pom.xml create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java create mode 100644 qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java create mode 100644 qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json create mode 100644 qiaoba-auth/src/main/resources/META-INF/spring.factories rename qiaoba-commons/{qiaoba-common-datasource/src/main/java/com/qiaoba/common/database => qiaoba-common-base/src/main/java/com/qiaoba/common/base}/utils/TenantUtil.java (93%) delete mode 100644 qiaoba-commons/qiaoba-common-security/pom.xml delete mode 100644 qiaoba-commons/qiaoba-common-security/src/main/java/com/qiaoba/common/security/utils/SecurityUtil.java create mode 100644 qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysLoginService.java create mode 100644 qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysLoginServiceImpl.java create mode 100644 qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserDetailsServiceImpl.java diff --git a/pom.xml b/pom.xml index d2bc6c5..502101a 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ qiaoba-apis qiaoba-commons qiaoba-application + qiaoba-auth @@ -104,6 +105,11 @@ + + com.qiaoba + qiaoba-auth + ${qiaoba.version} + com.qiaoba qiaoba-common-base @@ -136,12 +142,12 @@ com.qiaoba - qiaoba-common-security + qiaoba-common-poi ${qiaoba.version} com.qiaoba - qiaoba-common-poi + qiaoba-common-redis ${qiaoba.version} diff --git a/qiaoba-apis/pom.xml b/qiaoba-apis/pom.xml index b74aa80..d2d497c 100644 --- a/qiaoba-apis/pom.xml +++ b/qiaoba-apis/pom.xml @@ -31,7 +31,7 @@ com.qiaoba - qiaoba-common-security + qiaoba-auth com.qiaoba diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java index 05993eb..816616a 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysDept.java @@ -2,12 +2,15 @@ package com.qiaoba.api.system.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.qiaoba.common.base.entity.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + /** * 部门信息 sys_dept * @@ -41,11 +44,14 @@ public class SysDept extends BaseEntity { /** * 部门名称 */ + @Size(min = 1, max = 20, message = "部门名称允许长度: {min}-{max}") private String deptName; /** * 显示顺序 */ + @Min(value = 1, message = "排序最小允许: {value}") + @Max(value = Integer.MAX_VALUE, message = "排序最大允许: {value}") private Integer orderNum; /** @@ -66,6 +72,7 @@ public class SysDept extends BaseEntity { /** * 部门状态:0停用,1正常 */ + @NotBlank(message = "状态不能为空") private String status; } diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java index 3528193..7e35f6c 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/SysPost.java @@ -4,9 +4,15 @@ import cn.afterturn.easypoi.excel.annotation.Excel; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.qiaoba.common.base.entity.BaseEntity; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + /** * 岗位信息 sys_post * @@ -22,19 +28,28 @@ public class SysPost extends BaseEntity { private static final long serialVersionUID = 1L; @TableId - @Excel(name = "岗位序号" , width = 20) + @Excel(name = "岗位序号", width = 20) private String postId; - @Excel(name = "岗位编码" , width = 20) - private String postCode; - - @Excel(name = "岗位名称" , width = 20) + @Excel(name = "岗位名称", width = 20) + @Schema(description = "岗位名称") + @Size(min = 1, max = 20, message = "岗位名称允许长度: {min}-{max}") private String postName; - @Excel(name = "岗位排序" , width = 20) - private String postSort; + @Excel(name = "岗位编码", width = 20) + @Schema(description = "岗位编码") + @Size(min = 1, max = 20, message = "岗位编码允许长度: {min}-{max}") + private String postCode; - @Excel(name = "状态" , width = 20, replace = {"正常_1" , "异常_0"}) + @Excel(name = "岗位排序", width = 20) + @Schema(description = "岗位排序") + @Min(value = 1, message = "排序最小允许: {value}") + @Max(value = Integer.MAX_VALUE, message = "排序最大允许: {value}") + private Integer postSort; + + @Excel(name = "状态", width = 20, replace = {"正常_1", "异常_0"}) + @Schema(description = "状态(0->禁用,1->正常)") + @NotBlank(message = "状态不能为空") private String status; } diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java new file mode 100644 index 0000000..eed22e2 --- /dev/null +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/dto/LoginDto.java @@ -0,0 +1,35 @@ +package com.qiaoba.api.system.entity.dto; + +import lombok.Data; + +/** + * 用户登录对象 + * + * @author ailanyin + * @version 1.0 + * @since 2021/10/15 0015 上午 10:05 + */ +@Data +public class LoginDto { + + /** + * 用户名 + */ + private String username; + + /** + * 用户密码 + */ + private String password; + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid = ""; + +} diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java index 4fb456a..86deb40 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysDeptParam.java @@ -1,5 +1,6 @@ package com.qiaoba.api.system.entity.param; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -18,6 +19,8 @@ public class SysDeptParam implements Serializable { private static final long serialVersionUID = 1L; + @Schema(description = "部门名称") private String deptName; + @Schema(description = "状态(0->禁用,1->正常)") private String status; } diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java index 387e4e1..2c9d550 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/entity/param/SysPostParam.java @@ -1,5 +1,6 @@ package com.qiaoba.api.system.entity.param; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -18,10 +19,13 @@ public class SysPostParam implements Serializable { private static final long serialVersionUID = 1L; + @Schema(description = "岗位名称") private String postName; + @Schema(description = "岗位编码") private String postCode; + @Schema(description = "状态(0->禁用,1->正常)") private String status; public SysPostParam() { diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java index 3e959fb..13fa2e0 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysDeptApiService.java @@ -45,7 +45,7 @@ public interface SysDeptApiService { * @param deptId 部门Id * @return 部门信息 */ - SysDept selectById(Long deptId); + SysDept selectById(String deptId); /** * 删除部门 @@ -53,7 +53,7 @@ public interface SysDeptApiService { * @param deptId 部门Id * @return > 0 = success */ - int deleteById(Long deptId); + int deleteById(String deptId); /** * 构建前端部门树 diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java index 0977453..85198c5 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysMenuApiService.java @@ -5,6 +5,7 @@ import com.qiaoba.api.system.entity.param.SysMenuParam; import com.qiaoba.api.system.entity.vo.SysMenuVo; import java.util.List; +import java.util.Set; /** * 菜单对外暴露接口 @@ -54,4 +55,5 @@ public interface SysMenuApiService { * @return > 0 = success */ int deleteById(String menuId); + } diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java index 9180a34..eca34be 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysRoleApiService.java @@ -60,7 +60,7 @@ public interface SysRoleApiService { * 批量删除 * * @param ids 角色ID列表 - * @return > 0 = success + * @return > 0 = success */ int deleteByIds(List ids); @@ -71,4 +71,5 @@ public interface SysRoleApiService { * @return 结果 */ int authDataScope(DataScopeDto dto); + } diff --git a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java index 6db65fe..7bfa599 100644 --- a/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java +++ b/qiaoba-apis/qiaoba-api-system/src/main/java/com/qiaoba/api/system/service/SysUserApiService.java @@ -37,6 +37,14 @@ public interface SysUserApiService { */ SysUser selectById(String userId, Boolean hasPassword); + /** + * 查询用户 + * + * @param username 登录账号 + * @return SysUser + */ + SysUser selectByUsername(String username); + /** * 重置密码 * diff --git a/qiaoba-application/src/main/resources/application.yml b/qiaoba-application/src/main/resources/application.yml index ea168f1..aab78bf 100644 --- a/qiaoba-application/src/main/resources/application.yml +++ b/qiaoba-application/src/main/resources/application.yml @@ -16,8 +16,23 @@ spring: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 +qiaoba: + auth: + whitelist: + - / + - /*.* + - /favicon.ico + - /**/*.html + - /**/*.css + - /**/*.js + - /swagger-resources + - /v3/api-docs/** + - /druid/** + - /file/** + - /login + - /register + - /captchaImage -# springdoc-openapi项目配置 springdoc: swagger-ui: path: /swagger-ui.html @@ -29,6 +44,7 @@ springdoc: - group: '系统管理' paths-to-match: '/**' packages-to-scan: com.qiaoba.module.system.controller + # knife4j的增强配置,不需要增强可以不配 knife4j: enable: true diff --git a/qiaoba-auth/pom.xml b/qiaoba-auth/pom.xml new file mode 100644 index 0000000..2a2c23f --- /dev/null +++ b/qiaoba-auth/pom.xml @@ -0,0 +1,36 @@ + + + + qiaoba-boot + com.qiaoba + 1.0 + + 4.0.0 + + qiaoba-auth + + + + + org.springframework.boot + spring-boot-starter-security + + + + com.qiaoba + qiaoba-common-base + + + com.qiaoba + qiaoba-common-web + + + + com.qiaoba + qiaoba-common-redis + + + + diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java new file mode 100644 index 0000000..37870e9 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/config/SpringSecurityConfig.java @@ -0,0 +1,96 @@ +package com.qiaoba.auth.config; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.SecureUtil; +import com.qiaoba.auth.constants.SecurityConstant; +import com.qiaoba.auth.filters.JwtAuthenticationTokenFilter; +import com.qiaoba.auth.handler.AccessDeniedHandler; +import com.qiaoba.auth.handler.LogoutHandler; +import com.qiaoba.auth.properties.AuthConfigProperties; +import com.qiaoba.auth.utils.TokenUtil; +import com.qiaoba.common.redis.service.RedisService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import javax.annotation.PostConstruct; + +/** + * SpringSecurity安全配置 + * + * @author ailanyin + * @version 1.0 + * @since 2023/5/15 11:23 + */ +@Configuration +@RequiredArgsConstructor +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +@Slf4j +public class SpringSecurityConfig { + + private final AuthConfigProperties authConfigProperties; + private final AccessDeniedHandler accessDeniedHandler; + private final LogoutHandler logoutHandler; + private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; + private final RedisService redisService; + + /** + * 创建Token秘钥 + */ + @PostConstruct + public void initSecret() { + if (redisService.hasKey(SecurityConstant.REDIS_SECRET_KEY)) { + TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(redisService.get(SecurityConstant.REDIS_SECRET_KEY).toString())); + } else { + String random = RandomUtil.randomString(8); + TokenUtil.secret = SecureUtil.md5(SecureUtil.md5(random)); + redisService.set(SecurityConstant.REDIS_SECRET_KEY, random); + } + } + + @Bean + SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { + ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); + //白名单 + for (String url : authConfigProperties.getWhitelist()) { + registry.antMatchers(url).permitAll(); + } + + // 由于使用的是JWT,我们这里不需要csrf + httpSecurity.csrf() + .disable() + //添加自定义未授权和未登录结果返回 + .exceptionHandling() + .authenticationEntryPoint(accessDeniedHandler) + .and() + // 基于token,所以不需要session + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + //跨域请求会先进行一次options请求 + .antMatchers(HttpMethod.OPTIONS) + .permitAll() + // 除上面外的所有请求全部需要鉴权认证 + .anyRequest() + .authenticated(); + // 禁用缓存 + httpSecurity.headers().cacheControl(); + // 退出处理 + httpSecurity.logout().logoutUrl(SecurityConstant.LOGOUT_URL).logoutSuccessHandler(logoutHandler); + // 添加JWT filter + httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + + return httpSecurity.build(); + } +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java new file mode 100644 index 0000000..4bf7f5c --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/constants/SecurityConstant.java @@ -0,0 +1,81 @@ +package com.qiaoba.auth.constants; + +import java.util.Arrays; +import java.util.List; + +/** + * 安全常量 + * + * @author ailanyin + * @version 1.0 + * @since 2022/9/8 0008 下午 14:54 + */ +public class SecurityConstant { + + public static final int MAX_ERROR_COUNT = 5; + public static final String LOGOUT_URL = "/logout"; + public static final String HAS_BEEN_PULLED_BLACK = "您的IP已经被系统拉黑"; + public static final String ACCESS_DENIED = "暂无权限访问, 请重新登录"; + public static final String BLACKLIST_KEY = "login:blacklist"; + public static final String LOGIN_ERROR_COUNT = "login:errorCount:"; + public static final String BLACKLIST_ON = "true"; + public static final String BLACKLIST_ON_OFF_KEY = "sys_config:sys.account.blacklistOnOff"; + public static final String CAPTCHA_KEY = "login:captcha:"; + public static final String CAPTCHA_ON_OFF_KEY = "sys_config:sys.account.captchaOnOff"; + public static final String CAPTCHA_ON = "true"; + public static final String REGISTER_ON_OFF_KEY = "sys_config:sys.account.registerUser"; + public static final String REGISTER_ON = "true"; + public static final String REDIS_SECRET_KEY = "sys:secret:secret"; + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "登录成功"; + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "登录失败"; + /** + * 密码错误 + */ + public static final String PASSWORD_ERROR = "密码错误"; + + /** + * token header + */ + public static final String TOKEN_HEADER = "Authorization"; + + /** + * token前缀 + */ + public static final String TOKEN_HEAD = "Bearer "; + + + /** + * Xss过滤白名单 + */ + public final static List XSS_WHITELIST = Arrays.asList( + "/captchaImage" , + "/login", + "/workflow/process/start", + "/workflow/model/save" + ); + + /** + * 需要限流的接口 + */ + public final static List LIMIT_URI = Arrays.asList( + "/captchaImage" , + "/login" , + "/register" + ); + + /** + * 限流的RedisKey + */ + public final static String RATE_LIMIT_KEY = "rateLimit:"; + + /** + * 同IP每秒最大允许访问次数 + */ + public final static Integer MAX_RATE_LIMIT_TOTAL = 5; +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java new file mode 100644 index 0000000..c3d0c13 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/entity/LoginUser.java @@ -0,0 +1,172 @@ +package com.qiaoba.auth.entity; + +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 登录用户身份权限 + * + * @author ailanyin + * @version 1.0 + * @since 2021/10/15 0015 上午 10:05 + */ +public class LoginUser implements UserDetails { + + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private String userId; + + /** + * 部门ID + */ + private String deptId; + + /** + * 登录账号 + */ + private String username; + + /** + * 用户名称 + */ + private String nickname; + + + /** + * 角色列表 + */ + private List roleIds; + + + /** + * 权限列表 + */ + private Set permissions; + + + public LoginUser() { + } + + public LoginUser(String userId, String deptId, String username, String nickname, List roleIds, Set permissions) { + this.userId = userId; + this.deptId = deptId; + this.username = username; + this.permissions = permissions; + this.nickname = nickname; + this.roleIds = roleIds; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + + public List getRoleIds() { + return roleIds; + } + + public void setRoleIds(List roleIds) { + this.roleIds = roleIds; + } + + public Set getPermissions() { + return permissions; + } + + public void setPermissions(Set permissions) { + this.permissions = permissions; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public void setUsername(String username) { + this.username = username; + } + + + @Override + public String getUsername() { + return this.username; + } + + @Override + public String getPassword() { + return null; + } + + /** + * 账户是否未过期,过期无法验证 + */ + @Override + public boolean isAccountNonExpired() { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + */ + @Override + public boolean isAccountNonLocked() { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return boolean + */ + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return boolean + */ + @Override + public boolean isEnabled() { + return true; + } + + @Override + @JsonIgnore + public Collection getAuthorities() { + //返回当前用户的权限 + return permissions.stream() + .filter(StrUtil::isNotBlank) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + } + +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..c2764c4 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/filters/JwtAuthenticationTokenFilter.java @@ -0,0 +1,62 @@ +package com.qiaoba.auth.filters; + +import cn.hutool.core.util.StrUtil; +import com.qiaoba.auth.constants.SecurityConstant; +import com.qiaoba.auth.properties.AuthConfigProperties; +import com.qiaoba.auth.utils.TokenUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Objects; + +/** + * JwtAuthenticationTokenFilter + * 为了保证 SecurityContext 上下文中 userInfo 是最新的 + * + * @author ailanyin + * @version 1.0 + * @since 2021/10/21 0021 下午 14:13 + */ +@RequiredArgsConstructor +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + + private final UserDetailsService userDetailsService; + private final AuthConfigProperties authConfigProperties; + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain chain) throws ServletException, IOException { + // 鉴权白名单, 放行 + if (authConfigProperties.getWhitelist().contains(request.getRequestURI())) { + chain.doFilter(request, response); + return; + } + // 取Header中的Token + String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER); + if (StrUtil.isNotBlank(authHeader) && authHeader.startsWith(SecurityConstant.TOKEN_HEAD)) { + String authToken = authHeader.substring(SecurityConstant.TOKEN_HEAD.length()); + if (TokenUtil.validateToken(authToken)) { + String username = TokenUtil.getUserNameFromToken(authToken); + if (StrUtil.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) { + UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + } + + chain.doFilter(request, response); + } +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java new file mode 100644 index 0000000..55fd811 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/AccessDeniedHandler.java @@ -0,0 +1,31 @@ +package com.qiaoba.auth.handler; + +import cn.hutool.http.HttpStatus; +import cn.hutool.json.JSONUtil; +import com.qiaoba.auth.constants.SecurityConstant; +import com.qiaoba.common.base.result.AjaxResult; +import com.qiaoba.common.web.utils.ResponseUtil; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 无权限处理器 + * + * @author ailanyin + * @version 1.0 + * @since 2023/5/15 14:14 + */ +@Component +public class AccessDeniedHandler implements AuthenticationEntryPoint { + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { + AjaxResult result = AjaxResult.error(HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED); + ResponseUtil.response(response, JSONUtil.toJsonStr(result)); + } +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java new file mode 100644 index 0000000..59d51b8 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/handler/LogoutHandler.java @@ -0,0 +1,26 @@ +package com.qiaoba.auth.handler; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 退出处理器 + * + * @author ailanyin + * @version 1.0 + * @since 2022/1/4 0004 下午 16:20 + */ +@Component +public class LogoutHandler implements LogoutSuccessHandler { + + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) { + //删除SecurityContext上下文中的信息 + SecurityContextHolder.clearContext(); + } +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java new file mode 100644 index 0000000..7554899 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/properties/AuthConfigProperties.java @@ -0,0 +1,24 @@ +package com.qiaoba.auth.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +/** + * 鉴权配置(白名单/XSS) + * + * @author ailanyin + * @version 1.0 + * @since 2023/5/15 11:09 + */ +@Configuration +@ConfigurationProperties(prefix = "qiaoba.auth") +@Data +@EnableConfigurationProperties +public class AuthConfigProperties { + + private List whitelist; +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java new file mode 100644 index 0000000..27945f6 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/SecurityUtil.java @@ -0,0 +1,74 @@ +package com.qiaoba.auth.utils; + +import com.qiaoba.auth.entity.LoginUser; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +/** + * SecurityUtil + * + * @author ailanyin + * @version 1.0 + * @since 2022/8/16 0016 下午 14:51 + */ +public class SecurityUtil { + + private static final BCryptPasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder(); + + /** + * 获取登录用户的账号 + * + * @return username + */ + public static String getLoginUsername() { + return getLoginUser().getUsername(); + } + + /** + * 获取登录用户的账号 + * + * @return nickname + */ + public static String getLoginNickname() { + return getLoginUser().getNickname(); + } + + /** + * 获取登录用户的ID + * + * @return userId + */ + public static String getLoginUserId() { + return getLoginUser().getUserId(); + } + + + public static LoginUser getLoginUser() { + SecurityContext ctx = SecurityContextHolder.getContext(); + Authentication auth = ctx.getAuthentication(); + return (LoginUser) auth.getPrincipal(); + } + + /** + * 加密密码 + * + * @param password 原密码 + * @return 加密后密码 + */ + public static String encryptPassword(String password) { + return PASSWORD_ENCODER.encode(password); + } + + /** + * 判断密码是否相同 + * + * @param rawPassword 真实密码 + * @param encodedPassword 加密后字符 + * @return 结果 + */ + public static boolean matchesPassword(String rawPassword, String encodedPassword) { + return PASSWORD_ENCODER.matches(rawPassword, encodedPassword); + } +} diff --git a/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java new file mode 100644 index 0000000..aeb86d7 --- /dev/null +++ b/qiaoba-auth/src/main/java/com/qiaoba/auth/utils/TokenUtil.java @@ -0,0 +1,70 @@ +package com.qiaoba.auth.utils; + +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateTime; +import cn.hutool.jwt.JWTPayload; +import cn.hutool.jwt.JWTUtil; + +import java.util.HashMap; +import java.util.Map; + +/** + * TokenUtil + * + * @author ailanyin + * @version 1.0 + * @since 2022/6/8 0008 上午 11:44 + */ +public class TokenUtil { + + + /** + * jwt 加解密密钥,第一次项目启动时创建随机数 + */ + public static String secret; + + + public static String generateToken(String username) { + DateTime now = DateTime.now(); + // 3天过期 + DateTime newTime = now.offsetNew(DateField.HOUR, 72); + + Map payload = new HashMap(4); + //签发时间 + payload.put(JWTPayload.ISSUED_AT, now); + //过期时间 + payload.put(JWTPayload.EXPIRES_AT, newTime); + //生效时间 + payload.put(JWTPayload.NOT_BEFORE, now); + //载荷 + payload.put(JWTPayload.SUBJECT, username); + + return JWTUtil.createToken(payload, secret.getBytes()); + } + + public static String getUserNameFromToken(String token) { + try { + return JWTUtil.parseToken(token).getPayload(JWTPayload.SUBJECT).toString(); + } catch (Exception e) { + return null; + } + } + + /** + * 验证Token是否有效 + * + * @param token token + * @return 是/否 + */ + public static boolean validateToken(String token) { + try { + if (!JWTUtil.verify(token, secret.getBytes())) { + return false; + } + long expireTime = Long.parseLong(JWTUtil.parseToken(token).getPayload(JWTPayload.EXPIRES_AT).toString() + "000"); + return new DateTime(expireTime).after(DateTime.now()); + } catch (Exception e) { + return false; + } + } +} diff --git a/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json b/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 0000000..0ca18bc --- /dev/null +++ b/qiaoba-auth/src/main/resources/META-INF/spring-configuration-metadata.json @@ -0,0 +1,17 @@ +{ + "groups": [ + { + "name": "qiaoba.auth", + "type": "com.qiaoba.auth.properties.AuthConfigProperties", + "sourceType": "com.qiaoba.auth.properties.AuthConfigProperties" + } + ], + "properties": [ + { + "name": "qiaoba.auth.whitelist", + "type": "java.util.List", + "sourceType": "com.qiaoba.auth.properties.AuthConfigProperties" + } + ], + "hints": [] +} diff --git a/qiaoba-auth/src/main/resources/META-INF/spring.factories b/qiaoba-auth/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..65cc811 --- /dev/null +++ b/qiaoba-auth/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.qiaoba.auth.properties.AuthConfigProperties,\ + com.qiaoba.auth.handler.AccessDeniedHandler,\ + com.qiaoba.auth.handler.LogoutHandler,\ + com.qiaoba.auth.filters.JwtAuthenticationTokenFilter,\ + com.qiaoba.auth.config.SpringSecurityConfig diff --git a/qiaoba-commons/pom.xml b/qiaoba-commons/pom.xml index 73cfdd6..fe55844 100644 --- a/qiaoba-commons/pom.xml +++ b/qiaoba-commons/pom.xml @@ -17,7 +17,6 @@ qiaoba-common-web qiaoba-common-doc qiaoba-common-redis - qiaoba-common-security qiaoba-common-poi diff --git a/qiaoba-commons/qiaoba-common-base/pom.xml b/qiaoba-commons/qiaoba-common-base/pom.xml index 68fd04f..df45e79 100644 --- a/qiaoba-commons/qiaoba-common-base/pom.xml +++ b/qiaoba-commons/qiaoba-common-base/pom.xml @@ -16,5 +16,9 @@ cn.hutool hutool-all + + org.springframework.boot + spring-boot-starter-validation + diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java b/qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java similarity index 93% rename from qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java rename to qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java index c72d3ff..4f171df 100644 --- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/utils/TenantUtil.java +++ b/qiaoba-commons/qiaoba-common-base/src/main/java/com/qiaoba/common/base/utils/TenantUtil.java @@ -1,4 +1,4 @@ -package com.qiaoba.common.database.utils; +package com.qiaoba.common.base.utils; /** * 租户工具类 diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java index 37f669a..56482fb 100644 --- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java +++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/config/MybatisPlusConfig.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; -import com.qiaoba.common.database.utils.TenantUtil; +import com.qiaoba.common.base.utils.TenantUtil; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.StringValue; import org.springframework.context.annotation.Bean; diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java index 2e07a5b..8d1a8db 100644 --- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java +++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/entity/PageQuery.java @@ -1,14 +1,10 @@ package com.qiaoba.common.database.entity; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.Data; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; /** * 分页查询实体类 @@ -31,16 +27,6 @@ public class PageQuery implements Serializable { */ private Integer pageNum; - /** - * 排序列 - */ - private String orderByColumn; - - /** - * 排序的方向desc或者asc - */ - private String isAsc; - /** * 当前记录起始索引 默认值 */ @@ -57,12 +43,7 @@ public class PageQuery implements Serializable { if (pageNum <= 0) { pageNum = DEFAULT_PAGE_NUM; } - Page page = new Page<>(pageNum, pageSize); -/* List orderItems = buildOrderItem(); - if (CollUtil.isNotEmpty(orderItems)) { - page.addOrder(orderItems); - }*/ - return page; + return new Page<>(pageNum, pageSize); } } diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java index 37a6955..a5777a7 100644 --- a/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java +++ b/qiaoba-commons/qiaoba-common-datasource/src/main/java/com/qiaoba/common/database/filters/DynamicDataSourceFilter.java @@ -2,14 +2,13 @@ package com.qiaoba.common.database.filters; import com.qiaoba.common.database.config.DynamicDataSourceContext; import com.qiaoba.common.database.constants.DynamicDatasourceConstant; -import com.qiaoba.common.database.utils.TenantUtil; +import com.qiaoba.common.base.utils.TenantUtil; import com.qiaoba.common.web.utils.ResponseUtil; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.servlet.*; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; diff --git a/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories b/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories index 49807c2..f955e9d 100644 --- a/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories +++ b/qiaoba-commons/qiaoba-common-datasource/src/main/resources/META-INF/spring.factories @@ -1,5 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.qiaoba.common.database.factories.DynamicDataSourceFactory,\ com.qiaoba.common.database.config.MybatisPlusConfig - - diff --git a/qiaoba-commons/qiaoba-common-redis/pom.xml b/qiaoba-commons/qiaoba-common-redis/pom.xml index 3750505..6d5258d 100644 --- a/qiaoba-commons/qiaoba-common-redis/pom.xml +++ b/qiaoba-commons/qiaoba-common-redis/pom.xml @@ -17,10 +17,14 @@ org.springframework.boot spring-boot-starter-data-redis + + com.qiaoba + qiaoba-common-base + com.fasterxml.jackson.core jackson-databind - \ No newline at end of file + diff --git a/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java b/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java index 06b2d24..eb6beaf 100644 --- a/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java +++ b/qiaoba-commons/qiaoba-common-redis/src/main/java/com/qiaoba/common/redis/service/impl/RedisServiceImpl.java @@ -1,8 +1,9 @@ package com.qiaoba.common.redis.service.impl; +import com.qiaoba.common.base.utils.TenantUtil; import com.qiaoba.common.redis.service.RedisService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -20,33 +21,34 @@ import java.util.concurrent.TimeUnit; * @since 2021/10/2 0003 下午 17:44 */ @Service +@RequiredArgsConstructor public class RedisServiceImpl implements RedisService { - @Autowired - private RedisTemplate redisTemplate; + private final RedisTemplate redisTemplate; @Override public void set(String key, Object value, long time) { - redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(handleKey(key), value, time, TimeUnit.SECONDS); } @Override public void set(String key, Object value) { - redisTemplate.opsForValue().set(key, value); + redisTemplate.opsForValue().set(handleKey(key), value); } @Override public Object get(String key) { - return redisTemplate.opsForValue().get(key); + return redisTemplate.opsForValue().get(handleKey(key)); } @Override public Boolean del(String key) { - return redisTemplate.delete(key); + return redisTemplate.delete(handleKey(key)); } @Override public void del(Collection collection) { + // todo redisTemplate.delete(collection); } @@ -57,168 +59,178 @@ public class RedisServiceImpl implements RedisService { @Override public Long getExpire(String key) { - return redisTemplate.getExpire(key, TimeUnit.SECONDS); + return redisTemplate.getExpire(handleKey(key), TimeUnit.SECONDS); } @Override public Boolean hasKey(String key) { - return redisTemplate.hasKey(key); + return redisTemplate.hasKey(handleKey(key)); } @Override public Long incr(String key, long delta) { - return redisTemplate.opsForValue().increment(key, delta); + return redisTemplate.opsForValue().increment(handleKey(key), delta); } @Override public Long decr(String key, long delta) { - return redisTemplate.opsForValue().increment(key, -delta); + return redisTemplate.opsForValue().increment(handleKey(key), -delta); } @Override public Object hGet(String key, String hashKey) { - return redisTemplate.opsForHash().get(key, hashKey); + return redisTemplate.opsForHash().get(handleKey(key), hashKey); } @Override public Boolean hSet(String key, String hashKey, Object value, long time) { - redisTemplate.opsForHash().put(key, hashKey, value); - return expire(key, time); + String newKey = handleKey(key); + redisTemplate.opsForHash().put(newKey, hashKey, value); + return expire(newKey, time); } @Override public void hSet(String key, String hashKey, Object value) { - redisTemplate.opsForHash().put(key, hashKey, value); + redisTemplate.opsForHash().put(handleKey(key), hashKey, value); } @Override public Map hGetAll(String key) { - return redisTemplate.opsForHash().entries(key); + return redisTemplate.opsForHash().entries(handleKey(key)); } @Override public Boolean hSetAll(String key, Map map, long time) { - redisTemplate.opsForHash().putAll(key, map); - return expire(key, time); + String newKey = handleKey(key); + redisTemplate.opsForHash().putAll(newKey, map); + return expire(newKey, time); } @Override public void hSetAll(String key, Map map) { - redisTemplate.opsForHash().putAll(key, map); + redisTemplate.opsForHash().putAll(handleKey(key), map); } @Override public void hDel(String key, Object... hashKey) { - redisTemplate.opsForHash().delete(key, hashKey); + redisTemplate.opsForHash().delete(handleKey(key), hashKey); } @Override public Boolean hHasKey(String key, String hashKey) { - return redisTemplate.opsForHash().hasKey(key, hashKey); + return redisTemplate.opsForHash().hasKey(handleKey(key), hashKey); } @Override public Long hIncr(String key, String hashKey, Long delta) { - return redisTemplate.opsForHash().increment(key, hashKey, delta); + return redisTemplate.opsForHash().increment(handleKey(key), hashKey, delta); } @Override public Long hDecr(String key, String hashKey, Long delta) { - return redisTemplate.opsForHash().increment(key, hashKey, -delta); + return redisTemplate.opsForHash().increment(handleKey(key), hashKey, -delta); } @Override public Set sMembers(String key) { - return redisTemplate.opsForSet().members(key); + return redisTemplate.opsForSet().members(handleKey(key)); } @Override public Long sAdd(String key, Object... values) { - return redisTemplate.opsForSet().add(key, values); + return redisTemplate.opsForSet().add(handleKey(key), values); } @Override public Long sAdd(String key, long time, Object... values) { - Long count = redisTemplate.opsForSet().add(key, values); - expire(key, time); + String newKey = handleKey(key); + Long count = redisTemplate.opsForSet().add(newKey, values); + expire(newKey, time); return count; } @Override public Boolean sIsMember(String key, Object value) { - return redisTemplate.opsForSet().isMember(key, value); + return redisTemplate.opsForSet().isMember(handleKey(key), value); } @Override public Long sSize(String key) { - return redisTemplate.opsForSet().size(key); + return redisTemplate.opsForSet().size(handleKey(key)); } @Override public Long sRemove(String key, Object... values) { - return redisTemplate.opsForSet().remove(key, values); + return redisTemplate.opsForSet().remove(handleKey(key), values); } @Override public List lRange(String key, long start, long end) { - return redisTemplate.opsForList().range(key, start, end); + return redisTemplate.opsForList().range(handleKey(key), start, end); } @Override public Long lSize(String key) { - return redisTemplate.opsForList().size(key); + return redisTemplate.opsForList().size(handleKey(key)); } @Override public Object lIndex(String key, long index) { - return redisTemplate.opsForList().index(key, index); + return redisTemplate.opsForList().index(handleKey(key), index); } @Override public Long lPush(String key, Object value) { - return redisTemplate.opsForList().rightPush(key, value); + return redisTemplate.opsForList().rightPush(handleKey(key), value); } @Override public Long lPush(String key, Object value, long time) { - Long index = redisTemplate.opsForList().rightPush(key, value); - expire(key, time); + String newKey = handleKey(key); + Long index = redisTemplate.opsForList().rightPush(newKey, value); + expire(newKey, time); return index; } @Override public Long lPushAll(String key, Object... values) { - return redisTemplate.opsForList().rightPushAll(key, values); + return redisTemplate.opsForList().rightPushAll(handleKey(key), values); } @Override public Long lPushAll(String key, Long time, Object... values) { - Long count = redisTemplate.opsForList().rightPushAll(key, values); - expire(key, time); + String newKey = handleKey(key); + Long count = redisTemplate.opsForList().rightPushAll(newKey, values); + expire(newKey, time); return count; } @Override public Long lRemove(String key, long count, Object value) { - return redisTemplate.opsForList().remove(key, count, value); + return redisTemplate.opsForList().remove(handleKey(key), count, value); } @Override public Collection getKeys(String key) { - return redisTemplate.keys(key); + return redisTemplate.keys(handleKey(key)); } @Override @SuppressWarnings("unchecked") public T getObject(String key, Class clazz) { - return (T) get(key); + return (T) get(handleKey(key)); } @Override @SuppressWarnings("unchecked") public List getObjectList(String key, Class clazz) { - return (List) get(key); + return (List) get(handleKey(key)); } + private String handleKey(String key) { + StringBuilder sb = new StringBuilder(); + sb.append("tenant_").append(TenantUtil.getTenantId()).append(":").append(key); + return sb.toString(); + } } diff --git a/qiaoba-commons/qiaoba-common-security/pom.xml b/qiaoba-commons/qiaoba-common-security/pom.xml deleted file mode 100644 index 05c0f09..0000000 --- a/qiaoba-commons/qiaoba-common-security/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - qiaoba-commons - com.qiaoba - 1.0 - - 4.0.0 - - qiaoba-common-security - - - - com.qiaoba - qiaoba-common-web - - - - diff --git a/qiaoba-commons/qiaoba-common-security/src/main/java/com/qiaoba/common/security/utils/SecurityUtil.java b/qiaoba-commons/qiaoba-common-security/src/main/java/com/qiaoba/common/security/utils/SecurityUtil.java deleted file mode 100644 index 3833885..0000000 --- a/qiaoba-commons/qiaoba-common-security/src/main/java/com/qiaoba/common/security/utils/SecurityUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.qiaoba.common.security.utils; - -/** - * SecurityUtil - * - * @author ailanyin - * @version 1.0 - * @since 2023/5/9 9:22 - */ -public class SecurityUtil { - - /** - * 获取登录用户的账号 - * - * @return username - */ - public static String getLoginUsername() { - return "admin"; - } - - /** - * 获取登录用户的ID - * - * @return username - */ - public static String getLoginUserId() { - return "1L"; - } - -} diff --git a/qiaoba-commons/qiaoba-common-web/src/main/java/com/qiaoba/common/web/advice/ExceptionAdvice.java b/qiaoba-commons/qiaoba-common-web/src/main/java/com/qiaoba/common/web/advice/ExceptionAdvice.java index 87e4f05..7a1406e 100644 --- a/qiaoba-commons/qiaoba-common-web/src/main/java/com/qiaoba/common/web/advice/ExceptionAdvice.java +++ b/qiaoba-commons/qiaoba-common-web/src/main/java/com/qiaoba/common/web/advice/ExceptionAdvice.java @@ -3,10 +3,14 @@ package com.qiaoba.common.web.advice; import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.base.result.AjaxResult; +import org.springframework.validation.BindException; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.Objects; + /** * 全局异常处理 * @@ -38,8 +42,31 @@ public class ExceptionAdvice { */ @ExceptionHandler(ServiceException.class) @ResponseBody - public AjaxResult handlerApiException(ServiceException e) { + public AjaxResult handlerServiceException(ServiceException e) { return AjaxResult.error(e.getMessage()); } + /** + * 参数校验 + * + * @param e MethodArgumentNotValidException + * @return AjaxResult + */ + @ExceptionHandler({MethodArgumentNotValidException.class}) + @ResponseBody + public AjaxResult handlerValidException(MethodArgumentNotValidException e) { + return AjaxResult.error(Objects.isNull(e.getBindingResult().getFieldError()) ? e.getMessage() : e.getBindingResult().getFieldError().getDefaultMessage()); + } + + /** + * 参数校验 + * + * @param e BindException + * @return AjaxResult + */ + @ExceptionHandler({BindException.class}) + @ResponseBody + public AjaxResult handlerValidException(BindException e) { + return AjaxResult.error(Objects.isNull(e.getBindingResult().getFieldError()) ? e.getMessage() : e.getBindingResult().getFieldError().getDefaultMessage()); + } } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysDeptController.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysDeptController.java index 89a7726..e605dff 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysDeptController.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysDeptController.java @@ -4,7 +4,10 @@ import com.qiaoba.api.system.entity.SysDept; import com.qiaoba.api.system.entity.param.SysDeptParam; import com.qiaoba.common.base.result.AjaxResult; import com.qiaoba.module.system.service.SysDeptService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,50 +22,58 @@ import java.util.List; */ @RestController @RequestMapping("/system/dept") +@Tag(name = "部门管理") @RequiredArgsConstructor public class SysDeptController { private final SysDeptService sysDeptService; - //@PreAuthorize("hasAuthority('system:dept:list')") + @PreAuthorize("hasAuthority('system:dept:list')") @GetMapping("/list") + @Operation(summary = "获取列表") public AjaxResult list(SysDeptParam param) { return AjaxResult.success(sysDeptService.selectList(param)); } - //@PreAuthorize("hasAuthority('system:dept:list')") + @PreAuthorize("hasAuthority('system:dept:list')") @GetMapping("/list/exclude/{deptId}") + @Operation(summary = "查询部门列表(排除节点)") public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) String deptId) { return AjaxResult.success(sysDeptService.excludeChild(deptId)); } - //@PreAuthorize("hasAuthority('system:dept:query')") + @PreAuthorize("hasAuthority('system:dept:query')") @GetMapping(value = "/{deptId}") - public AjaxResult getInfo(@PathVariable Long deptId) { + @Operation(summary = "获取详情") + public AjaxResult getInfo(@PathVariable String deptId) { return AjaxResult.success(sysDeptService.selectById(deptId)); } @GetMapping("/deptTree") + @Operation(summary = "构建部门树") public AjaxResult deptTree(SysDeptParam param) { List list = sysDeptService.selectList(param); return AjaxResult.success(sysDeptService.buildDeptTree(list)); } - //@PreAuthorize("hasAuthority('system:dept:add')") + @PreAuthorize("hasAuthority('system:dept:add')") @PostMapping + @Operation(summary = "新增部门") public AjaxResult add(@Validated @RequestBody SysDept dept) { return AjaxResult.toAjax(sysDeptService.insert(dept)); } - //@PreAuthorize("hasAuthority('system:dept:edit')") + @PreAuthorize("hasAuthority('system:dept:edit')") @PutMapping + @Operation(summary = "修改部门") public AjaxResult edit(@Validated @RequestBody SysDept dept) { return AjaxResult.toAjax(sysDeptService.updateById(dept)); } - //@PreAuthorize("hasAuthority('system:dept:remove')") + @PreAuthorize("hasAuthority('system:dept:remove')") @DeleteMapping("/{id}") - public AjaxResult remove(@PathVariable Long id) { + @Operation(summary = "删除部门") + public AjaxResult remove(@PathVariable String id) { return AjaxResult.toAjax(sysDeptService.deleteById(id)); } } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysLoginController.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysLoginController.java index ff23662..e1824e8 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysLoginController.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysLoginController.java @@ -1,18 +1,22 @@ package com.qiaoba.module.system.controller; -import com.qiaoba.api.system.entity.SysMenu; +import com.qiaoba.api.system.entity.dto.LoginDto; import com.qiaoba.api.system.entity.vo.SysMenuVo; +import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.common.base.result.AjaxResult; +import com.qiaoba.module.system.service.SysLoginService; import com.qiaoba.module.system.service.SysMenuService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.Set; /** - * 登录 + * 登录 Web层 * * @author ailanyin * @version 1.0 @@ -23,15 +27,30 @@ import java.util.List; public class SysLoginController { private final SysMenuService sysMenuService; + private final SysLoginService sysLoginService; + @GetMapping("/captchaImage") + public AjaxResult getCaptchaImage() { + return sysLoginService.getCaptchaImage(); + } + @PostMapping("/login") - public String login() { - return "{\"msg\":\"操作成功\",\"code\":200,\"token\":\"eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjhhNjY4MGY1LTI0OTAtNDUyYi1hYzQ1LWE5YWI0MzQ0YTRlYyJ9.mTZr7TN1Jk2-_7zbeUbOBuHijVLiqY2QSbhcAIfWuX4oF22xGw_DpxOz3I2_-TLeYlJN4y2Gm1qmw6ricqCBqw\"}"; + public AjaxResult login(@RequestBody LoginDto dto) { + String token = sysLoginService.login(dto); + AjaxResult ajax = AjaxResult.success(); + ajax.put("token", token); + return ajax; } @GetMapping("/getInfo") public String getInfo() { + List roleIds = SecurityUtil.getLoginUser().getRoleIds(); + Set permissions = SecurityUtil.getLoginUser().getPermissions(); + AjaxResult ajax = AjaxResult.success(); + ajax.put("permissions", permissions); + ajax.put("roles", roleIds); + ajax.put("user",sysLoginService.selectUserFromCache(SecurityUtil.getLoginUserId())); return "{\"msg\":\"操作成功\",\"code\":200,\"permissions\":[\"*:*:*\"],\"roles\":[\"admin\"],\"user\":{\"createBy\":\"admin\",\"createTime\":\"2023-04-23 16:11:38\",\"updateBy\":null,\"updateTime\":null,\"remark\":\"管理员\",\"userId\":1,\"deptId\":103,\"userName\":\"admin\",\"nickName\":\"若依\",\"email\":\"ry@163.com\",\"phonenumber\":\"15888888888\",\"sex\":\"1\",\"avatar\":\"\",\"password\":\"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2\",\"status\":\"0\",\"delFlag\":\"0\",\"loginIp\":\"27.154.23.192\",\"loginDate\":\"2023-05-05T09:45:24.000+08:00\",\"dept\":{\"createBy\":null,\"createTime\":null,\"updateBy\":null,\"updateTime\":null,\"remark\":null,\"deptId\":103,\"parentId\":101,\"ancestors\":\"0,100,101\",\"deptName\":\"研发部门\",\"orderNum\":1,\"leader\":\"若依\",\"phone\":null,\"email\":null,\"status\":\"0\",\"delFlag\":null,\"parentName\":null,\"children\":[]},\"roles\":[{\"createBy\":null,\"createTime\":null,\"updateBy\":null,\"updateTime\":null,\"remark\":null,\"roleId\":1,\"roleName\":\"超级管理员\",\"roleKey\":\"admin\",\"roleSort\":1,\"dataScope\":\"1\",\"menuCheckStrictly\":false,\"deptCheckStrictly\":false,\"status\":\"0\",\"delFlag\":null,\"flag\":false,\"menuIds\":null,\"deptIds\":null,\"permissions\":null,\"admin\":true}],\"roleIds\":null,\"postIds\":null,\"roleId\":null,\"admin\":true}}"; } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysPostController.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysPostController.java index aa52bed..009e5b3 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysPostController.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysPostController.java @@ -7,7 +7,11 @@ import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.TableDataInfo; import com.qiaoba.common.poi.utils.ExcelUtil; import com.qiaoba.module.system.service.SysPostService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; @@ -23,68 +27,52 @@ import java.util.List; @RestController @RequestMapping("/system/post") @RequiredArgsConstructor +@Tag(name = "岗位管理") public class SysPostController { private final SysPostService sysPostService; - /** - * 获取岗位列表 - */ @GetMapping("/list") - //@PreAuthorize("hasAuthority('system:post:list')") + @PreAuthorize("hasAuthority('system:post:list')") + @Operation(summary = "获取列表") public TableDataInfo list(SysPostParam param, PageQuery pageQuery) { return sysPostService.selectPageList(param, pageQuery); } @PostMapping("/export") - //@PreAuthorize("hasAuthority('system:post:export')") + @PreAuthorize("hasAuthority('system:post:export')") + @Operation(summary = "导出岗位") public void export(HttpServletResponse response, SysPostParam param) { List list = sysPostService.selectList(param); ExcelUtil.exportExcel(list, SysPost.class, "岗位数据", response); } - /** - * 根据岗位编号获取详细信息 - */ @GetMapping(value = "/{postId}") - //@PreAuthorize("hasAuthority('system:post:query')") + @PreAuthorize("hasAuthority('system:post:query')") + @Operation(summary = "获取详情") public AjaxResult getInfo(@PathVariable("postId") String postId) { return AjaxResult.success(sysPostService.selectById(postId)); } - /** - * 新增岗位 - */ @PostMapping - //@PreAuthorize("hasAuthority('system:post:add')") - public AjaxResult add(@RequestBody SysPost post) { + @PreAuthorize("hasAuthority('system:post:add')") + @Operation(summary = "新增岗位") + public AjaxResult add(@Validated @RequestBody SysPost post) { return AjaxResult.toAjax(sysPostService.insert(post)); } - /** - * 修改岗位 - */ @PutMapping - //@PreAuthorize("hasAuthority('system:post:edit')") - public AjaxResult edit(@RequestBody SysPost post) { + @PreAuthorize("hasAuthority('system:post:edit')") + @Operation(summary = "修改岗位") + public AjaxResult edit(@Validated @RequestBody SysPost post) { return AjaxResult.toAjax(sysPostService.updateById(post)); } - /** - * 删除岗位 - */ @DeleteMapping("/{ids}") - //@PreAuthorize("hasAuthority('system:post:remove')") + @PreAuthorize("hasAuthority('system:post:remove')") + @Operation(summary = "删除岗位") public AjaxResult remove(@PathVariable List ids) { return AjaxResult.toAjax(sysPostService.deleteByIds(ids)); } - /** - * 获取岗位选择框列表 - */ -/* @GetMapping("/optionSelect") - public AjaxResult optionSelect() { - List posts = postService.selectPostAll(); - return AjaxResult.success(posts); - }*/ } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysUserController.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysUserController.java index 6193bc5..234557c 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysUserController.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/controller/SysUserController.java @@ -98,7 +98,7 @@ public class SysUserController { SysUser sysUser = sysUserService.selectById(userId, false); ajax.put(AjaxResult.DATA_TAG, sysUser); ajax.put("postIds", sysUserPostService.selectPostIdsByUserId(userId)); - ajax.put("roleIds", sysUserRoleService.selectRoleIdsByUserId(userId)); + ajax.put("roleIds", sysUserRoleService.selectRoleIdsByUserId(userId, null)); } return ajax; } @@ -111,7 +111,7 @@ public class SysUserController { List roles = sysRoleService.selectList(new SysRoleParam()); ajax.put("user", user); ajax.put("roles", roles); - ajax.put("hasRoleIds", sysUserRoleService.selectRoleIdsByUserId(userId)); + ajax.put("hasRoleIds", sysUserRoleService.selectRoleIdsByUserId(userId, null)); return ajax; } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysDeptMapper.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysDeptMapper.java index 2acf0cd..72e5ba9 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysDeptMapper.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysDeptMapper.java @@ -30,4 +30,20 @@ public interface SysDeptMapper extends BaseMapper { */ List selectDeptIdsByRoleId(String roleId); + /** + * 检查是否存在子部门 + * + * @param deptId deptId + * @return != null -> 是 + */ + String existChild(String deptId); + + /** + * 检查部门是否被使用 + * + * @param deptId deptId + * @return != null -> 是 + */ + String existUsed(String deptId); + } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysMenuMapper.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysMenuMapper.java index dfb7cc9..a13d222 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysMenuMapper.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysMenuMapper.java @@ -5,6 +5,7 @@ import com.qiaoba.api.system.entity.vo.SysMenuVo; import com.qiaoba.common.database.mapper.BaseMapperPlus; import java.util.List; +import java.util.Set; /** * 菜单管理 数据层 @@ -38,4 +39,12 @@ public interface SysMenuMapper extends BaseMapperPlus selectByUserId(String userId); + + /** + * 查询用户拥有的权限列表 + * + * @param userId userId + * @return 权限列表 + */ + Set selectPermsByUserId(String userId); } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysPostMapper.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysPostMapper.java index cac5ee0..01671e3 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysPostMapper.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysPostMapper.java @@ -18,7 +18,7 @@ public interface SysPostMapper extends BaseMapper { * @param sysPost 岗位名称 * @return 结果 */ - int checkPostNameUnique(SysPost sysPost); + String checkPostNameUnique(SysPost sysPost); /** * 校验岗位编码 @@ -26,6 +26,6 @@ public interface SysPostMapper extends BaseMapper { * @param sysPost 岗位编码 * @return 结果 */ - int checkPostCodeUnique(SysPost sysPost); + String checkPostCodeUnique(SysPost sysPost); } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserPostMapper.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserPostMapper.java index b69a8ee..00a5faa 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserPostMapper.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserPostMapper.java @@ -2,6 +2,7 @@ package com.qiaoba.module.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.qiaoba.api.system.entity.SysUserPost; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -20,4 +21,12 @@ public interface SysUserPostMapper extends BaseMapper { * @return postIds */ List selectPostIdsByUserId(String userId); + + /** + * 查询正在被使用的岗位名称列表 + * + * @param postIds postIds + * @return postNames + */ + List selectUsedPostNameByIds(@Param("list") List postIds); } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserRoleMapper.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserRoleMapper.java index 0c5cc81..4cccc62 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserRoleMapper.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/mapper/SysUserRoleMapper.java @@ -19,9 +19,10 @@ public interface SysUserRoleMapper extends BaseMapper { * 通过userId查询所绑定的角色ID列表 * * @param userId userId + * @param status 状态 * @return roleIds */ - List selectRoleIdsByUserId(String userId); + List selectRoleIdsByUserId(@Param("userId") String userId, @Param("status") String status); /** * 批量取消角色所绑定的用户 diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysLoginService.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysLoginService.java new file mode 100644 index 0000000..4268184 --- /dev/null +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysLoginService.java @@ -0,0 +1,38 @@ +package com.qiaoba.module.system.service; + +import com.qiaoba.api.system.entity.SysUser; +import com.qiaoba.api.system.entity.dto.LoginDto; +import com.qiaoba.common.base.result.AjaxResult; + +/** + * 登录 服务层 + * + * @author ailanyin + * @version 1.0 + * @since 2023/5/15 15:31 + */ +public interface SysLoginService { + + /** + * 生成图片验证码 + * + * @return uuid + base64 + */ + AjaxResult getCaptchaImage(); + + /** + * 登录 + * + * @param dto dto + * @return token + */ + String login(LoginDto dto); + + /** + * 从缓存中读取user + * + * @param userId userId + * @return SysUser + */ + SysUser selectUserFromCache(String userId); +} diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysMenuService.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysMenuService.java index 59cca3c..87f54dc 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysMenuService.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysMenuService.java @@ -7,6 +7,7 @@ import com.qiaoba.api.system.entity.vo.SysMenuVo; import com.qiaoba.api.system.service.SysMenuApiService; import java.util.List; +import java.util.Set; /** * 菜单管理 服务层 @@ -41,6 +42,14 @@ public interface SysMenuService extends SysMenuApiService { */ List selectByUserId(String userId); + /** + * 查询用户拥有的权限列表 + * + * @param userId userId + * @return 权限列表 + */ + Set selectPermsByUserId(String userId); + /** * 菜单转路由 * diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserPostService.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserPostService.java index ac2138e..834adbf 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserPostService.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserPostService.java @@ -34,4 +34,12 @@ public interface SysUserPostService { * @return postIds */ List selectPostIdsByUserId(String userId); + + /** + * 查询正在被使用的岗位名称列表 + * + * @param postIds postIds + * @return postNames + */ + List selectUsedPostNameByIds(List postIds); } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserRoleService.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserRoleService.java index 5855551..669979b 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserRoleService.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserRoleService.java @@ -39,9 +39,10 @@ public interface SysUserRoleService { * 通过userId查询所绑定的角色ID列表 * * @param userId userId + * @param status 状态 * @return roleIds */ - List selectRoleIdsByUserId(String userId); + List selectRoleIdsByUserId(String userId, String status); /** * 批量选择用户授权 diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserService.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserService.java index b236963..d026b03 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserService.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/SysUserService.java @@ -62,4 +62,5 @@ public interface SysUserService extends SysUserApiService { * @return list */ TableDataInfo selectUnAllocatedList(SysUserParam param, PageQuery pageQuery); + } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysDeptServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysDeptServiceImpl.java index 0ebbc56..7030beb 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysDeptServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysDeptServiceImpl.java @@ -9,10 +9,10 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.toolkit.Db; import com.qiaoba.api.system.entity.SysDept; import com.qiaoba.api.system.entity.param.SysDeptParam; +import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.common.base.constants.BaseConstant; import com.qiaoba.common.base.enums.BaseEnum; import com.qiaoba.common.base.exceptions.ServiceException; -import com.qiaoba.common.security.utils.SecurityUtil; import com.qiaoba.module.system.mapper.SysDeptMapper; import com.qiaoba.module.system.service.SysDeptService; import lombok.RequiredArgsConstructor; @@ -36,6 +36,7 @@ public class SysDeptServiceImpl implements SysDeptService { private final SysDeptMapper sysDeptMapper; + @Override public int insert(SysDept sysDept) { if (checkDeptNameNotUnique(sysDept)) { @@ -83,12 +84,19 @@ public class SysDeptServiceImpl implements SysDeptService { } @Override - public SysDept selectById(Long deptId) { + public SysDept selectById(String deptId) { return sysDeptMapper.selectById(deptId); } @Override - public int deleteById(Long deptId) { + public int deleteById(String deptId) { + if (StrUtil.isNotBlank(sysDeptMapper.existChild(deptId))) { + throw new ServiceException("存在子级部门,不允许删除"); + } + String nickname = sysDeptMapper.existUsed(deptId); + if (StrUtil.isNotBlank(nickname)) { + throw new ServiceException(StrUtil.format("用户[{}]已绑定部门,不允许删除", nickname)); + } return sysDeptMapper.deleteById(deptId); } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysLoginServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysLoginServiceImpl.java new file mode 100644 index 0000000..10ad710 --- /dev/null +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysLoginServiceImpl.java @@ -0,0 +1,146 @@ +package com.qiaoba.module.system.service.impl; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.LineCaptcha; +import cn.hutool.core.lang.UUID; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.qiaoba.api.system.entity.SysUser; +import com.qiaoba.api.system.entity.dto.LoginDto; +import com.qiaoba.auth.constants.SecurityConstant; +import com.qiaoba.auth.utils.SecurityUtil; +import com.qiaoba.auth.utils.TokenUtil; +import com.qiaoba.common.base.enums.BaseEnum; +import com.qiaoba.common.base.exceptions.ServiceException; +import com.qiaoba.common.base.result.AjaxResult; +import com.qiaoba.common.redis.service.RedisService; +import com.qiaoba.module.system.service.SysLoginService; +import com.qiaoba.module.system.service.SysUserService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; + +/** + * 登录 服务层实现 + * + * @author ailanyin + * @version 1.0 + * @since 2023/5/15 15:31 + */ +@Service +@RequiredArgsConstructor +public class SysLoginServiceImpl implements SysLoginService { + + private final RedisService redisService; + private final HttpServletRequest request; + private final UserDetailsService userDetailsService; + private final SysUserService sysUserService; + + @Override + public AjaxResult getCaptchaImage() { + AjaxResult ajax = AjaxResult.success(); + ajax.put("register", getRegisterConfig()); + if (!getCaptchaConfig()) { + ajax.put("captchaEnabled", false); + return ajax; + } + String uuid = UUID.randomUUID().toString(true); + LineCaptcha captcha = CaptchaUtil.createLineCaptcha(150, 50, 4, 20); + ajax.put("uuid", uuid); + ajax.put("img", captcha.getImageBase64()); + redisService.set(SecurityConstant.CAPTCHA_KEY + uuid, captcha.getCode(), 120); + + return ajax; + } + + @Override + public String login(LoginDto dto) { + // 校验验证码 + validateCaptcha(dto.getCode(), dto.getUuid()); + // username查询用户信息 + SysUser sysUser = sysUserService.selectByUsername(dto.getUsername()); + // 检查账号信息 + validateUser(dto.getUsername(), sysUser); + // 检验密码 + validatePassword(dto.getUsername(), sysUser.getPassword(), dto.getPassword()); + // 缓存user + addUserToCache(sysUser); + // 创建UserDetails + UserDetails userDetails = userDetailsService.loadUserByUsername(dto.getUsername()); + // 生成Token + return TokenUtil.generateToken(userDetails.getUsername()); + } + + @Override + public SysUser selectUserFromCache(String userId) { + return redisService.getObject(userId, SysUser.class); + } + + private void addUserToCache(SysUser sysUser) { + sysUser.setPassword(null); + redisService.set(sysUser.getUserId(), sysUser); + } + + private void validatePassword(String username, String password, String inputPassword) { + boolean result = SecurityUtil.matchesPassword(inputPassword, password); + if (!result) { + beforePasswordError(username); + throw new ServiceException(SecurityConstant.PASSWORD_ERROR); + } + } + + private void beforePasswordError(String username) { + + } + + private void validateUser(String username, SysUser user) { + if (ObjectUtil.isNull(user)) { + throw new ServiceException(StrUtil.format("登录用户:{} 不存在", username)); + } else if (BaseEnum.YES.getCode().equals(user.getIsDelete())) { + throw new ServiceException(StrUtil.format("对不起, 您的账号:{} 已被删除", username)); + } else if (BaseEnum.ABNORMAL.getCode().equals(user.getStatus())) { + throw new ServiceException(StrUtil.format("对不起, 您的账号:{} 已被禁用", username)); + } + } + + private boolean getCaptchaConfig() { + return false; +/* try { + return SecurityConstant.CAPTCHA_ON.equals(redisService.get(SecurityConstant.CAPTCHA_ON_OFF_KEY)); + } catch (Exception e) { + throw new ServiceException("Redis中验证码配置不存在!"); + }*/ + } + + private boolean getRegisterConfig() { + return false; + /* try { + return SecurityConstant.REGISTER_ON.equals(redisService.get(SecurityConstant.REGISTER_ON_OFF_KEY)); + } catch (Exception e) { + throw new ServiceException("Redis中注册配置不存在!"); + }*/ + } + + private void validateCaptcha(String code, String uuid) { + if (getCaptchaConfig()) { + if (StrUtil.isBlank(code) || StrUtil.isBlank(uuid)) { + throw new ServiceException("验证码或uuid获取失败!"); + } + try { + if (!redisService.hasKey(SecurityConstant.CAPTCHA_KEY + uuid)) { + throw new ServiceException("验证码已经过期失效!"); + } else { + if (!code.equalsIgnoreCase(redisService.get(SecurityConstant.CAPTCHA_KEY + uuid).toString())) { + throw new ServiceException("验证码输入错误!"); + } + } + + } finally { + redisService.del(SecurityConstant.CAPTCHA_KEY + uuid); + } + } + } +} diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysMenuServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysMenuServiceImpl.java index 2310468..bbe5f09 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysMenuServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysMenuServiceImpl.java @@ -19,6 +19,7 @@ import org.springframework.stereotype.Service; import java.util.Date; import java.util.List; +import java.util.Set; /** * 菜单管理 服务层实现 @@ -94,6 +95,11 @@ public class SysMenuServiceImpl implements SysMenuService { return sysMenuMapper.selectByUserId(userId); } + @Override + public Set selectPermsByUserId(String userId) { + return sysMenuMapper.selectPermsByUserId(userId); + } + @Override public List menusToRouters(List menus) { return MenuUtil.menusToRouters(menus); diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysPostServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysPostServiceImpl.java index 56b69db..5826481 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysPostServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysPostServiceImpl.java @@ -1,5 +1,6 @@ package com.qiaoba.module.system.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.qiaoba.api.system.entity.SysPost; @@ -7,9 +8,10 @@ import com.qiaoba.api.system.entity.param.SysPostParam; import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.TableDataInfo; -import com.qiaoba.common.security.utils.SecurityUtil; +import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.module.system.mapper.SysPostMapper; import com.qiaoba.module.system.service.SysPostService; +import com.qiaoba.module.system.service.SysUserPostService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -28,6 +30,7 @@ import java.util.List; public class SysPostServiceImpl implements SysPostService { private final SysPostMapper sysPostMapper; + private final SysUserPostService sysUserPostService; @Override public TableDataInfo selectPageList(SysPostParam param, PageQuery pageQuery) { @@ -64,11 +67,13 @@ public class SysPostServiceImpl implements SysPostService { @Override public int deleteById(String deptId) { + checkAllowDelete(CollUtil.toList(deptId)); return sysPostMapper.deleteById(deptId); } @Override public int deleteByIds(List ids) { + checkAllowDelete(ids); return sysPostMapper.deleteBatchIds(ids); } @@ -88,8 +93,8 @@ public class SysPostServiceImpl implements SysPostService { * @param post 岗位信息 */ private void checkPostNameUnique(SysPost post) { - if (sysPostMapper.checkPostNameUnique(post) > 0) { - throw new ServiceException(StrUtil.format("处理岗位'{}'失败,岗位名称已存在", post.getPostName())); + if (StrUtil.isNotBlank(sysPostMapper.checkPostNameUnique(post))) { + throw new ServiceException(StrUtil.format("处理岗位{}失败, 岗位名称已存在", post.getPostName())); } } @@ -99,8 +104,20 @@ public class SysPostServiceImpl implements SysPostService { * @param post 岗位信息 */ private void checkPostCodeUnique(SysPost post) { - if (sysPostMapper.checkPostCodeUnique(post) > 0) { - throw new ServiceException(StrUtil.format("处理岗位'{}'失败,岗位编码已存在", post.getPostName())); + if (StrUtil.isNotBlank(sysPostMapper.checkPostCodeUnique(post))) { + throw new ServiceException(StrUtil.format("处理岗位{}失败, 岗位编码已存在", post.getPostName())); + } + } + + /** + * 检查岗位是否允许删除 + * + * @param ids ids + */ + private void checkAllowDelete(List ids) { + List names = sysUserPostService.selectUsedPostNameByIds(ids); + if (CollUtil.isNotEmpty(names)) { + throw new ServiceException(StrUtil.format("删除岗位{}失败, 岗位已绑定用户", names.toString())); } } } diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysRoleServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysRoleServiceImpl.java index e8b120e..73883b9 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysRoleServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysRoleServiceImpl.java @@ -13,7 +13,7 @@ import com.qiaoba.api.system.entity.param.SysRoleParam; import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.TableDataInfo; -import com.qiaoba.common.security.utils.SecurityUtil; +import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.module.system.mapper.SysRoleMapper; import com.qiaoba.module.system.service.SysRoleDeptService; import com.qiaoba.module.system.service.SysRoleMenuService; @@ -105,6 +105,7 @@ public class SysRoleServiceImpl implements SysRoleService { return row; } + private QueryWrapper param2Wrapper(SysRoleParam param) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda() diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserDetailsServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserDetailsServiceImpl.java new file mode 100644 index 0000000..a2513e5 --- /dev/null +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserDetailsServiceImpl.java @@ -0,0 +1,48 @@ +package com.qiaoba.module.system.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.qiaoba.api.system.entity.SysUser; +import com.qiaoba.auth.entity.LoginUser; +import com.qiaoba.common.base.enums.BaseEnum; +import com.qiaoba.module.system.service.SysMenuService; +import com.qiaoba.module.system.service.SysUserRoleService; +import com.qiaoba.module.system.service.SysUserService; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; + +/** + * 用户权限验证处理 + * + * @author ailanyin + * @version 1.0 + * @since 2022-09-22 04:20:28 + */ +@Service +@RequiredArgsConstructor +public class SysUserDetailsServiceImpl implements UserDetailsService { + + private final SysUserService sysUserService; + private final SysMenuService sysMenuService; + private final SysUserRoleService sysUserRoleService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + SysUser user = sysUserService.selectByUsername(username); + StrUtil.format("{}",1); + return createUserDetails(user); + } + + + private UserDetails createUserDetails(SysUser user) { + Set perms = sysMenuService.selectPermsByUserId(user.getUserId()); + List roleIds = sysUserRoleService.selectRoleIdsByUserId(user.getUserId(), BaseEnum.NORMAL.getCode()); + return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), roleIds, perms); + } + +} diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserPostServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserPostServiceImpl.java index 40142c6..013d691 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserPostServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserPostServiceImpl.java @@ -38,6 +38,11 @@ public class SysUserPostServiceImpl implements SysUserPostService { return sysUserPostMapper.selectPostIdsByUserId(userId); } + @Override + public List selectUsedPostNameByIds(List postIds) { + return sysUserPostMapper.selectUsedPostNameByIds(postIds); + } + private QueryWrapper createWrapper(String userId) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda() diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserRoleServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserRoleServiceImpl.java index 6bed0ea..f02342d 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserRoleServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserRoleServiceImpl.java @@ -40,8 +40,8 @@ public class SysUserRoleServiceImpl implements SysUserRoleService { } @Override - public List selectRoleIdsByUserId(String userId) { - return sysUserRoleMapper.selectRoleIdsByUserId(userId); + public List selectRoleIdsByUserId(String userId, String status) { + return sysUserRoleMapper.selectRoleIdsByUserId(userId, status); } @Override diff --git a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserServiceImpl.java b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserServiceImpl.java index c0b18ab..4042a42 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserServiceImpl.java +++ b/qiaoba-modules/qiaoba-module-system/src/main/java/com/qiaoba/module/system/service/impl/SysUserServiceImpl.java @@ -17,7 +17,9 @@ import com.qiaoba.common.base.enums.BaseEnum; import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.TableDataInfo; -import com.qiaoba.common.security.utils.SecurityUtil; +import com.qiaoba.common.redis.constants.CacheConstant; +import com.qiaoba.common.redis.service.RedisService; +import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.module.system.mapper.SysUserMapper; import com.qiaoba.module.system.service.SysUserPostService; import com.qiaoba.module.system.service.SysUserRoleService; @@ -41,6 +43,7 @@ public class SysUserServiceImpl implements SysUserService { private final SysUserMapper sysUserMapper; private final SysUserPostService sysUserPostService; private final SysUserRoleService sysUserRoleService; + private final RedisService redisService; @Override public int saveOrUpdate(SysUserDto dto, Boolean isUpdate) { @@ -71,6 +74,14 @@ public class SysUserServiceImpl implements SysUserService { return sysUser; } + @Override + public SysUser selectByUsername(String username) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.lambda() + .eq(SysUser::getUsername, username); + return sysUserMapper.selectOne(wrapper); + } + @Override public int resetPwd(ResetPwdDto dto) { // todo 加密密码 @@ -157,7 +168,6 @@ public class SysUserServiceImpl implements SysUserService { private SysUser dtoToSysUser(SysUserDto dto, Boolean isUpdate) { if (StrUtil.isNotBlank(dto.getPassword())) { - // todo 加密密码 dto.setPassword("123456"); } SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class); diff --git a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysDeptMapper.xml b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysDeptMapper.xml index 00a1c2b..8e74d83 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysDeptMapper.xml +++ b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysDeptMapper.xml @@ -19,4 +19,12 @@ order by d.parent_id, d.order_num + + + + diff --git a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysMenuMapper.xml b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysMenuMapper.xml index 440eff5..6198cdb 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysMenuMapper.xml +++ b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysMenuMapper.xml @@ -24,11 +24,25 @@ + + diff --git a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysPostMapper.xml b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysPostMapper.xml index 5406bb3..1526a0a 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysPostMapper.xml +++ b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysPostMapper.xml @@ -4,8 +4,8 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + select post_id from sys_post where post_name = #{postName} and post_id != #{postId} @@ -13,8 +13,8 @@ limit 1 - + select post_id from sys_post where post_code = #{postCode} and post_id != #{postId} diff --git a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserPostMapper.xml b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserPostMapper.xml index 602dcf5..a8c17f4 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserPostMapper.xml +++ b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserPostMapper.xml @@ -7,4 +7,16 @@ + + + diff --git a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserRoleMapper.xml b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserRoleMapper.xml index 850a10a..fa1a7ec 100644 --- a/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserRoleMapper.xml +++ b/qiaoba-modules/qiaoba-module-system/src/main/resources/mapper/SysUserRoleMapper.xml @@ -5,7 +5,12 @@