diff --git a/pom.xml b/pom.xml index 0e9ce0b..35aa0c7 100644 --- a/pom.xml +++ b/pom.xml @@ -20,10 +20,12 @@ 0.2.0 5.2.5 3.14.0 + 1.12.0 2.5.0 5.1.3 4.4.0 3.5.6 + 2.1.0 @@ -53,6 +55,11 @@ mybatis-plus-spring-boot3-starter ${mybatis-plus.version} + + com.github.pagehelper + pagehelper-spring-boot-starter + ${page-helper.version} + com.mysql @@ -82,12 +89,17 @@ commons-lang3 ${commons-lang3.version} + + org.apache.commons + commons-text + ${commons-text.version} + - - - - - + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${open-api.version} + redis.clients @@ -155,6 +167,7 @@ ${lomstrcut-binding.version} + --enable-preview diff --git a/src/main/java/com/rainbus/dlp/config/MybatisMetaObjectHandler.java b/src/main/java/com/rainbus/dlp/config/MybatisMetaObjectHandler.java index 79ad839..e20ef1f 100644 --- a/src/main/java/com/rainbus/dlp/config/MybatisMetaObjectHandler.java +++ b/src/main/java/com/rainbus/dlp/config/MybatisMetaObjectHandler.java @@ -2,6 +2,7 @@ package com.rainbus.dlp.config; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.rainbus.dlp.entity.dto.user.CustomUserDetails; +import com.rainbus.dlp.util.AuthUtil; import org.apache.ibatis.reflection.MetaObject; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.context.SecurityContextHolder; @@ -10,6 +11,12 @@ import java.time.LocalDateTime; @Configuration public class MybatisMetaObjectHandler implements MetaObjectHandler { + private final AuthUtil authUtil; + + public MybatisMetaObjectHandler(AuthUtil authUtil) { + this.authUtil = authUtil; + } + @Override public void insertFill(MetaObject metaObject) { if (metaObject.hasSetter("createAt")) { @@ -40,7 +47,7 @@ public class MybatisMetaObjectHandler implements MetaObjectHandler { } private Long getCurrentUserId() { - CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getDetails(); + CustomUserDetails userDetails = authUtil.getUserDetails(); return userDetails.getId(); } diff --git a/src/main/java/com/rainbus/dlp/config/MybatisPlusConf.java b/src/main/java/com/rainbus/dlp/config/MybatisPlusConf.java new file mode 100644 index 0000000..400667a --- /dev/null +++ b/src/main/java/com/rainbus/dlp/config/MybatisPlusConf.java @@ -0,0 +1,19 @@ +package com.rainbus.dlp.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MybatisPlusConf { + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } + +} diff --git a/src/main/java/com/rainbus/dlp/config/OpenApiConf.java b/src/main/java/com/rainbus/dlp/config/OpenApiConf.java new file mode 100644 index 0000000..7686b68 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/config/OpenApiConf.java @@ -0,0 +1,20 @@ +package com.rainbus.dlp.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenApiConf { + + @Bean + public OpenAPI springOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("DLP Admin") + .description("DLP Admin APIs") + .version("0.0.1")); + } + +} diff --git a/src/main/java/com/rainbus/dlp/config/SecurityConf.java b/src/main/java/com/rainbus/dlp/config/SecurityConf.java index da70248..9e56cc2 100644 --- a/src/main/java/com/rainbus/dlp/config/SecurityConf.java +++ b/src/main/java/com/rainbus/dlp/config/SecurityConf.java @@ -1,7 +1,7 @@ package com.rainbus.dlp.config; -import com.rainbus.dlp.entity.pojo.user.SysRole; +import com.rainbus.dlp.repository.dao.UserDao; import com.rainbus.dlp.service.UserServ; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; @@ -19,14 +19,12 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import java.util.List; - @Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConf { - private final UserServ userServ; + private final UserDao userDao; @Bean public SecurityFilterChain filterChain(HttpSecurity http, JwtFilter jwtFilter) throws Exception { @@ -34,7 +32,7 @@ public class SecurityConf { .csrf(AbstractHttpConfigurer::disable) .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests((authorizeHttpRequests) -> { - userServ.listRoleResource().forEach(role -> { + userDao.listRoleResource().forEach(role -> { role.getResources().forEach(resource -> { authorizeHttpRequests.requestMatchers( HttpMethod.valueOf(resource.getRequestMethod().name()), diff --git a/src/main/java/com/rainbus/dlp/controller/UserCtrl.java b/src/main/java/com/rainbus/dlp/controller/UserCtrl.java index ddc9e98..2ae991d 100644 --- a/src/main/java/com/rainbus/dlp/controller/UserCtrl.java +++ b/src/main/java/com/rainbus/dlp/controller/UserCtrl.java @@ -1,66 +1,85 @@ package com.rainbus.dlp.controller; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.rainbus.dlp.entity.converter.UserConv; -import com.rainbus.dlp.entity.pojo.user.SysUser; -import com.rainbus.dlp.entity.req.user.RegisterReq; +import com.github.pagehelper.PageInfo; +import com.rainbus.dlp.entity.req.user.*; import com.rainbus.dlp.entity.resp.Resp; -import com.rainbus.dlp.repository.mapper.user.SysRoleMapper; -import com.rainbus.dlp.repository.mapper.user.SysUserMapper; -import com.rainbus.dlp.service.SystemServ; +import com.rainbus.dlp.entity.resp.user.GetTagResp; +import com.rainbus.dlp.entity.resp.user.GetUserResp; +import com.rainbus.dlp.entity.resp.user.LoginResp; +import com.rainbus.dlp.service.UserServ; import com.rainbus.dlp.util.RedisUtil; +import io.swagger.v3.oas.annotations.Operation; import lombok.AllArgsConstructor; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequestMapping("/user") @AllArgsConstructor public class UserCtrl { - private final UserConv userConv; - private final AuthenticationManager authenticationManager; - private final PasswordEncoder passwordEncoder; private final RedisUtil redisUtil; - private final SystemServ systemServ; - private final SysUserMapper sysUserMapper; - private final SysRoleMapper sysRoleMapper; - - @PostMapping("/addUser") - public Resp addUser(@RequestBody @Validated RegisterReq req) { -// userRepo.save(userConv.RegisterReq2Pojo(req, defaultPwd(req.getUsername()))); - return Resp.success(); - } + private final UserServ userServ; @PostMapping("/login") - public Resp login(@RequestBody RegisterReq req) { -// SysUser user = userRepo.findByUsername(req.getUsername()).orElse(null); -// Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword())); -// SecurityContextHolder.getContext().setAuthentication(authentication); -// if (user == null) { -// return Resp.fail("user not exist"); -// } -// if (!passwordEncoder.matches(req.getPassword(), user.getPassword())) { -// return Resp.fail("password error"); -// } -// return Resp.success(JwtUtil.generateToken(userConv.ClaimsPojo2Dto(user))); + @Operation(summary = "登录接口") + public Resp login(@RequestBody LoginReq req) { + return Resp.success(userServ.login(req)); + } + + @PostMapping("/list") + @Operation(summary = "搜索用户") + public Resp> listUser(@RequestBody ListUserReq req) { + return Resp.success(null); + } + + @PostMapping("/add") + @Operation(summary = "增加用户") + public Resp addUser(@RequestBody AddUserReq req) { return Resp.success(); } - @PostMapping("/test") - public Resp test() throws JsonProcessingException { - return Resp.success(redisUtil.get("user", SysUser.class)); + @PostMapping("/get/{id}") + @Operation(summary = "获取用户") + public Resp getUser(@PathVariable("id") Long id) { + return Resp.success(null); } - @GetMapping("/test2") - public Resp test2() { - return Resp.success(sysRoleMapper.selectAllRoleResource()); + @PostMapping("/update") + @Operation(summary = "更新用户") + public Resp updateUser(@RequestBody UpdateUserReq req) { + return Resp.success(); } - private String defaultPwd(String username) { - return passwordEncoder.encode("Dlp" + username); + @PostMapping("/delete/{id}") + @Operation(summary = "删除用户") + public Resp deleteUser(@PathVariable Long id) { + return Resp.success(); + } + + @PostMapping("/resetPwd/{id}") + @Operation(summary = "重置密码") + public Resp resetPwd(@PathVariable Long id) { + return Resp.success(); + } + + @PostMapping("/tag/add") + @Operation(summary = "增加用户标签") + private Resp addUserTag(@RequestBody AddUserTagReq req) { + return Resp.success(); + } + + @PostMapping("/tag/delete/{id}") + @Operation(summary = "删除用户标签") + private Resp deleteUserTag(@PathVariable Long id) { + return Resp.success(); + } + + @GetMapping("/tag/list") + @Operation(summary = "获取所有用户标签") + private Resp> listUserTag() { + return Resp.success(null); } } diff --git a/src/main/java/com/rainbus/dlp/entity/ApiDescription.java b/src/main/java/com/rainbus/dlp/entity/ApiDescription.java new file mode 100644 index 0000000..e4c477e --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/ApiDescription.java @@ -0,0 +1,11 @@ +package com.rainbus.dlp.entity; + + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface ApiDescription { + String value(); +} diff --git a/src/main/java/com/rainbus/dlp/entity/converter/SystemConv.java b/src/main/java/com/rainbus/dlp/entity/converter/SystemConv.java new file mode 100644 index 0000000..83bee63 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/converter/SystemConv.java @@ -0,0 +1,21 @@ +package com.rainbus.dlp.entity.converter; + +import com.rainbus.dlp.entity.dto.system.ApiInfo; +import com.rainbus.dlp.entity.pojo.user.SysResource; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import java.util.List; + +@Mapper(componentModel = "spring") +public interface SystemConv { + + @Mapping(target = "id", ignore = true) + @Mapping(target = "updatedAt", ignore = true) + @Mapping(target = "resource", source = "uri") + @Mapping(target = "createdAt", ignore = true) + SysResource ApiInfoDto2Pojo(ApiInfo apiInfo); + + List ApiInfosDto2Pojo(List apiInfos); + +} diff --git a/src/main/java/com/rainbus/dlp/entity/converter/UserConv.java b/src/main/java/com/rainbus/dlp/entity/converter/UserConv.java index 4a80e39..0225016 100644 --- a/src/main/java/com/rainbus/dlp/entity/converter/UserConv.java +++ b/src/main/java/com/rainbus/dlp/entity/converter/UserConv.java @@ -3,7 +3,7 @@ package com.rainbus.dlp.entity.converter; import com.rainbus.dlp.entity.dto.user.CustomUserDetails; import com.rainbus.dlp.entity.dto.user.TokenClaims; import com.rainbus.dlp.entity.pojo.user.SysUser; -import com.rainbus.dlp.entity.req.user.RegisterReq; +import com.rainbus.dlp.entity.req.user.AddUserReq; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; @@ -12,13 +12,15 @@ import org.mapstruct.Mapping; public interface UserConv { @InheritInverseConfiguration - SysUser RegisterReq2Pojo(RegisterReq req, String password); + SysUser RegisterReq2Pojo(AddUserReq req, String password); @Mapping(target = "roles", expression = "java(user.getRoles().stream().map(com.rainbus.dlp.entity.pojo.user.SysRole::getRole).toList())") + @Mapping(target = "orgId", expression = "java(user.getOrg().getId())") TokenClaims ClaimsPojo2Dto(SysUser user); + @Mapping(target = "orgId", expression = "java(user.getOrg().getId())") @Mapping(target = "authorities", ignore = true) @Mapping(target = "roles", expression = "java(user.getRoles().stream().map(com.rainbus.dlp.entity.pojo.user.SysRole::getRole).toList())") - CustomUserDetails UserPojo2UserDetails(SysUser user); + CustomUserDetails UserDetailsPojo2Dto(SysUser user); } diff --git a/src/main/java/com/rainbus/dlp/entity/dto/Tuple.java b/src/main/java/com/rainbus/dlp/entity/dto/Tuple.java new file mode 100644 index 0000000..3f82aa9 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/dto/Tuple.java @@ -0,0 +1,4 @@ +package com.rainbus.dlp.entity.dto; + +public record Tuple(T1 t1, T2 t2, T3 t3) { +} diff --git a/src/main/java/com/rainbus/dlp/entity/dto/system/ApiInfo.java b/src/main/java/com/rainbus/dlp/entity/dto/system/ApiInfo.java new file mode 100644 index 0000000..dfe4f12 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/dto/system/ApiInfo.java @@ -0,0 +1,7 @@ +package com.rainbus.dlp.entity.dto.system; + +import org.springframework.web.bind.annotation.RequestMethod; + +public record ApiInfo(String uri, RequestMethod requestMethod, String description) { + +} diff --git a/src/main/java/com/rainbus/dlp/entity/dto/user/CustomUserDetails.java b/src/main/java/com/rainbus/dlp/entity/dto/user/CustomUserDetails.java index b70b8b9..dba8bfc 100644 --- a/src/main/java/com/rainbus/dlp/entity/dto/user/CustomUserDetails.java +++ b/src/main/java/com/rainbus/dlp/entity/dto/user/CustomUserDetails.java @@ -24,6 +24,7 @@ public class CustomUserDetails implements UserDetails { private String username; private String password; private List roles; + private Long orgId; @Override @JsonIgnore diff --git a/src/main/java/com/rainbus/dlp/entity/dto/user/TokenClaims.java b/src/main/java/com/rainbus/dlp/entity/dto/user/TokenClaims.java index 6ec599b..f9828ba 100644 --- a/src/main/java/com/rainbus/dlp/entity/dto/user/TokenClaims.java +++ b/src/main/java/com/rainbus/dlp/entity/dto/user/TokenClaims.java @@ -1,6 +1,7 @@ package com.rainbus.dlp.entity.dto.user; import com.auth0.jwt.interfaces.Claim; +import com.rainbus.dlp.entity.pojo.user.SysOrg; import com.rainbus.dlp.util.ConvertUtil; import lombok.Data; @@ -10,9 +11,11 @@ import java.util.Map; @Data public class TokenClaims { + private Long id; private String username; private List roles; + private Long orgId; public Map toMap() { return ConvertUtil.toMap(this, Object.class); diff --git a/src/main/java/com/rainbus/dlp/entity/exception/OrgNotExistExcp.java b/src/main/java/com/rainbus/dlp/entity/exception/OrgNotExistExcp.java new file mode 100644 index 0000000..af279b3 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/exception/OrgNotExistExcp.java @@ -0,0 +1,14 @@ +package com.rainbus.dlp.entity.exception; + +import lombok.Getter; + +@Getter +public class OrgNotExistExcp extends RuntimeException { + private final int code; + private final String message; + + public OrgNotExistExcp() { + this.code = 40003; + this.message = "组织不存在"; + } +} diff --git a/src/main/java/com/rainbus/dlp/entity/pojo/user/SysResource.java b/src/main/java/com/rainbus/dlp/entity/pojo/user/SysResource.java index e3d6df0..378af1a 100644 --- a/src/main/java/com/rainbus/dlp/entity/pojo/user/SysResource.java +++ b/src/main/java/com/rainbus/dlp/entity/pojo/user/SysResource.java @@ -17,10 +17,6 @@ public class SysResource { private String description; - private Long createdBy; - - private Long updatedBy; - private LocalDateTime createdAt; private LocalDateTime updatedAt; diff --git a/src/main/java/com/rainbus/dlp/entity/pojo/user/SysUser.java b/src/main/java/com/rainbus/dlp/entity/pojo/user/SysUser.java index 9d2fa36..8fafd1d 100644 --- a/src/main/java/com/rainbus/dlp/entity/pojo/user/SysUser.java +++ b/src/main/java/com/rainbus/dlp/entity/pojo/user/SysUser.java @@ -2,10 +2,13 @@ package com.rainbus.dlp.entity.pojo.user; import com.baomidou.mybatisplus.annotation.TableLogic; import com.rainbus.dlp.entity.enums.UserStatusEnum; +import com.rainbus.dlp.entity.exception.UserDisabledExcp; +import com.rainbus.dlp.entity.exception.UsernameOrPasswordExcp; import lombok.Data; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @Data public class SysUser { diff --git a/src/main/java/com/rainbus/dlp/entity/req/PageReq.java b/src/main/java/com/rainbus/dlp/entity/req/PageReq.java new file mode 100644 index 0000000..4b45acc --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/req/PageReq.java @@ -0,0 +1,9 @@ +package com.rainbus.dlp.entity.req; + +import lombok.Data; + +@Data +public class PageReq { + private Integer pageCurrent = 1; + private Integer pageSize = 10; +} diff --git a/src/main/java/com/rainbus/dlp/entity/req/user/AddUserReq.java b/src/main/java/com/rainbus/dlp/entity/req/user/AddUserReq.java new file mode 100644 index 0000000..ec86c87 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/req/user/AddUserReq.java @@ -0,0 +1,38 @@ +package com.rainbus.dlp.entity.req.user; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import lombok.Data; +import lombok.NonNull; + +@Data +public class AddUserReq { + + @Pattern(regexp = "^[a-zA-Z0-9_-]{4,16}$", message = "用户名格式不正确") + private String username; + + @Pattern(regexp = "^[\\u4E00-\\u9FA5]{2,4}$", message = "姓名格式不正确") + private String realName; + + @Email(message = "邮箱格式不正确") + private String email; + + @NotNull + private Long orgId; + + @NotNull + private String region; + + @Pattern(regexp = "^1(3\\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\\d|9[0-35-9])\\d{8}$", message = "手机号格式不正确") + private String mobile; + + @Pattern(regexp = "0\\d{2,3}-\\d{7,8}$", message = "座机号格式不正确") + private String phone; + + private String remark; + + private Long tagId; + + +} diff --git a/src/main/java/com/rainbus/dlp/entity/req/user/AddUserTagReq.java b/src/main/java/com/rainbus/dlp/entity/req/user/AddUserTagReq.java new file mode 100644 index 0000000..b4a977b --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/req/user/AddUserTagReq.java @@ -0,0 +1,9 @@ +package com.rainbus.dlp.entity.req.user; + +import lombok.Data; + +@Data +public class AddUserTagReq { + private String tag; + private String remark; +} diff --git a/src/main/java/com/rainbus/dlp/entity/req/user/ListUserReq.java b/src/main/java/com/rainbus/dlp/entity/req/user/ListUserReq.java new file mode 100644 index 0000000..d4dcaf0 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/req/user/ListUserReq.java @@ -0,0 +1,15 @@ +package com.rainbus.dlp.entity.req.user; + +import com.rainbus.dlp.entity.req.PageReq; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Data +@EqualsAndHashCode(callSuper = true) +public class ListUserReq extends PageReq { + private String username; + private String email; + private String region; + private Long orgId; +} diff --git a/src/main/java/com/rainbus/dlp/entity/req/user/RegisterReq.java b/src/main/java/com/rainbus/dlp/entity/req/user/LoginReq.java similarity index 62% rename from src/main/java/com/rainbus/dlp/entity/req/user/RegisterReq.java rename to src/main/java/com/rainbus/dlp/entity/req/user/LoginReq.java index a709a30..226b11a 100644 --- a/src/main/java/com/rainbus/dlp/entity/req/user/RegisterReq.java +++ b/src/main/java/com/rainbus/dlp/entity/req/user/LoginReq.java @@ -1,16 +1,15 @@ package com.rainbus.dlp.entity.req.user; -import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Pattern; import lombok.Data; @Data -public class RegisterReq { +public class LoginReq { @Pattern(regexp = "^[a-zA-Z0-9_-]{4,16}$", message = "用户名格式不正确") private String username; - @Email(message = "邮箱格式不正确") - private String email; + @Pattern(regexp = "^[a-zA-Z0-9_-]{8,16}$", message = "密码格式不正确") + private String password; } diff --git a/src/main/java/com/rainbus/dlp/entity/req/user/UpdateUserReq.java b/src/main/java/com/rainbus/dlp/entity/req/user/UpdateUserReq.java new file mode 100644 index 0000000..50645b2 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/req/user/UpdateUserReq.java @@ -0,0 +1,37 @@ +package com.rainbus.dlp.entity.req.user; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import lombok.Data; + +@Data +public class UpdateUserReq { + + @NotNull + private Long id; + + @Pattern(regexp = "^[a-zA-Z0-9_-]{4,16}$", message = "用户名格式不正确") + private String username; + + @Pattern(regexp = "^[\\u4E00-\\u9FA5]{2,4}$", message = "姓名格式不正确") + private String realName; + + @Email(message = "邮箱格式不正确") + private String email; + + @NotNull + private Long orgId; + + @NotNull + private String region; + + @Pattern(regexp = "^1(3\\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\\d|9[0-35-9])\\d{8}$", message = "手机号格式不正确") + private String mobile; + + @Pattern(regexp = "0\\d{2,3}-\\d{7,8}$", message = "座机号格式不正确") + private String phone; + + private String remark; + +} diff --git a/src/main/java/com/rainbus/dlp/entity/resp/PageResp.java b/src/main/java/com/rainbus/dlp/entity/resp/PageResp.java new file mode 100644 index 0000000..aa16193 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/resp/PageResp.java @@ -0,0 +1,13 @@ +package com.rainbus.dlp.entity.resp; + +import lombok.Data; + +import java.util.List; + +@Data +public class PageResp { + private List list; + private Long total; + private Long pageSize; + private Long current; +} diff --git a/src/main/java/com/rainbus/dlp/entity/resp/user/GetTagResp.java b/src/main/java/com/rainbus/dlp/entity/resp/user/GetTagResp.java new file mode 100644 index 0000000..a669786 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/resp/user/GetTagResp.java @@ -0,0 +1,10 @@ +package com.rainbus.dlp.entity.resp.user; + +import lombok.Data; + +@Data +public class GetTagResp { + private Long id; + private String tag; + private String remark; +} diff --git a/src/main/java/com/rainbus/dlp/entity/resp/user/GetUserResp.java b/src/main/java/com/rainbus/dlp/entity/resp/user/GetUserResp.java new file mode 100644 index 0000000..9fcc88a --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/resp/user/GetUserResp.java @@ -0,0 +1,39 @@ +package com.rainbus.dlp.entity.resp.user; + +import com.rainbus.dlp.entity.enums.UserStatusEnum; +import com.rainbus.dlp.entity.pojo.user.SysOrg; +import com.rainbus.dlp.entity.pojo.user.SysRole; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class GetUserResp { + + private Long id; + + private String username; + + private String email; + + private List roles; + + private SysOrg org; + + @Schema(description = "未定字段格式") + private List tags; + + private UserStatusEnum status; + + private Long createBy; + + private Long updateBy; + + private LocalDateTime createAt; + + private LocalDateTime updateAt; + +} diff --git a/src/main/java/com/rainbus/dlp/entity/resp/user/LoginResp.java b/src/main/java/com/rainbus/dlp/entity/resp/user/LoginResp.java new file mode 100644 index 0000000..d5e2033 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/entity/resp/user/LoginResp.java @@ -0,0 +1,8 @@ +package com.rainbus.dlp.entity.resp.user; + +import lombok.Data; + +@Data +public class LoginResp { + private String token; +} diff --git a/src/main/java/com/rainbus/dlp/repository/dao/SystemDao.java b/src/main/java/com/rainbus/dlp/repository/dao/SystemDao.java new file mode 100644 index 0000000..7d8300b --- /dev/null +++ b/src/main/java/com/rainbus/dlp/repository/dao/SystemDao.java @@ -0,0 +1,27 @@ +package com.rainbus.dlp.repository.dao; + +import com.baomidou.mybatisplus.core.batch.MybatisBatch; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.rainbus.dlp.entity.pojo.user.SysResource; +import com.rainbus.dlp.repository.mapper.user.SysResourceMapper; +import com.rainbus.dlp.repository.mapper.user.SysUserMapper; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class SystemDao { + + private final SysResourceMapper resourceMapper; + private final SqlSessionFactory sqlSessionFactory; + private final SysUserMapper sysUserMapper; + + public SystemDao(SysResourceMapper sysResourceMapper, SqlSessionFactory sqlSessionFactory, SysUserMapper sysUserMapper) { + this.resourceMapper = sysResourceMapper; + this.sqlSessionFactory = sqlSessionFactory; + this.sysUserMapper = sysUserMapper; + } + +} diff --git a/src/main/java/com/rainbus/dlp/repository/dao/UserDao.java b/src/main/java/com/rainbus/dlp/repository/dao/UserDao.java index eecc48e..0e37b91 100644 --- a/src/main/java/com/rainbus/dlp/repository/dao/UserDao.java +++ b/src/main/java/com/rainbus/dlp/repository/dao/UserDao.java @@ -1,22 +1,27 @@ package com.rainbus.dlp.repository.dao; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.rainbus.dlp.entity.pojo.user.SysOrg; import com.rainbus.dlp.entity.pojo.user.SysRole; import com.rainbus.dlp.entity.pojo.user.SysUser; +import com.rainbus.dlp.repository.mapper.user.SysOrgMapper; import com.rainbus.dlp.repository.mapper.user.SysRoleMapper; import com.rainbus.dlp.repository.mapper.user.SysUserMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.List; +import java.util.Objects; import java.util.Optional; + @Component @RequiredArgsConstructor public class UserDao { private final SysUserMapper userMapper; private final SysRoleMapper roleMapper; + private final SysOrgMapper orgMapper; public Optional findUserByUsername(String username) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper() @@ -33,4 +38,24 @@ public class UserDao { } + public Optional findOrgById(Long orgId) { + return Optional.ofNullable(orgMapper.selectById(orgId)); + } + + public List listOrgWithSubOrg(Long orgId) { + SysOrg org = orgMapper.selectById(orgId); + if (Objects.isNull(org)) { + return List.of(); + } + LambdaQueryWrapper subQueryWrapper = new LambdaQueryWrapper() + .like(SysOrg::getFullPath, org.getFullPath() + "%"); + return orgMapper.selectList(subQueryWrapper); + } + + public List listUserByOrgIds(List orgIds) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper() + .in(SysUser::getOrg, orgIds); + return userMapper.selectList(lqw); + } + } diff --git a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysResourceMapper.java b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysResourceMapper.java index b088a46..231c015 100644 --- a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysResourceMapper.java +++ b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysResourceMapper.java @@ -3,6 +3,9 @@ package com.rainbus.dlp.repository.mapper.user; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.rainbus.dlp.entity.pojo.user.SysResource; +import com.rainbus.dlp.util.SqlUtil; +import com.rainbus.dlp.util.TextUtil; +import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.mapstruct.Mapping; @@ -11,11 +14,19 @@ import java.util.List; public interface SysResourceMapper extends BaseMapper { @Select(""" - select * from sys_resource sr - left join sys_role_resources srr - on sr.id = srr.resources_id - where srr.sys_role_id = #{roleId} - """) + select * from sys_resource sr + left join sys_role_resources srr + on sr.id = srr.resources_id + where srr.sys_role_id = #{roleId} + """) List selectListByRoleId(Long roleId); + @Insert(""" + insert into sys_resource (request_method, resource, created_at, description, updated_at) values + + (#{item.requestMethod}, #{item.resource}, #{item.createdAt}, #{item.description}, #{item.updatedAt}) + + """) + Long batchInsert(List resources); + } diff --git a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysRoleMapper.java b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysRoleMapper.java index 7994ae4..03d2435 100644 --- a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysRoleMapper.java +++ b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysRoleMapper.java @@ -10,16 +10,16 @@ import java.util.List; public interface SysRoleMapper extends BaseMapper { @Select(""" - select * from sys_role sr - left join sys_user_roles sur - on sr.id = sur.roles_id - where sur.sys_user_id = #{userId} - """) + select * from sys_role sr + left join sys_user_roles sur + on sr.id = sur.roles_id + where sur.sys_user_id = #{userId} + """) List selectListByUserId(Long userId); @Select(""" - select * from sys_role where id = 4 - """) + select * from sys_role where id = 4 + """) @Results( @Result( property = "resources", diff --git a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysUserMapper.java b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysUserMapper.java index a700cc9..da027c4 100644 --- a/src/main/java/com/rainbus/dlp/repository/mapper/user/SysUserMapper.java +++ b/src/main/java/com/rainbus/dlp/repository/mapper/user/SysUserMapper.java @@ -4,10 +4,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.rainbus.dlp.entity.pojo.user.SysUser; import org.apache.ibatis.annotations.*; +import java.util.List; + public interface SysUserMapper extends BaseMapper { @Select(""" - select * from sys_user where username = #{username} - """) + select * from sys_user where username = #{username} + """) @Results({ @Result(column = "id", property = "id"), @Result( @@ -26,4 +28,10 @@ public interface SysUserMapper extends BaseMapper { ) }) SysUser selectUserRoleOrgByUsername(@Param("username") String username); + + @Select(""" + select roles_id from sys_user_roles where sys_user_id = #{userId} + """) + List selectRoleIdsByUserId(Long userId); + } diff --git a/src/main/java/com/rainbus/dlp/service/SystemServ.java b/src/main/java/com/rainbus/dlp/service/SystemServ.java index 0e257b8..5a6e1c4 100644 --- a/src/main/java/com/rainbus/dlp/service/SystemServ.java +++ b/src/main/java/com/rainbus/dlp/service/SystemServ.java @@ -1,5 +1,10 @@ package com.rainbus.dlp.service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.rainbus.dlp.entity.ApiDescription; +import com.rainbus.dlp.entity.converter.SystemConv; +import com.rainbus.dlp.entity.dto.system.ApiInfo; +import com.rainbus.dlp.entity.pojo.user.SysResource; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; @@ -17,31 +22,35 @@ import java.util.stream.Collectors; public class SystemServ { private final ApplicationContext applicationContext; - - public record ApiInfo(String url, RequestMethod method) { - } + private final SystemConv systemConv; public List getSystemApis() { - List apiInfos = new ArrayList<>(); RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class); Map methodMap = mapping.getHandlerMethods(); - for (RequestMappingInfo info : methodMap.keySet()) { + + List apiInfos = new LinkedList<>(); + methodMap.forEach((info, func) -> { if (Objects.isNull(info.getPathPatternsCondition())) { - continue; + return; } Set patterns = info.getPathPatternsCondition().getPatterns(); Set methods = info.getMethodsCondition().getMethods(); + Optional desc = Optional.ofNullable(func.getMethod().getAnnotation(ApiDescription.class)); for (PathPattern url : patterns) { for (RequestMethod method : methods) { - apiInfos.add(new ApiInfo(url.getPatternString(), method)); + apiInfos.add(new ApiInfo(url.getPatternString(), method, desc.map(ApiDescription::value).orElse(null))); } } - } + }); return apiInfos; } + public void initResources() { + List resources = systemConv.ApiInfosDto2Pojo(getSystemApis()); + } + } diff --git a/src/main/java/com/rainbus/dlp/service/UserServ.java b/src/main/java/com/rainbus/dlp/service/UserServ.java index 29d17d2..cae2d5c 100644 --- a/src/main/java/com/rainbus/dlp/service/UserServ.java +++ b/src/main/java/com/rainbus/dlp/service/UserServ.java @@ -2,19 +2,27 @@ package com.rainbus.dlp.service; import com.rainbus.dlp.entity.converter.UserConv; import com.rainbus.dlp.entity.dto.user.CustomUserDetails; +import com.rainbus.dlp.entity.dto.user.TokenClaims; import com.rainbus.dlp.entity.enums.UserStatusEnum; +import com.rainbus.dlp.entity.exception.OrgNotExistExcp; import com.rainbus.dlp.entity.exception.UserDisabledExcp; +import com.rainbus.dlp.entity.exception.UsernameOrPasswordExcp; +import com.rainbus.dlp.entity.pojo.user.SysOrg; import com.rainbus.dlp.entity.pojo.user.SysRole; import com.rainbus.dlp.entity.pojo.user.SysUser; +import com.rainbus.dlp.entity.req.user.LoginReq; +import com.rainbus.dlp.entity.resp.user.LoginResp; import com.rainbus.dlp.repository.dao.UserDao; +import com.rainbus.dlp.util.AuthUtil; +import com.rainbus.dlp.util.JwtUtil; import com.rainbus.dlp.util.RedisUtil; import lombok.AllArgsConstructor; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; -import javax.management.relation.Role; import java.util.List; import java.util.Optional; @@ -29,22 +37,32 @@ public class UserServ implements UserDetailsService { public static final String REDIS_USER_DETAILS = "user_details_%s"; public static final long REDIS_USER_DETAILS_EXPIRE = 1 * 60 * 60; private final RedisUtil redisUtil; + private final PasswordEncoder passwordEncoder; + private final AuthUtil authUtil; public SysUser getUserByUsername(String username) { Optional user = userDao.findUserByUsername(username); if (user.isEmpty()) { - throw new UsernameNotFoundException("用户不存在"); + throw new UsernameNotFoundException("用户不存在"); } return user.get(); } - public List listRoleResource() { - return userDao.listRoleResource(); + public LoginResp login(LoginReq req) { + Optional userOpt = userDao.findUserRoleOrgByUsername(req.getUsername()); + SysUser user = validUserAvailable(userOpt); + validPassword(req.getPassword(), user.getPassword()); + TokenClaims claims = userConv.ClaimsPojo2Dto(user); + LoginResp resp = new LoginResp(); + resp.setToken(JwtUtil.generateToken(claims)); + return resp; } -// public List getAllRoles() { -// return roleRepo.findAll(); -// } + public Object listUser() { + Long orgId = authUtil.getUserDetails().getOrgId(); + List subOrgIds = userDao.listOrgWithSubOrg(orgId).stream().map(SysOrg::getId).toList(); + return userDao.listUserByOrgIds(subOrgIds); + } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { @@ -55,18 +73,12 @@ public class UserServ implements UserDetailsService { } // 读数据库 - Optional user = userDao.findUserRoleOrgByUsername(username); - if (user.isEmpty()) { - throw new UsernameNotFoundException("用户不存在"); - } - if (user.get().getStatus() == UserStatusEnum.DISABLED) { - throw new UserDisabledExcp(); - } - CustomUserDetails userDetails = userConv.UserPojo2UserDetails(user.get()); + Optional userOpt = userDao.findUserRoleOrgByUsername(username); + SysUser user = validUserAvailable(userOpt); + CustomUserDetails userDetails = userConv.UserDetailsPojo2Dto(user); // 写缓存 redisUtil.setex(RedisUtil.parseKey(REDIS_USER_DETAILS, username), userDetails, REDIS_USER_DETAILS_EXPIRE); - return userDetails; } @@ -74,4 +86,26 @@ public class UserServ implements UserDetailsService { return redisUtil.get(RedisUtil.parseKey(REDIS_USER_DETAILS, username), CustomUserDetails.class); } + private void validPassword(String rawPassword, String encodedPassword) { + if (!passwordEncoder.matches(rawPassword, encodedPassword)) { + throw new UsernameOrPasswordExcp(); + } + } + + private SysUser validUserAvailable(Optional userOpt) { + if (userOpt.isEmpty()) { + throw new UsernameOrPasswordExcp(); + } + if (userOpt.get().getStatus() == UserStatusEnum.DISABLED) { + throw new UserDisabledExcp(); + } + return userOpt.get(); + } + + private SysOrg validOrgAvailable(Optional orgOpt) { + if (orgOpt.isEmpty()) { + throw new OrgNotExistExcp(); + } + return orgOpt.get(); + } } diff --git a/src/main/java/com/rainbus/dlp/util/AuthUtil.java b/src/main/java/com/rainbus/dlp/util/AuthUtil.java new file mode 100644 index 0000000..53de53f --- /dev/null +++ b/src/main/java/com/rainbus/dlp/util/AuthUtil.java @@ -0,0 +1,14 @@ +package com.rainbus.dlp.util; + +import com.rainbus.dlp.entity.dto.user.CustomUserDetails; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +@Component +public class AuthUtil { + public CustomUserDetails getUserDetails() { + return (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getDetails(); + } +} diff --git a/src/main/java/com/rainbus/dlp/util/SqlUtil.java b/src/main/java/com/rainbus/dlp/util/SqlUtil.java new file mode 100644 index 0000000..b8e6160 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/util/SqlUtil.java @@ -0,0 +1,28 @@ +package com.rainbus.dlp.util; + +import java.util.Arrays; +import java.util.List; + +public class SqlUtil { + + record TableInfo(String tableName, List columName) {} + +// public static String generateBatchInsertSql(String fieldName, Class tClass) { +// TableInfo tableInfo = getTableInfo(tClass); +// return STR.""" +// INSERT INTO \{tableInfo.tableName} (\{String.join(", ", tableInfo.columName)}) +// VALUES +// +// (\{String.join(", ", tableInfo.columName.stream().map(colum -> STR."#{item.\{colum}}").toList())}) +// +// """; +// } +// +// private static TableInfo getTableInfo(Class tClass) { +// String tableName = TextUtil.camelToSnake(tClass.getSimpleName()); +// List columName = Arrays.stream(tClass.getDeclaredFields()) +// .map(field -> TextUtil.camelToSnake(field.getName())) +// .toList(); +// return new TableInfo(tableName, columName); +// } +} diff --git a/src/main/java/com/rainbus/dlp/util/TextUtil.java b/src/main/java/com/rainbus/dlp/util/TextUtil.java new file mode 100644 index 0000000..88046b4 --- /dev/null +++ b/src/main/java/com/rainbus/dlp/util/TextUtil.java @@ -0,0 +1,25 @@ +package com.rainbus.dlp.util; + +import org.apache.commons.lang3.StringUtils; + +import java.nio.charset.StandardCharsets; + +public class TextUtil { + public static String camelToSnake(String camel) { + if (StringUtils.isBlank(camel)) { + return camel; + } + camel = Character.toLowerCase(camel.charAt(0)) + camel.substring(1); + + StringBuilder result = new StringBuilder(); + for (Character c: camel.toCharArray()) { + if (Character.isUpperCase(c)) { + result.append("_"); + result.append(Character.toLowerCase(c)); + } else { + result.append(c); + } + } + return result.toString(); + } +}