package org.codiki.account; import java.io.IOException; import java.security.Principal; import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codiki.core.entities.dto.ImageDTO; import org.codiki.core.entities.dto.PasswordWrapperDTO; import org.codiki.core.entities.dto.UserDTO; import org.codiki.core.entities.persistence.User; import org.codiki.core.repositories.ImageRepository; import org.codiki.core.repositories.UserRepository; import org.codiki.core.security.CustomAuthenticationProvider; import org.codiki.core.services.FileUploadService; import org.codiki.core.services.UserService; import org.codiki.core.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @Service public class AccountService { @Autowired private CustomAuthenticationProvider authenticationProvider; @Autowired private UserService userService; @Autowired private UserRepository userRepository; @Autowired private FileUploadService fileUploadService; @Autowired private ImageRepository imageRepository; public User authenticate(final User pUser) throws BadCredentialsException { final User user = userService.checkCredentials(pUser.getEmail(), pUser.getPassword()); authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword())); return user; } public void changePassword(final User pUser, final PasswordWrapperDTO pPasswordWrapper, final HttpServletResponse pResponse) throws IOException { if(pPasswordWrapper.getNewPassword().equals(pPasswordWrapper.getConfirmPassword())) { // We fetch the connected user from database to get his hashed password final Optional userFromDb = userRepository.findById(pUser.getId()); if(userFromDb.isPresent() && StringUtils.compareHash(pPasswordWrapper.getOldPassword(), userFromDb.get().getPassword())) { userFromDb.get().setPassword(StringUtils.hashPassword(pPasswordWrapper.getNewPassword())); userRepository.save(userFromDb.get()); } else { pResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Le mot de passe saisi ne correspond pas au votre."); } } else { pResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Le mot de passe saisi ne correspond pas au votre."); } } public String uploadFile(final MultipartFile pFile, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { final String avatarFileName = fileUploadService.uploadProfileImage(pFile); final Optional connectedUser = userService.getUserByPrincipal(pPrincipal); if(connectedUser.isPresent()) { final Optional userFromDb = userRepository.findById(connectedUser.get().getId()); if(userFromDb.isPresent()) { userFromDb.get().setImage(avatarFileName); userRepository.save(userFromDb.get()); } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } return avatarFileName; } public Resource loadAvatar(final String pAvatarFileName) { return fileUploadService.loadAvatar(pAvatarFileName); } public List getUserImages(final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { List result = new LinkedList<>(); final Optional connectedUser = userService.getUserByPrincipal(pPrincipal); if(connectedUser.isPresent()) { result = imageRepository.getByUserId(connectedUser.get().getId()) .stream().map(ImageDTO::new).collect(Collectors.toList()); } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } return result; } public UserDTO signin(final UserDTO pUser, final HttpServletResponse pResponse) throws IOException { User user = new User(); if(pUser.getName() == null || pUser.getEmail() == null || pUser.getPassword() == null || "".equals(pUser.getPassword().trim())) { pResponse.sendError(HttpServletResponse.SC_BAD_REQUEST); } else if(userRepository.findByEmail(pUser.getEmail()).isPresent()) { pResponse.sendError(HttpServletResponse.SC_CONFLICT); } else { user.setName(pUser.getName()); user.setEmail(pUser.getEmail()); user.setPassword(StringUtils.hashPassword(pUser.getPassword())); user.setInscriptionDate(new Date()); userRepository.save(user); } return new UserDTO(user); } public void updateUser(final UserDTO pUser, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { final Optional connectedUserOpt = userService.getUserByPrincipal(pPrincipal); if(connectedUserOpt.isPresent()) { final User connectedUser = connectedUserOpt.get(); final Optional userFromDb = userRepository.findByEmail(pUser.getEmail()); /* * If a user is returned by the repository, that's the email adress is used, but * if it is not the same as the connected user, that's the email adress * corresponds to another user. So a 409 error is sent. Otherwise, if no user is * returned by the repository, that's the email adress is free to be used. So, * user can change him email adress. */ if(userFromDb.isPresent() && !connectedUser.getEmail().equals(userFromDb.get().getEmail())) { pResponse.sendError(HttpServletResponse.SC_CONFLICT); } else { connectedUser.setName(pUser.getName()); connectedUser.setEmail(pUser.getEmail()); userRepository.save(connectedUser); } } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } }