Przeglądaj źródła

fix: 检验邮箱合法性,只允许南京大学邮箱

201250038 1 rok temu
rodzic
commit
b9b59865d4

+ 45 - 32
src/main/java/com/njuzr/eaibackend/service/impl/UserServiceImpl.java

@@ -66,8 +66,8 @@ public class UserServiceImpl implements UserService {
     public IPage<UserVO> searchUsers(Page<User> page, Long id, String name, String officialNumber, Role role) {
         QueryWrapper<User> queryWrapper = new QueryWrapper<>(); // 设置查询条件
 
-        if(role == Role.ADMIN) // 禁止访问查询ADMIN用户
-            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase()+":"+"被拒绝");
+        if (role == Role.ADMIN) // 禁止访问查询ADMIN用户
+            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase() + ":" + "被拒绝");
 
         queryWrapper
                 .eq(Objects.nonNull(id), "id", id)
@@ -75,7 +75,7 @@ public class UserServiceImpl implements UserService {
                 .eq(StringUtils.isNotBlank(officialNumber), "official_number", officialNumber)
                 .eq(Objects.nonNull(role), "role", role);
 
-        IPage<User> targets = userMapper.selectPage(page,queryWrapper); // selectPage是内置的方法
+        IPage<User> targets = userMapper.selectPage(page, queryWrapper); // selectPage是内置的方法
 
         // targets.total如果为0,则说明没有符合条件的用户,但是不报错,由前端自行处理异常。
 
@@ -85,13 +85,13 @@ public class UserServiceImpl implements UserService {
 
     //TODO:   注册DEMO:学生老师都可自行注册账号,管理员那套不需要修改/弃用,学生注册这套已经有完整逻辑,直接使用
     @Override
-    public UserVO createUser(UserRegisterDTO userDTO) throws MyException{
+    public UserVO createUser(UserRegisterDTO userDTO) throws MyException {
         // 从Redis中获取验证码
         final String key = "verifyCode:" + userDTO.getOfficialEmail();
         String storedCode = (String) redisTemplate.opsForValue().get(key);
 
         if (storedCode == null)
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"验证码已过期");
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码已过期");
 
         // 验证码校验
         if (storedCode.equals(userDTO.getVerifyCode())) {
@@ -110,25 +110,30 @@ public class UserServiceImpl implements UserService {
                 }
             }
 
-            log.info("User创建完毕,User对象如下:"+ targetUser);
+            log.info("User创建完毕,User对象如下:" + targetUser);
 
             redisTemplate.delete(key); //注册成功后删除验证码
 
             return ModelMapperUtil.map(targetUser, UserVO.class);
 
         } else {
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"验证码错误");
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "验证码错误");
         }
     }
 
     @Override
-    public void sendVerifyCode(String officialEmail) {
+    public void sendVerifyCode(String officialEmail) throws MyException {
+        // 检验邮箱合法性,只允许南京大学邮箱
+        if (!officialEmail.endsWith("@smail.nju.edu.cn") && !officialEmail.endsWith("@nju.edu.cn")) {
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "只允许南京大学邮箱,请检查邮箱格式");
+        }
+
         ValueOperations<String, Object> ops = redisTemplate.opsForValue();
         String intervalKey = "requestInterval:" + officialEmail;
 
         // 检查是否已经发送过验证码并且时间间隔未过
         if (ops.get(intervalKey) != null) {
-            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase()+":"+"需等待"+SEND_INTERVAL+"秒才能再次发送验证码");
+            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase() + ":" + "需等待" + SEND_INTERVAL + "秒才能再次发送验证码");
         }
 
         // 生成验证码
@@ -145,9 +150,9 @@ public class UserServiceImpl implements UserService {
     }
 
 
-
     /**
      * 管理员创建用户,给出name、officialEmail、officialNumber、role,随机生成密码,将密码通过邮件服务发送到用户邮箱
+     *
      * @param adminRegisterDTO
      * @return 1表示成功,0表示失败
      */
@@ -155,7 +160,7 @@ public class UserServiceImpl implements UserService {
     public void adminCreateUser(AdminRegisterDTO adminRegisterDTO) {
         Role role = adminRegisterDTO.getRole();
         if (role != Role.STUDENT && role != Role.TEACHER) { // 只能注册学生或老师账号
-            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase()+":"+"被拒绝");
+            throw new MyException(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase() + ":" + "被拒绝");
         }
 
         User targetUser = ModelMapperUtil.map(adminRegisterDTO, User.class);
@@ -169,12 +174,12 @@ public class UserServiceImpl implements UserService {
         // 同一个邮箱、学号只能注册一次
         if (isOfficialNumberNotExists(targetUser.getOfficialNumber())
                 && isEmailNotExists(targetUser.getOfficialEmail())) {
-            int code =  userMapper.insert(targetUser);
+            int code = userMapper.insert(targetUser);
             if (code == 0) {
                 log.error("createUser -- 数据库插入错误:");
                 throw new MyException(501, "数据库插入错误");
             }
-            log.info("User创建完毕,User对象如下:"+ targetUser);
+            log.info("User创建完毕,User对象如下:" + targetUser);
         }
 
         // 发送初始密码
@@ -183,7 +188,6 @@ public class UserServiceImpl implements UserService {
     }
 
     /**
-     *
      * @param userDTO
      * @return
      */
@@ -202,24 +206,24 @@ public class UserServiceImpl implements UserService {
             if (status > 0) {
                 return ModelMapperUtil.map(userMapper.selectById(opeUser.getId()), UserVO.class);
             }
-        }catch (Exception e) {
-            log.error("数据库更新错误,错误如下:"+e.getMessage());
-            throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"数据库更新失败");
+        } catch (Exception e) {
+            log.error("数据库更新错误,错误如下:" + e.getMessage());
+            throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() + ":" + "数据库更新失败");
         }
         return null;
     }
 
     @Override
