1
0
Files
light-blog/src/main/java/xyz/fortern/service/AccountService.java
2024-03-28 04:24:35 +08:00

117 lines
4.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}