diff --git a/src/main/java/org/waterproofingdata/wpdauth/controller/UsersController.java b/src/main/java/org/waterproofingdata/wpdauth/controller/UsersController.java new file mode 100644 index 0000000..1e4b58b --- /dev/null +++ b/src/main/java/org/waterproofingdata/wpdauth/controller/UsersController.java @@ -0,0 +1,99 @@ +package org.waterproofingdata.wpdauth.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.waterproofingdata.wpdauth.dto.UsersRequestDTO; +import org.waterproofingdata.wpdauth.dto.UsersResponseDTO; +import org.waterproofingdata.wpdauth.model.Users; +import org.waterproofingdata.wpdauth.service.UsersService; +import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; + +@RestController +@RequestMapping("/users") +@Api(tags = "users") +public class UsersController { + @Autowired + private UsersService userService; + + @Autowired + private ModelMapper modelMapper; + + @PostMapping("/signin") + @ApiOperation(value = "${UserController.signin}") + @ApiResponses(value = {// + @ApiResponse(code = 400, message = "Something went wrong"), // + @ApiResponse(code = 422, message = "Invalid username/password supplied")}) + public String login(// + @ApiParam("Username") @RequestParam String username, // + @ApiParam("Password") @RequestParam String password) { + return userService.signin(username, password); + } + + @PostMapping("/signup") + @ApiOperation(value = "${UserController.signup}") + @ApiResponses(value = {// + @ApiResponse(code = 400, message = "Something went wrong"), // + @ApiResponse(code = 403, message = "Access denied"), // + @ApiResponse(code = 422, message = "Username is already in use")}) + public String signup(@ApiParam("Signup User") @RequestBody UsersRequestDTO user) { + return userService.signup(modelMapper.map(user, Users.class)); + } + + @PostMapping("/activate") + @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") + @ApiOperation(value = "${UserController.activate}", authorizations = { @Authorization(value="apiKey") }) + @ApiResponses(value = {// + @ApiResponse(code = 400, message = "Something went wrong"), // + @ApiResponse(code = 403, message = "Access denied"), // + @ApiResponse(code = 404, message = "The user doesn't exist"), // + @ApiResponse(code = 500, message = "Expired or invalid JWT token")}) + public String activate(@ApiParam("Username") @PathVariable String username) { + userService.activate(username); + return username; + } + + @GetMapping(value = "/{username}") + @PreAuthorize("hasRole('ROLE_ADMIN')") + @ApiOperation(value = "${UserController.search}", response = UsersResponseDTO.class, authorizations = { @Authorization(value="apiKey") }) + @ApiResponses(value = {// + @ApiResponse(code = 400, message = "Something went wrong"), // + @ApiResponse(code = 403, message = "Access denied"), // + @ApiResponse(code = 404, message = "The user doesn't exist"), // + @ApiResponse(code = 500, message = "Expired or invalid JWT token")}) + public UsersResponseDTO search(@ApiParam("Username") @PathVariable String username) { + return modelMapper.map(userService.search(username), UsersResponseDTO.class); + } + + @GetMapping(value = "/me") + @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") + @ApiOperation(value = "${UserController.me}", response = UsersResponseDTO.class, authorizations = { @Authorization(value="apiKey") }) + @ApiResponses(value = {// + @ApiResponse(code = 400, message = "Something went wrong"), // + @ApiResponse(code = 403, message = "Access denied"), // + @ApiResponse(code = 500, message = "Expired or invalid JWT token")}) + public UsersResponseDTO whoami(HttpServletRequest req) { + return modelMapper.map(userService.whoami(req), UsersResponseDTO.class); + } + + @GetMapping("/refresh") + @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')") + public String refresh(HttpServletRequest req) { + return userService.refresh(req.getRemoteUser()); + } +} diff --git a/src/main/java/org/waterproofingdata/wpdauth/service/UsersService.java b/src/main/java/org/waterproofingdata/wpdauth/service/UsersService.java new file mode 100644 index 0000000..8c3864e --- /dev/null +++ b/src/main/java/org/waterproofingdata/wpdauth/service/UsersService.java @@ -0,0 +1,74 @@ +package org.waterproofingdata.wpdauth.service; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import org.waterproofingdata.wpdauth.exception.CustomException; +import org.waterproofingdata.wpdauth.model.Users; +import org.waterproofingdata.wpdauth.repository.UsersRepository; +import org.waterproofingdata.wpdauth.security.JwtTokenProvider; + +@Service +public class UsersService { + @Autowired + private UsersRepository userRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private JwtTokenProvider jwtTokenProvider; + + @Autowired + private AuthenticationManager authenticationManager; + + public boolean existsByUsername(String username) { + return userRepository.existsByUsername(username); + } + + public String signin(String username, String password) { + try { + authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); + return jwtTokenProvider.createToken(username, userRepository.findByUsername(username).getRoles()); + } catch (AuthenticationException e) { + throw new CustomException("Invalid username/password supplied", HttpStatus.UNPROCESSABLE_ENTITY); + } + } + + public String signup(Users user) { + if (!existsByUsername(user.getUsername())) { + user.setPassword(passwordEncoder.encode(user.getPassword())); + userRepository.save(user); + return jwtTokenProvider.createToken(user.getUsername(), user.getRoles()); + } else { + throw new CustomException("Username is already in use", HttpStatus.UNPROCESSABLE_ENTITY); + } + } + + public void activate(String username) { + //userRepository.activateByUsername(username); + } + + public Users search(String username) { + Users user = userRepository.findByUsername(username); + if (user == null) { + throw new CustomException("The user doesn't exist", HttpStatus.NOT_FOUND); + } + return user; + } + + public Users whoami(HttpServletRequest req) { + return userRepository.findByUsername(jwtTokenProvider.getUsername(jwtTokenProvider.resolveToken(req))); + } + + public String refresh(String username) { + return jwtTokenProvider.createToken(username, userRepository.findByUsername(username).getRoles()); + } +}