-    public void updatePassword(Long id, String newPassword, String oldPassword) throws MyException{
+    public void updatePassword(Long id, String newPassword, String oldPassword) throws MyException {
         User user = userMapper.selectById(id);
         if (user == null) {
             log.error("用户不存在");
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"找不到用户");
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "找不到用户");
         }
 
         if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
             log.error("用户就密码不正确");
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"旧密码不正确");
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "旧密码不正确");
         }
 
         String encodedNewPassword = passwordEncoder.encode(newPassword);
@@ -231,12 +235,14 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 管理员重置密码,并将重置密码发送到指定邮箱
+     *
      * @param id
      */
     @Override
     public void resetPassword(Long id) {
         User targetUser = userMapper.selectById(id);
-        if(targetUser == null) throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"用户不存在");
+        if (targetUser == null)
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "用户不存在");
         String targetName = targetUser.getName();
         String targetEmail = targetUser.getOfficialEmail();
         String randomPassword = UUID.randomUUID().toString();
@@ -253,12 +259,13 @@ public class UserServiceImpl implements UserService {
         if (isUserExists(id)) {
             int res = userMapper.deleteById(id);
             if (res == 0)
-                throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"删除失败");
+                throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "删除失败");
         }
     }
 
     /**
      * 解析文件,批量创建用户。其中,文件必须包含姓名、邮箱、学号。
+     *
      * @param file
      * @return
      */
@@ -271,8 +278,8 @@ public class UserServiceImpl implements UserService {
         int numberCol = findColumnIndex(headerRow, "学号");
         int emailCol = findColumnIndex(headerRow, "邮箱");
 
-        if(nameCol < 0 || numberCol < 0 || emailCol < 0)
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"缺失必要字段信息");
+        if (nameCol < 0 || numberCol < 0 || emailCol < 0)
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "缺失必要字段信息");
 
         List<User> users = new ArrayList<>();
 
@@ -295,6 +302,7 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 批量创建用户,从csv文件中读取数据
+     *
      * @param file csv文件
      */
     @Override
@@ -305,8 +313,8 @@ public class UserServiceImpl implements UserService {
         int numberCol = findColumnIndex(header, "学号");
         int emailCol = findColumnIndex(header, "邮箱");
 
-        if(nameCol < 0 || numberCol < 0 || emailCol < 0)
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"缺失必要字段信息");
+        if (nameCol < 0 || numberCol < 0 || emailCol < 0)
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "缺失必要字段信息");
 
         List<User> users = new ArrayList<>();
         String[] nextRecord;
@@ -335,10 +343,11 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 查看学号是否不存在
+     *
      * @param officialNumber 学号
      * @return true表示不存在,false表示存在
      */
-    private boolean isOfficialNumberNotExists(String officialNumber) throws MyException{
+    private boolean isOfficialNumberNotExists(String officialNumber) throws MyException {
         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("official_number", officialNumber);
         User existingUser = userMapper.selectOne(queryWrapper);
@@ -352,10 +361,11 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 查看邮箱是否不存在
+     *
      * @param email 邮箱
      * @return true表示不存在,false表示存在
      */
-    private boolean isEmailNotExists(String email) throws MyException{
+    private boolean isEmailNotExists(String email) throws MyException {
         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("official_email", email);
         User existingUser = userMapper.selectOne(queryWrapper);
@@ -369,11 +379,12 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 检查用户ID是否存在,如果存在则返回true;不存在则报错
+     *
      * @param id
      * @return
      * @throws MyException
      */
-    private boolean isUserExists(Long id) throws MyException{
+    private boolean isUserExists(Long id) throws MyException {
         QueryWrapper<User> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("id", id);
         User existingUser = userMapper.selectOne(queryWrapper);
@@ -414,13 +425,14 @@ public class UserServiceImpl implements UserService {
         } else {
             // 其他类型,根据需要处理或转换为字符串
             // 例如,对于公式类型,可以计算公式的值
-            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase()+":"+"上传失败:请检查excel单元格的类型");
+            throw new MyException(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase() + ":" + "上传失败:请检查excel单元格的类型");
         }
         return cellValue;
     }
 
     /**
      * 在csv文件的header中找到具体列的索引值
+     *
      * @param header
      * @param columnName
      * @return
@@ -437,11 +449,12 @@ public class UserServiceImpl implements UserService {
 
     /**
      * 统一生成随机密码,批量创建用户,创建成功后,将初始密码发送至邮箱
+     *
      * @param users
      */
     private void processUsers(List<User> users) {
         List<String> passwordStage = new ArrayList<>();
-        for(User user: users) {
+        for (User user : users) {
             // 随机生成密码,并使用BCryptPasswordEncoder加密密码
             String randomPassword = UUID.randomUUID().toString();
             passwordStage.add(randomPassword);
@@ -450,7 +463,7 @@ public class UserServiceImpl implements UserService {
         }
         int res = userMapper.batchInsert(users);
         if (res == 0)
-            throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(),HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()+":"+"批量创建失败");
+            throw new MyException(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase() + ":" + "批量创建失败");
 
         for (int i = 0; i < users.size(); i++) {
             emailService.sendInitialPasswordEmail(users.get(i).getOfficialEmail(), users.get(i).getName(), passwordStage.get(i));