package xyz.fortern.service; import org.springframework.lang.NonNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import xyz.fortern.dao.SecurityMapper; import xyz.fortern.dao.UserMapper; import xyz.fortern.pojo.PermissionKeyValue; import xyz.fortern.pojo.Security; import xyz.fortern.pojo.User; import javax.servlet.http.HttpSession; import java.util.HashSet; import static xyz.fortern.bbs.SystemConstant.EMAIL_REGEX; @Service public class AccountService { private final UserMapper userMapper; private final SecurityMapper securityMapper; private final PasswordEncoder passwordEncoder; public AccountService(UserMapper userMapper, SecurityMapper securityMapper, PasswordEncoder passwordEncoder) { this.userMapper = userMapper; this.securityMapper = securityMapper; this.passwordEncoder = passwordEncoder; } /** * 通过登录名和密码登录 * * @param loginName 登录名,可能是用户名和手机号 * @param password 密码 * @return 登录结果 */ public int login(String loginName, String password, HttpSession session) { String column = EMAIL_REGEX.matcher(loginName).matches() ? "email" : "username"; var security = securityMapper.selectSecurityInfoByLoginName(loginName, column); if (security == null) return 0;//用户不存在 if (security.getLocked()) return -2;//用户被锁定,不可登录 if (passwordEncoder.matches(password, security.getPassword())) { int userId = security.getUserId(); //如果密码匹配 //获取用户基本信息 var user = userMapper.selectById(userId); //设置权限信息 var authorities = new HashSet(); for (PermissionKeyValue permission : PermissionKeyValue.values()) { if ((permission.value ^ security.getPermissions()) == permission.value) { authorities.add(new SimpleGrantedAuthority(permission.name)); } } if (security.getPosition() == Security.Position.MANAGER) authorities.add(new SimpleGrantedAuthority("manager")); var authenticationToken = new UsernamePasswordAuthenticationToken(userId, null, authorities); //将认证成功信息设置到安全上下文中 SecurityContextHolder.getContext().setAuthentication(authenticationToken); //用户相关信息放入Session中 session.setAttribute("user", user); session.setAttribute("security", security); return 1;//登录成功 } else { return -1;//密码错误 } } /** * 注册业务 * * @param username 用户名 * @param password 密码 * @param email 电子邮箱 * @param qqNumber QQ号 */ @Transactional public void register(String username, String password, String email, String qqNumber) { //先存用户,获取用户id var user = User.builder().username(username).email(email).qqNumber(qqNumber).build(); userMapper.insert(user); //再存安全信息 var security = Security.builder().password(passwordEncoder.encode(password)).userId(user.getId()).build(); securityMapper.insert(security); } /** * 修改密码 * * @param uid 用户id * @param newPassword 新密码(明文) */ @Transactional public Security changePassword(int uid, String newPassword) { var security = Security.builder().userId(uid).password(passwordEncoder.encode(newPassword)).build(); securityMapper.updateById(security); return securityMapper.selectSecurityInfoByLoginName(Integer.toString(uid), "user_id"); } /** * 检验密码是否正确 * * @param oldPassword 旧密码(明文) * @param encodedOldPassword 旧密码(密文) */ public boolean passwordMatches(@NonNull String oldPassword, @NonNull String encodedOldPassword) { return passwordEncoder.matches(oldPassword, encodedOldPassword); } }