Java tutorial
/* * Copyright 2014 zhanhb. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.edu.zjnu.acm.judge.user; import cn.edu.zjnu.acm.judge.config.JudgeConfiguration; import cn.edu.zjnu.acm.judge.domain.User; import cn.edu.zjnu.acm.judge.mapper.UserMapper; import cn.edu.zjnu.acm.judge.util.Utility; import cn.edu.zjnu.acm.judge.util.ValueCheck; import java.io.IOException; import java.io.PrintWriter; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.HashMap; import java.util.Locale; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.MailException; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import static org.springframework.http.MediaType.TEXT_HTML_VALUE; @Controller @Slf4j public class ResetPasswordController { @Autowired private JavaMailSenderImpl javaMailSender; @Autowired private TemplateEngine templateEngine; @Autowired private UserMapper userMapper; @Autowired private PasswordEncoder passwordEncoder; @Autowired private JudgeConfiguration judgeConfiguration; @GetMapping(value = "/resetPassword", produces = TEXT_HTML_VALUE) public String doGet(HttpServletRequest request) { if (checkVcode(request)) { return "resetPassword"; } else { return "invalid"; } } @PostMapping("/resetPassword") public void doPost(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "action", required = false) String action, @RequestParam(value = "verify", required = false) String verify, @RequestParam(value = "username", required = false) String username, Locale locale) throws IOException { response.setContentType("text/javascript;charset=UTF-8"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(false); String word = null; if (session != null) { word = (String) session.getAttribute("word"); session.removeAttribute("word"); } if (word == null || !word.equalsIgnoreCase(verify)) { out.print("alert('??');"); return; } User user = userMapper.findOne(username); if (user == null) { out.print("alert('?');"); return; } String email = user.getEmail(); if (email == null || !email.toLowerCase().matches(ValueCheck.EMAIL_PATTERN)) { out.print( "alert('???????');"); return; } try { String vc = user.getVcode(); if (vc == null || user.getExpireTime() != null && user.getExpireTime().compareTo(Instant.now()) < 0) { vc = Utility.getRandomString(16); } user = user.toBuilder().vcode(vc).expireTime(Instant.now().plus(1, ChronoUnit.HOURS)).build(); userMapper.update(user); String url = getPath(request, "/resetPassword.html?vc=", vc + "&u=", user.getId()); HashMap<String, Object> map = new HashMap<>(2); map.put("url", url); map.put("ojName", judgeConfiguration.getContextPath() + " OJ"); String content = templateEngine.process("users/password", new Context(locale, map)); String title = templateEngine.process("users/passwordTitle", new Context(locale, map)); MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setTo(email); helper.setSubject(title); helper.setText(content, true); helper.setFrom(javaMailSender.getUsername()); javaMailSender.send(mimeMessage); } catch (MailException | MessagingException ex) { log.error("", ex); out.print("alert('?????')"); return; } out.print("alert('???" + user.getEmail() + "??');"); } @PostMapping(value = "/resetPassword", params = "action=changePassword", produces = "text/javascript") public void changePassword(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/javascript;charset=UTF-8"); PrintWriter out = response.getWriter(); if (!checkVcode(request)) { out.print("alert(\"??\");"); return; } String newPassword = request.getParameter("newPassword"); ValueCheck.checkPassword(newPassword); User user = userMapper.findOne(request.getParameter("u")); userMapper.update(user.toBuilder().password(passwordEncoder.encode(newPassword)).vcode(null) .expireTime(null).build()); out.print("alert(\"???\");"); out.print("document.location='" + request.getContextPath() + "'"); } @SuppressWarnings("NestedAssignment") private boolean checkVcode(HttpServletRequest request) { String uid = request.getParameter("u"); String vcode = request.getParameter("vc"); User user = null; if (uid != null) { user = userMapper.findOne(uid); } String code; Instant expire; return user != null && (code = user.getVcode()) != null && code.equals(vcode) && ((expire = user.getExpireTime()) == null || expire.toEpochMilli() > System.currentTimeMillis()); } private String getPath(HttpServletRequest request, String... params) { int serverPort = request.getServerPort(); int defaultPort = request.isSecure() ? 443 : 80; StringBuilder sb = new StringBuilder(80); sb.append(request.getScheme()).append("://").append(request.getServerName()); if (serverPort != defaultPort) { sb.append(":").append(serverPort); } sb.append(request.getContextPath()); for (String param : params) { sb.append(param); } return sb.toString(); } }