学生管理系统作业
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.5 KiB

package com.student.service;
import com.student.bean.LoginLog;
import com.student.bean.RememberToken;
import com.student.bean.User;
import com.student.dao.LogDao;
import com.student.dao.RememberTokenDao;
import com.student.dao.UserDao;
import com.student.dao.impl.LogDaoImpl;
import com.student.dao.impl.RememberTokenDaoImpl;
import com.student.dao.impl.UserDaoImpl;
import com.student.util.PasswordUtil;
import java.util.Calendar;
import java.util.Date;
public class AuthService {
private static final int MAX_FAIL_COUNT = 5;
private static final int LOCK_MINUTES = 30;
private static final int REMEMBER_DAYS = 7;
private final UserDao userDao;
private final LogDao logDao;
private final RememberTokenDao tokenDao;
public AuthService() {
this(new UserDaoImpl(), new LogDaoImpl(), new RememberTokenDaoImpl());
}
AuthService(UserDao userDao, LogDao logDao, RememberTokenDao tokenDao) {
this.userDao = userDao;
this.logDao = logDao;
this.tokenDao = tokenDao;
}
public User login(String username, String password, String ip) {
User user = userDao.findByUsername(username);
if (user == null) {
saveLoginLog(null, username, ip, 0, "用户不存在");
return null;
}
if (isLocked(user)) {
saveLoginLog(user.getId(), username, ip, 0, "账户已锁定");
throw new RuntimeException("账户已锁定,请稍后再试");
}
if (!PasswordUtil.verify(password, user.getSalt(), user.getPassword())) {
int failCount = (user.getFailCount() != null ? user.getFailCount() : 0) + 1;
userDao.updateFailCount(user.getId(), failCount);
if (failCount >= MAX_FAIL_COUNT) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, LOCK_MINUTES);
userDao.lockUser(user.getId(), cal.getTime());
saveLoginLog(user.getId(), username, ip, 0, "密码错误,账户已锁定");
throw new RuntimeException("密码错误次数过多,账户已锁定30分钟");
}
saveLoginLog(user.getId(), username, ip, 0, "密码错误");
return null;
}
if (user.getStatus() != null && user.getStatus() == User.STATUS_PENDING) {
saveLoginLog(user.getId(), username, ip, 0, "账户待审核");
throw new RuntimeException("账户待审核,请等待管理员审批");
}
if (user.getStatus() != null && (user.getStatus() == User.STATUS_SUSPEND
|| user.getStatus() == User.STATUS_DROPPED)) {
saveLoginLog(user.getId(), username, ip, 0, "账户已停用");
throw new RuntimeException("账户已停用");
}
userDao.updateFailCount(user.getId(), 0);
userDao.lockUser(user.getId(), null);
saveLoginLog(user.getId(), username, ip, 1, "登录成功");
user.setPassword(null);
return user;
}
public String createRememberToken(int userId) {
tokenDao.deleteByUser(userId);
RememberToken token = new RememberToken();
token.setUserId(userId);
token.setToken(PasswordUtil.generateToken());
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, REMEMBER_DAYS);
token.setExpireTime(cal.getTime());
tokenDao.save(token);
return token.getToken();
}
public User loginByToken(String token) {
RememberToken rt = tokenDao.findByToken(token);
if (rt == null) {
return null;
}
User user = userDao.findById(rt.getUserId());
if (user != null) {
user.setPassword(null);
}
return user;
}
public void logoutRemember(int userId) {
tokenDao.deleteByUser(userId);
}
public void cleanExpiredTokens() {
tokenDao.deleteExpired();
}
private boolean isLocked(User user) {
if (user.getLockUntil() == null) {
return false;
}
return user.getLockUntil().after(new Date());
}
private void saveLoginLog(Integer userId, String username, String ip, int result, String message) {
LoginLog log = new LoginLog();
log.setUserId(userId);
log.setUsername(username);
log.setIp(ip);
log.setResult(result);
log.setMessage(message);
logDao.saveLoginLog(log);
}
}