diff --git a/common/src/main/java/com/canvas/web/annotation/rest/AnonymousPutMapping.java b/common/src/main/java/com/canvas/web/annotation/rest/AnonymousPutMapping.java new file mode 100644 index 0000000..7df17a9 --- /dev/null +++ b/common/src/main/java/com/canvas/web/annotation/rest/AnonymousPutMapping.java @@ -0,0 +1,59 @@ +package com.canvas.web.annotation.rest; + + +import com.canvas.web.annotation.AnonymousAccess; +import org.springframework.core.annotation.AliasFor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import java.lang.annotation.*; + +@AnonymousAccess +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RequestMapping(method = RequestMethod.PUT) +public @interface AnonymousPutMapping { + + /** + * Alias for {@link RequestMapping#name}. + */ + @AliasFor(annotation = RequestMapping.class) + String name() default ""; + + /** + * Alias for {@link RequestMapping#value}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] value() default {}; + + /** + * Alias for {@link RequestMapping#path}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] path() default {}; + + /** + * Alias for {@link RequestMapping#params}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] params() default {}; + + /** + * Alias for {@link RequestMapping#headers}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] headers() default {}; + + /** + * Alias for {@link RequestMapping#consumes}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] consumes() default {}; + + /** + * Alias for {@link RequestMapping#produces}. + */ + @AliasFor(annotation = RequestMapping.class) + String[] produces() default {}; +} diff --git a/common/src/main/java/com/canvas/web/utils/RedisUtils.java b/common/src/main/java/com/canvas/web/utils/RedisUtils.java index 2570217..521c672 100644 --- a/common/src/main/java/com/canvas/web/utils/RedisUtils.java +++ b/common/src/main/java/com/canvas/web/utils/RedisUtils.java @@ -12,9 +12,7 @@ import org.springframework.data.redis.core.RedisConnectionUtils; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; + import java.util.*; import java.util.concurrent.TimeUnit; diff --git a/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCode.java b/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCode.java new file mode 100644 index 0000000..0b154ac --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCode.java @@ -0,0 +1,59 @@ +package com.canvas.web.modules.security.config.bean; + + +import lombok.AllArgsConstructor; +import lombok.Data; + +//短信配置类 + + +public class MessageCode { + + //短信验证码到期时间 + private static Long expiration = 5L; + + //短信模板编号 + private static String project = "hhzXr"; + + //短信验证码模板代码 + private static String key = "code"; + + //短信验证码模板值 + private static String val; + + //生成多少位验证码 + private static final Integer count = 4; + + + public static String getVal() { + return val; + } + + public static void setVal(String val) { + MessageCode.val = val; + } + + public static Long getExpiration() { + return expiration; + } + + public static void setExpiration(Long expiration) { + MessageCode.expiration = expiration; + } + + public static String getProject() { + return project; + } + + public static void setProject(String project) { + MessageCode.project = project; + } + + public static String getKey() { + return key; + } + + public static void setKey(String key) { + MessageCode.key = key; + } +} diff --git a/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCodeProperties.java b/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCodeProperties.java new file mode 100644 index 0000000..b4cb836 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/security/config/bean/MessageCodeProperties.java @@ -0,0 +1,9 @@ +package com.canvas.web.modules.security.config.bean; + +public class MessageCodeProperties { + + //随机生成验证码 + public static String generatedCode(int count){ + return String.valueOf((int)((Math.random()*9+1)*Math.pow(10,count-1))); + } +} diff --git a/system/src/main/java/com/canvas/web/modules/security/controller/AuthorizationController.java b/system/src/main/java/com/canvas/web/modules/security/controller/AuthorizationController.java index 302cca6..0c91808 100644 --- a/system/src/main/java/com/canvas/web/modules/security/controller/AuthorizationController.java +++ b/system/src/main/java/com/canvas/web/modules/security/controller/AuthorizationController.java @@ -7,14 +7,16 @@ import com.canvas.web.annotation.rest.AnonymousPostMapping; import com.canvas.web.config.RsaProperties; import com.canvas.web.config.SubMailMsgConfig; import com.canvas.web.exception.BaseException; -import com.canvas.web.modules.security.config.bean.LoginCodeEnum; -import com.canvas.web.modules.security.config.bean.LoginProperties; -import com.canvas.web.modules.security.config.bean.SecurityProperties; +import com.canvas.web.modules.security.config.bean.*; import com.canvas.web.modules.security.msglib.MESSAGEXsend; import com.canvas.web.modules.security.security.TokenProvider; import com.canvas.web.modules.security.service.OnlineUserService; import com.canvas.web.modules.security.service.dto.AuthUserDto; import com.canvas.web.modules.security.service.dto.JwtUserDto; +import com.canvas.web.modules.security.service.dto.MsgDto; +import com.canvas.web.modules.system.domain.vo.UserPassVo; +import com.canvas.web.modules.system.service.UserService; +import com.canvas.web.modules.system.service.dto.UserDto; import com.canvas.web.utils.*; import com.wf.captcha.base.Captcha; import io.swagger.annotations.Api; @@ -27,6 +29,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -50,10 +53,13 @@ public class AuthorizationController { private final OnlineUserService onlineUserService; private final TokenProvider tokenProvider; private final AuthenticationManagerBuilder authenticationManagerBuilder; + private final UserService userService; + private final PasswordEncoder passwordEncoder; @Resource private LoginProperties loginProperties; + @ApiOperation("登录授权") @AnonymousPostMapping(value = "/login") public ResponseEntity login(@Validated @RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { @@ -124,16 +130,47 @@ public class AuthorizationController { } @ApiOperation("短信验证码") - @AnonymousGetMapping(value = "/msg") - public ResponseEntity sendXMsg(){ - SubMailMsgConfig config= ConfigLoader.load(ConfigLoader.ConfigType.Message); + @AnonymousPostMapping(value = "/msg") + public ResponseEntity sendXMsg(@Validated MsgDto msgDto) { + //加载短信配置文件 + SubMailMsgConfig config = ConfigLoader.load(ConfigLoader.ConfigType.Message); + //创建发送短信对象 MESSAGEXsend submail = new MESSAGEXsend(config); - submail.addTo("15902734788"); - submail.setProject("hhzXr"); - submail.addVar("code", "2346"); - submail.addVar("minue", "2289"); - String response=submail.xsend(); - System.out.println("接口返回数据:"+response); - return ResponseEntity.ok(response); + //获取短信随机四位数 + MessageCode.setVal(MessageCodeProperties.generatedCode(4)); + submail.addTo(msgDto.getPhone()); + submail.setProject(MessageCode.getProject()); + submail.addVar(MessageCode.getKey(), MessageCode.getVal()); + String uuid = properties.getCodeKey() + IdUtil.simpleUUID(); + redisUtils.set(uuid, MessageCode.getVal(), MessageCode.getExpiration(), TimeUnit.MINUTES); + Map msgResult = new HashMap(2) {{ + put("code", MessageCode.getVal()); + put("uuid", uuid); + }}; + String response = submail.xsend(); + return ResponseEntity.ok(msgResult); + } + + @ApiOperation("客户端修改密码") + @AnonymousPostMapping(value = "/password") + public ResponseEntity clientLogin(@Validated @RequestBody UserPassVo userPassVo) throws Exception { + // 查询验证码 + String code = (String) redisUtils.get(userPassVo.getUuid()); + String newPass=RsaUtils.decryptByPrivateKey(RsaProperties.privateKey,userPassVo.getNewPass()); + // 清除验证码 + redisUtils.del(userPassVo.getUuid()); + if (StringUtils.isBlank(code)) { + throw new BaseException("验证码不存在或已过期"); + } + if (StringUtils.isBlank(userPassVo.getCode()) || !userPassVo.getCode().equalsIgnoreCase(code)) { + throw new BaseException("验证码错误"); + } + UserDto userDto=userService.findByName(SecurityUtils.getCurrentUsername()); + + userService.updatePass(userDto.getUsername(),passwordEncoder.encode(newPass)); + + return new ResponseEntity<>(HttpStatus.OK); } + + } diff --git a/system/src/main/java/com/canvas/web/modules/security/service/dto/MsgDto.java b/system/src/main/java/com/canvas/web/modules/security/service/dto/MsgDto.java new file mode 100644 index 0000000..e0b0bd7 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/security/service/dto/MsgDto.java @@ -0,0 +1,18 @@ +package com.canvas.web.modules.security.service.dto; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MsgDto { + + @NotBlank(message = "手机号不能为空") + private String phone; + +} diff --git a/system/src/main/java/com/canvas/web/modules/system/controller/UserController.java b/system/src/main/java/com/canvas/web/modules/system/controller/UserController.java new file mode 100644 index 0000000..56962ce --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/system/controller/UserController.java @@ -0,0 +1,35 @@ +package com.canvas.web.modules.system.controller; + + +import com.canvas.web.modules.system.service.RoleService; +import com.canvas.web.modules.system.service.UserService; +import com.canvas.web.modules.system.service.dto.UserDto; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Api(tags = "用户管理") +@RestController +@RequestMapping("api/users/") +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + private final RoleService roleService; + +// @ApiOperation("新增用户") +// @PostMapping +// public ResponseEntity create(@Validated @RequestBody UserDto userDto){ +// +// } +// +// private void checkLevel(UserDto userDto){ +// Integer currentLevel= +// } +} diff --git a/system/src/main/java/com/canvas/web/modules/system/domain/vo/UserPassVo.java b/system/src/main/java/com/canvas/web/modules/system/domain/vo/UserPassVo.java new file mode 100644 index 0000000..9ed2782 --- /dev/null +++ b/system/src/main/java/com/canvas/web/modules/system/domain/vo/UserPassVo.java @@ -0,0 +1,24 @@ +package com.canvas.web.modules.system.domain.vo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class UserPassVo { + + @NotBlank(message = "手机号不能为空") + private String phone; + + @JsonProperty("new_pass") + @JSONField(name = "new_pass") + @NotBlank(message = "密码不能为空") + private String newPass; + + @NotBlank(message = "验证码不能为空") + private String code; + + private String uuid; +} diff --git a/system/src/main/java/com/canvas/web/modules/system/repository/UserRepository.java b/system/src/main/java/com/canvas/web/modules/system/repository/UserRepository.java index 6d32134..01cbd35 100644 --- a/system/src/main/java/com/canvas/web/modules/system/repository/UserRepository.java +++ b/system/src/main/java/com/canvas/web/modules/system/repository/UserRepository.java @@ -26,8 +26,9 @@ public interface UserRepository extends JpaRepository, JpaSpecificat */ User findByPhone(String phone); + //根据手机号查询修改密码 @Modifying - @Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where username = ?1",nativeQuery = true) + @Query(value = "update sys_user set password = ?2 , pwd_reset_time = ?3 where phone = ?1",nativeQuery = true) void updatePass(String username, String pass, Date lastPasswordResetTime); diff --git a/system/src/main/java/com/canvas/web/modules/system/service/RoleService.java b/system/src/main/java/com/canvas/web/modules/system/service/RoleService.java index 1a0a434..d6664ae 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/RoleService.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/RoleService.java @@ -1,9 +1,12 @@ package com.canvas.web.modules.system.service; +import com.canvas.web.modules.system.domain.Role; +import com.canvas.web.modules.system.service.dto.RoleSmallDto; import com.canvas.web.modules.system.service.dto.UserDto; import org.springframework.security.core.GrantedAuthority; import java.util.List; +import java.util.Set; public interface RoleService { @@ -13,4 +16,18 @@ public interface RoleService { * @return 权限信息 */ List mapToGrantedAuthorities(UserDto user); + + /** + * 根据用户ID查询 + * @param id 用户ID + * @return / + */ + List findByUsersId(Long id); + + /** + * 根据角色查询角色级别 + * @param roles / + * @return / + */ + Integer findByRoles(Set roles); } diff --git a/system/src/main/java/com/canvas/web/modules/system/service/UserService.java b/system/src/main/java/com/canvas/web/modules/system/service/UserService.java index c7ed06a..d07ee9e 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/UserService.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/UserService.java @@ -46,6 +46,7 @@ public interface UserService { UserDto findByName(String userName); + /** * 修改密码 * @param username 用户名 diff --git a/system/src/main/java/com/canvas/web/modules/system/service/impl/RoleServiceImpl.java b/system/src/main/java/com/canvas/web/modules/system/service/impl/RoleServiceImpl.java index 52c9e2b..6e34520 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/impl/RoleServiceImpl.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/impl/RoleServiceImpl.java @@ -1,6 +1,8 @@ package com.canvas.web.modules.system.service.impl; +import com.canvas.web.modules.system.domain.Role; import com.canvas.web.modules.system.service.RoleService; +import com.canvas.web.modules.system.service.dto.RoleSmallDto; import com.canvas.web.modules.system.service.dto.UserDto; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CacheConfig; @@ -8,6 +10,7 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Set; @Service @RequiredArgsConstructor @@ -17,4 +20,14 @@ public class RoleServiceImpl implements RoleService { public List mapToGrantedAuthorities(UserDto user) { return null; } + + @Override + public List findByUsersId(Long id) { + return null; + } + + @Override + public Integer findByRoles(Set roles) { + return null; + } } diff --git a/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java b/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java index 872edc2..6702b2a 100644 --- a/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java +++ b/system/src/main/java/com/canvas/web/modules/system/service/impl/UserServiceImpl.java @@ -1,10 +1,13 @@ package com.canvas.web.modules.system.service.impl; import com.canvas.web.config.FileProperties; +import com.canvas.web.exception.BaseException; import com.canvas.web.modules.security.service.UserCacheClean; import com.canvas.web.modules.system.domain.User; import com.canvas.web.modules.system.repository.UserRepository; +import com.canvas.web.modules.system.service.RoleService; import com.canvas.web.modules.system.service.UserService; +import com.canvas.web.modules.system.service.dto.RoleSmallDto; import com.canvas.web.modules.system.service.dto.UserDto; import com.canvas.web.modules.system.service.dto.UserQueryCriteria; import com.canvas.web.modules.system.service.mapstruct.UserMapper; @@ -18,9 +21,8 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -33,6 +35,8 @@ public class UserServiceImpl implements UserService{ private final FileProperties properties; private final RedisUtils redisUtils; private final UserCacheClean userCacheClean; + private final RoleService roleService; + @Override @@ -47,6 +51,8 @@ public class UserServiceImpl implements UserService{ } + + //需求手机号就是用户名,所以根据此处username 实际是手机号 @Override public UserDto findByName(String userName) { User user = userRepository.findByPhone(userName); @@ -59,7 +65,7 @@ public class UserServiceImpl implements UserService{ @Override public void updatePass(String username, String encryptPassword) { - + userRepository.updatePass(username,encryptPassword,new Date()); } @Override @@ -85,5 +91,17 @@ public class UserServiceImpl implements UserService{ } + /** + * 如果当前用户的角色级别低于创建用户的角色级别,则抛出权限错误 + * @param resources + */ + private void checkLevel(User resources) { + Integer currentLevel = Collections.min(roleService.findByUsersId(SecurityUtils.getCurrentUserId()).stream().map(RoleSmallDto::getLevel).collect(Collectors.toList())); + Integer optLevel = roleService.findByRoles(resources.getRoles()); + if (currentLevel > optLevel) { + throw new BaseException("角色权限不足"); + } + } + }