package org.codiki.account; import java.io.IOException; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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.security.TokenService; import org.codiki.core.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/api/account") public class AccountController { private static final String HEADER_TOKEN = "token"; @Autowired private AccountService accountService; @Autowired private TokenService tokenService; /** * Log in the user in request body. * * @param pUser * The user to connect. * @param response * The reponse injected by Spring. * @return The connected user object. * @throws IOException * If credentials are bad. */ @PostMapping("/login") public UserDTO login(@RequestBody UserDTO pUser, HttpServletResponse response) throws IOException { return accountService.checkCredentials(response, pUser); } /** * Log out the user. * * @param pRequest * The request injected by Spring. */ @GetMapping("/logout") public void logout(HttpServletRequest pRequest) { tokenService.removeUser(pRequest.getHeader(HEADER_TOKEN)); } /** * Updates the user password. * * @param pPasswordWrapper * The object which contains the old password for verification and * the new password to set to the user. * @param pRequest * The request injected by Spring. * @param pResponse * The reponse injected by Spring. * @throws IOException * If the old password doesn't match to the user password in * database. */ @PutMapping("/changePassword") public void changePassword(@RequestBody final PasswordWrapperDTO pPasswordWrapper, final HttpServletRequest pRequest, final HttpServletResponse pResponse) throws IOException { final Optional connectedUser = tokenService.getAuthenticatedUserByToken(pRequest); if(connectedUser.isPresent()) { accountService.changePassword(connectedUser.get(), pPasswordWrapper, pResponse); } else { pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } @PostMapping("/uploadAvatar") public ResponseEntity uploadAvatar(@RequestParam("file") MultipartFile pFile, final HttpServletRequest pRequest, final HttpServletResponse pResponse) { String result; try { result = accountService.uploadFile(pFile, pRequest, pResponse); return ResponseEntity.status(HttpStatus.OK).body(result); } catch(final Exception pEx) { result = StringUtils.concat("Fail to upload ", pFile.getOriginalFilename() + "."); return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(result); } } @GetMapping("/loadAvatar/{avatarFileName}") public ResponseEntity loadAvatar(@PathVariable("avatarFileName") final String pAvatarFileName) { final Resource avatarFile = accountService.loadAvatar(pAvatarFileName); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, StringUtils.concat("attachment; filename=\"", avatarFile.getFilename(), "\"")) .body(avatarFile); } }