117 lines
4.1 KiB
Java
117 lines
4.1 KiB
Java
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<GrantedAuthority>();
|
||
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);
|
||
}
|
||
|
||
}
|