package cc.openhome.controller; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.SessionAttribute; import org.springframework.web.bind.annotation.SessionAttributes; import cc.openhome.model.Account; import cc.openhome.model.EmailService; import cc.openhome.model.AccountService; @Controller @SessionAttributes("token") public class AccountController { @Value("#{'redirect:' + '${path.url.index}'}") private String REDIRECT_INDEX_PATH; @Value("${path.view.register_success}") private String REGISTER_SUCCESS_PATH; @Value("${path.view.register_form}") private String REGISTER_FORM_PATH; @Value("${path.view.verify}") private String VERIFY_PATH; @Value("${path.view.forgot}") private String FORGOT_PATH; @Value("${path.view.reset_password_form}") private String RESET_PASSWORD_FORM_PATH; @Value("${path.view.reset_password_success}") private String RESET_PASSWORD_SUCCESS_PATH; @Autowired private AccountService accountService; @Autowired private EmailService emailService; @GetMapping("register") public String registerForm() { return REGISTER_FORM_PATH; } @PostMapping("register") public String register( @Valid RegisterForm form, BindingResult bindingResult, Model model) { List<String> errors = toList(bindingResult); String path; if(errors.isEmpty()) { path = REGISTER_SUCCESS_PATH; Optional<Account> optionalAcct = Optional.ofNullable(accountService.tryCreateUser( form.getEmail(), form.getUsername(), form.getPassword()).getContent()); System.out.println(optionalAcct); if(optionalAcct.isPresent()) { emailService.validationLink(optionalAcct.get()); } else { emailService.failedRegistration( form.getUsername(), form.getEmail()); } } else { path = REGISTER_FORM_PATH; model.addAttribute("errors", errors); } return path; } @GetMapping("verify") public String verify( @RequestParam String email, @RequestParam String token, Model model) { model.addAttribute("acct", accountService.verify(email, token)); return VERIFY_PATH; } @PostMapping("forgot") public String forgot( @RequestParam String name, @RequestParam String email, Model model) { Optional<Account> optionalAcct = Optional.ofNullable(accountService.accountByNameEmail(name, email).getContent()); if(optionalAcct.isPresent()) { emailService.passwordResetLink(optionalAcct.get()); } model.addAttribute("email", email); return FORGOT_PATH; } @GetMapping("reset_password") public String resetPasswordForm( @RequestParam String name, @RequestParam String email, @RequestParam String token, Model model) { Optional<Account> optionalAcct = Optional.ofNullable(accountService.accountByNameEmail(name, email).getContent()); if(optionalAcct.isPresent()) { Account acct = optionalAcct.get(); if(acct.getPassword().equals(token)) { model.addAttribute("acct", acct); model.addAttribute("token", token); return RESET_PASSWORD_FORM_PATH; } } return REDIRECT_INDEX_PATH; } @PostMapping("reset_password") public String resetPassword( @Valid ResetPasswordForm form, BindingResult bindingResult, @SessionAttribute(name = "token") String storedToken, Model model) { if(storedToken == null || !storedToken.equals(form.getToken())) { return REDIRECT_INDEX_PATH; } List<String> errors = toList(bindingResult); if(!errors.isEmpty()) { Optional<Account> optionalAcct = Optional.ofNullable(accountService.accountByNameEmail(form.getName(), form.getEmail()).getContent()); model.addAttribute("errors", errors); model.addAttribute("acct", optionalAcct.get()); return RESET_PASSWORD_FORM_PATH; } else { accountService.resetPassword(form.getName(), form.getPassword()); return RESET_PASSWORD_SUCCESS_PATH; } } private List<String> toList(BindingResult bindingResult) { List<String> errors = new ArrayList<>(); if(bindingResult.hasErrors()) { bindingResult.getFieldErrors().forEach(err -> { errors.add(err.getDefaultMessage()); }); } return errors; } }