package org.xmx0632.deliciousfruit.service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springside.modules.utils.Encodes;
import org.xmx0632.deliciousfruit.api.v1.helper.PasswordHelper;
import org.xmx0632.deliciousfruit.entity.UserAccount;
import org.xmx0632.deliciousfruit.global.ConfigConstant;
import org.xmx0632.deliciousfruit.utilities.email.MimeMailService;
import org.xmx0632.deliciousfruit.utilities.email.SendNotificationMailParameter;
import org.xmx0632.deliciousfruit.utilities.sms.SmsService;
@Component
public class ResetPasswordService {
private static Logger log = LoggerFactory
.getLogger(ResetPasswordService.class);
private LinkedBlockingQueue<ResetPasswordTask> emailResetPasswordTaskList = new LinkedBlockingQueue<ResetPasswordTask>(
300);
private LinkedBlockingQueue<ResetPasswordTask> mobileResetPasswordTaskList = new LinkedBlockingQueue<ResetPasswordTask>(
300);
@Autowired
private MimeMailService mimeMailService;
@Autowired
private SmsService smsService;
@Autowired
private UserAccountService userAccountService;
private int batchLimit = 10;
@Autowired
private ConfigService configService;
public void sendNotificationMail() {
int queueSize = emailResetPasswordTaskList.size();
log.debug("resetPasswordTask queue size:{} ", queueSize);
int size = Math.min(queueSize, batchLimit);
log.debug("size:{} ", size);
List<SendNotificationMailParameter> paramList = new ArrayList<SendNotificationMailParameter>();
for (int i = 0; i < size; i++) {
ResetPasswordTask task = emailResetPasswordTaskList.poll();
log.debug("reset password task:{}", task);
if (task == null) {
continue;
}
String resetUrl = generateResetUrl(task);
paramList.add(new SendNotificationMailParameter(task.getUsername(),
resetUrl, task.getMail(), task.getMail(), "用户密码重置"));
}
if (paramList.isEmpty()) {
log.debug("no reset task in queue.");
return;
}
mimeMailService.sendNotificationMail(paramList
.toArray(new SendNotificationMailParameter[paramList.size()]));
}
public void sendNewPasswordToMobile() {
int queueSize = mobileResetPasswordTaskList.size();
log.debug("mobile resetPasswordTask queue size:{} ", queueSize);
int size = Math.min(queueSize, batchLimit);
log.debug("size:{} ", size);
for (int i = 0; i < size; i++) {
ResetPasswordTask task = mobileResetPasswordTaskList.poll();
if (task == null) {
continue;
}
boolean result = sendSmsMessage(task);
log.debug("mobile reset password task:{} result:{}", task, result);
}
}
private boolean sendSmsMessage(ResetPasswordTask task) {
// 发送短信通知
log.debug("send message to mobile for task:{}", task);
String userName = task.getUsername();
String mobileNo = task.getUsername();
// 取手机号后6位作为新密码
long currentTime = System.currentTimeMillis();
String newPassword = PasswordHelper.generatePassword(
String.valueOf(currentTime), 6);
boolean sendNewPasswordSuccess = smsService.sendResetPassword(userName,
mobileNo, newPassword);
log.info("send new password sms success:{} for [{}]",
sendNewPasswordSuccess, userName);
// 更新用户密码
if (sendNewPasswordSuccess) {
log.debug("update new passord [{}] for [{}]", newPassword, userName);
UserAccount userAccount = userAccountService
.findByUsername(userName);
if (userAccount != null && StringUtils.isNotBlank(newPassword)) {
String encodedPassword = PasswordHelper.md5(newPassword);
userAccount.setPassword(encodedPassword);
userAccountService.saveUserAccount(userAccount);
}
}
return true;
}
private String generateResetUrl(ResetPasswordTask task) {
String serverAddress = configService
.getByName(ConfigConstant.SERVER_ROOT_ADDRESS);
long currentTimeMillis = System.currentTimeMillis();
String params = setupParams(task.getUsername(), task.getMail(),
currentTimeMillis);
String enkey = Encodes.encodeBase62(params.getBytes());
String rstUrl = serverAddress + "resetPwd/init?" + params + "&enkey="
+ enkey;
log.debug("serverAddress:{} rstUrl:{}", serverAddress, rstUrl);
return rstUrl;
}
public void addEmailTask(ResetPasswordTask task) {
log.info("user:{} need reset password by email", task.getUsername());
emailResetPasswordTaskList.add(task);
}
public void addMobileTask(ResetPasswordTask task) {
log.info("user:{} need reset password by mobile", task.getUsername());
mobileResetPasswordTaskList.add(task);
}
public boolean isValidRequest(String username, String email, Long ts,
String enkey) {
if (isExpired(ts)) {
return false;
}
String params = setupParams(username, email, ts);
String caculatedEnkey = Encodes.encodeBase62(params.getBytes());
log.debug("caculatedEnkey:{}", caculatedEnkey);
return caculatedEnkey.equals(enkey);
}
private boolean isExpired(Long ts) {
int expireTime = configService
.getIntByName(ConfigConstant.PASSWORD_RESET_URL_EXPIRE_TIME);
DateTime resetTimestamp = new DateTime(ts);
DateTime _3DayBefore = DateTime.now().plusDays(-expireTime);
log.debug("_3DayBefore:{}", _3DayBefore);
if (resetTimestamp.isBefore(_3DayBefore)) {
return true;
}
return false;
}
private String setupParams(String username, String email, Long ts) {
return "username=" + username + "&email=" + email + "&ts=" + ts;
}
}