package org.codiki.account; import java.io.IOException; import java.security.Principal; 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.dto.View; import org.codiki.core.entities.persistence.User; import org.codiki.core.services.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.web.bind.annotation.GetMapping; 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.RestController; import com.fasterxml.jackson.annotation.JsonView; @RestController @RequestMapping("/api/account") public class AccountController { /** Account service. */ private AccountService accountService; /** User service. */ private UserService userService; /** * Constructor. * @param accountService Account service. * @param userService User service. */ public AccountController(AccountService accountService, UserService userService) { this.accountService = accountService; this.userService = userService; } @JsonView(View.UserDTO.class) @PostMapping("/login") public User login(@RequestBody final User pUser, HttpServletResponse pResponse) throws BadCredentialsException { User result = null; try { result = accountService.authenticate(pUser); } catch(BadCredentialsException ex) { pResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } return result; } @GetMapping("/logout") public void logout(final HttpServletRequest request, final HttpServletResponse response) { final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if(auth != null) { new SecurityContextLogoutHandler().logout(request, response, auth); } } /** * 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 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 HttpServletResponse pResponse, final Principal pPrincipal) { int httpResponseCode = userService.getUserByPrincipal(pPrincipal) .map(user -> { try { return accountService.changePassword(user, pPasswordWrapper); } catch (IllegalArgumentException e) { return HttpServletResponse.SC_BAD_REQUEST; } }) .orElse(HttpServletResponse.SC_UNAUTHORIZED); pResponse.setStatus(httpResponseCode); } @PostMapping("/signin") public void signin(@RequestBody final User pUser, final HttpServletResponse pResponse) throws IOException { accountService.signin(pUser, pResponse); } @PutMapping("/") public void update(@RequestBody final UserDTO pUser, final HttpServletRequest pRequest, final HttpServletResponse pResponse, final Principal pPrincipal) throws IOException { accountService.updateUser(pUser, pRequest, pResponse, pPrincipal); } }