/* * Copyright (C) 2008-2023, Juick * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package com.juick.www.controllers; import com.juick.model.User; import com.juick.util.HttpBadRequestException; import com.juick.util.HttpForbiddenException; import com.juick.util.UsernameTakenException; import com.juick.www.WebApp; import com.juick.service.EmailService; import com.juick.service.UserService; import com.juick.service.security.entities.JuickUser; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.RememberMeServices; import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.inject.Inject; /** * * @author Ugnich Anton */ @Controller public class SignUp { @Inject private UserService userService; @Inject private EmailService emailService; @Inject private WebApp webApp; @Inject private RememberMeServices rememberMeServices; @GetMapping("/signup") protected String doGet( @Parameter(hidden = true) User visitor, @RequestParam String type, @RequestParam String hash, ModelMap model) { if (hash.length() > 36 || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) { throw new HttpBadRequestException(); } String account = null; switch (type) { case "fb": account = userService.getFacebookNameByHash(hash); break; case "vk": account = userService.getVKNameByHash(hash); break; case "xmpp": account = userService.getJIDByHash(hash); break; case "durov": account = userService.getTelegramNameByHash(hash); break; case "email": account = emailService.getEmailByAuthCode(hash); } if (account == null) { throw new HttpBadRequestException(); } model.addAttribute("title", "Новый пользователь"); visitor.setAvatar(webApp.getAvatarWebPath(visitor)); model.addAttribute("visitor", visitor); model.addAttribute("account", account); model.addAttribute("type", type); model.addAttribute("hash", hash); return "views/signup"; } @PostMapping("/signup") protected String doPost( HttpServletRequest request, HttpServletResponse response, @Parameter(hidden = true) User visitor, @RequestParam String type, @RequestParam String hash, @RequestParam String action, @RequestParam(required = false) String username, @RequestParam(required = false) String password, ModelMap modelMap) { User current; if (hash.length() > 36 || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) { modelMap.addAttribute("result", "Invalid request"); modelMap.addAttribute("visitor", visitor); return "views/signup_result"; } if (action.charAt(0) == 'l') { if (visitor.isAnonymous()) { if (username.length() > 32) { modelMap.addAttribute("result", "Invalid request"); modelMap.addAttribute("visitor", visitor); return "views/signup_result"; } current = userService.checkPassword(username, password).orElseThrow(HttpForbiddenException::new); } else { current = visitor; } if (current.getUid() <= 0) { modelMap.addAttribute("result", "Invalid request"); modelMap.addAttribute("visitor", visitor); return "views/signup_result"; } if (!(type.charAt(0) == 'f' && userService.setFacebookUser(hash, current.getUid())) && !(type.charAt(0) == 'v' && userService.setVKUser(hash, current.getUid())) && !(type.charAt(0) == 'd' && userService.setTelegramUser(hash, current.getUid())) && !(type.charAt(0) == 'x' && userService.getAllJIDs(visitor).size() > 0 && userService.setJIDUser(hash, current.getUid()))) { if (type.equals("email")) { String email = emailService.getEmailByAuthCode(hash); emailService.addEmail(current.getUid(), email); emailService.deleteAuthCode(hash); } else { if (type.equals("xmpp")) { modelMap.addAttribute("result", "XMPP support is disabled for new users"); } else { modelMap.addAttribute("result", "Invalid request"); } modelMap.addAttribute("visitor", visitor); return "views/signup_result"; } } } else { // Create new account if (username.length() < 2 || username.length() > 16 || !username.matches("^[a-zA-Z0-9\\-]+$") || password.length() < 6 || password.length() > 32) { modelMap.addAttribute("visitor", visitor); modelMap.addAttribute("result", "Bad username or password"); return "views/signup_result"; } try { current = userService.createUser(username, password).orElseThrow(HttpBadRequestException::new); } catch(UsernameTakenException e) { modelMap.addAttribute("visitor", visitor); modelMap.addAttribute("result", e.getMessage()); return "views/signup_result"; } if (!(type.charAt(0) == 'f' && userService.setFacebookUser(hash, current.getUid())) && !(type.charAt(0) == 'v' && userService.setVKUser(hash, current.getUid())) && !(type.charAt(0) == 'd' && userService.setTelegramUser(hash, current.getUid()))) { if (type.equals("email")) { String email = emailService.getEmailByAuthCode(hash); emailService.addEmail(current.getUid(), email); emailService.deleteAuthCode(hash); } else { if (type.equals("xmpp")) { modelMap.addAttribute("result", "XMPP support is disabled for new users"); } else { modelMap.addAttribute("result", "Invalid request"); } modelMap.addAttribute("visitor", visitor); return "views/signup_result"; } } } if (visitor.isAnonymous()) { var authentication = new RememberMeAuthenticationToken( ((AbstractRememberMeServices) rememberMeServices).getKey(), new JuickUser(current), JuickUser.USER_AUTHORITY); SecurityContextHolder.getContext().setAuthentication(authentication); rememberMeServices.loginSuccess(request, response, authentication); } return "redirect:/"; } }