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; } }