From 1820b567a6f63b9983d9a83046c5f6c0f7c47360 Mon Sep 17 00:00:00 2001 From: Programmist73 Date: Mon, 15 May 2023 15:59:55 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=20=D0=B1=D0=B5=D0=BA=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D0=B0=20=D1=82=D0=B8=D0=BF=D0=BE=20=D0=B2?= =?UTF-8?q?=D1=81=D1=91.=20=D0=9D=D0=BE=20=D1=8D=D1=82=D0=BE=20=D1=82?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BF=D0=BE=D0=BA=D0=B0...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../configuration/SecurityConfiguration.java | 2 +- .../controller/GameClientController.java | 42 +++++++++++++++---- .../service/GameClientService.java | 37 +++++++++++++--- .../exception/ClientNotFoundException.java | 4 ++ .../exception/UserExistsException.java | 7 ++++ 5 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 spring_online_calculator/src/main/java/premium_store/service/exception/UserExistsException.java diff --git a/spring_online_calculator/src/main/java/premium_store/configuration/SecurityConfiguration.java b/spring_online_calculator/src/main/java/premium_store/configuration/SecurityConfiguration.java index 7528515..7f06a82 100644 --- a/spring_online_calculator/src/main/java/premium_store/configuration/SecurityConfiguration.java +++ b/spring_online_calculator/src/main/java/premium_store/configuration/SecurityConfiguration.java @@ -40,7 +40,7 @@ public class SecurityConfiguration { final String admin = "admin"; if (userService.findByLogin(admin) == null) { log.info("Admin user successfully created"); - userService.addClient(admin, "admin@gmail.com", admin, admin, UserRole.ADMIN); + userService.addClient(admin, "admin@gmail.com", admin, 0, admin, UserRole.ADMIN); } } diff --git a/spring_online_calculator/src/main/java/premium_store/controller/controller/GameClientController.java b/spring_online_calculator/src/main/java/premium_store/controller/controller/GameClientController.java index ccc5a78..748aec4 100644 --- a/spring_online_calculator/src/main/java/premium_store/controller/controller/GameClientController.java +++ b/spring_online_calculator/src/main/java/premium_store/controller/controller/GameClientController.java @@ -1,19 +1,27 @@ package premium_store.controller.controller; +import org.springframework.security.access.annotation.Secured; import org.springframework.web.bind.annotation.*; import premium_store.configuration.OpenAPI30Configuration; -import premium_store.configuration.WebConfiguration; import premium_store.controller.DTO.ClientDTO; +import premium_store.controller.DTO.UserSignupDto; +import premium_store.model.GameClient; import premium_store.model.UserRole; import premium_store.service.GameClientService; import premium_store.service.TankService; +import javax.validation.Valid; +import javax.validation.ValidationException; import java.util.List; @RestController @CrossOrigin -@RequestMapping(OpenAPI30Configuration.API_PREFIX + "/client") +@RequestMapping("/client") public class GameClientController { + public static final String URL_LOGIN = "/jwt/login"; + public static final String URL_SING_UP = "/sing_up"; + public static final String URL_WHO_AM_I = "/who_am_i"; + private final GameClientService gameClientService; private final TankService tankService; @@ -22,21 +30,39 @@ public class GameClientController { this.tankService = tankService; } + @PostMapping(URL_LOGIN) + public String login(@RequestBody @Valid ClientDTO userDto) { + return gameClientService.loginAndGetToken(userDto); + } + + @PostMapping(URL_SING_UP) + public String singUp(@RequestBody @Valid UserSignupDto userSignupDto) { + try { + final GameClient user = gameClientService.addClient(userSignupDto.getLogin(), userSignupDto.getEmail(), userSignupDto.getPassword(), + Integer.parseInt(userSignupDto.getBalance()), userSignupDto.getPasswordConfirm(), UserRole.USER); + + return "created " + user.getLogin(); + } catch (ValidationException e) { + return e.getMessage(); + } + } + //аннотация PathVariable связывает значения id из URL и Long id - @GetMapping("/{id}") + @GetMapping(OpenAPI30Configuration.API_PREFIX + "/{id}") public ClientDTO getClient(@PathVariable Long id) { return new ClientDTO(gameClientService.findClient(id)); } //с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto - @GetMapping("/") + @GetMapping(OpenAPI30Configuration.API_PREFIX + "/") + @Secured({UserRole.AsString.ADMIN}) public List getClients() { return gameClientService.findAllClients().stream() .map(ClientDTO::new) .toList(); } - @PostMapping("/") + @PostMapping(OpenAPI30Configuration.API_PREFIX + "/") public ClientDTO createClient(@RequestParam("login") String login, @RequestParam("password") String password, @RequestParam("email") String email, @@ -44,7 +70,8 @@ public class GameClientController { return new ClientDTO(gameClientService.addClient(login, email, password, balance, password, UserRole.USER)); } - @PutMapping("/{id}") + @PutMapping(OpenAPI30Configuration.API_PREFIX + "/{id}") + @Secured({UserRole.AsString.USER}) public ClientDTO updateClient(@PathVariable Long id, @RequestParam("login") String login, @RequestParam("password") String password, @@ -54,7 +81,8 @@ public class GameClientController { return new ClientDTO(gameClientService.updateClient(id, login, password, email, balance, tankService.findTank(tankId))); } - @DeleteMapping("/{id}") + @DeleteMapping(OpenAPI30Configuration.API_PREFIX + "/{id}") + @Secured({UserRole.AsString.USER}) public ClientDTO deleteClient(@PathVariable Long id) { return new ClientDTO(gameClientService.deleteClient(id)); } diff --git a/spring_online_calculator/src/main/java/premium_store/service/GameClientService.java b/spring_online_calculator/src/main/java/premium_store/service/GameClientService.java index 7746559..72c9997 100644 --- a/spring_online_calculator/src/main/java/premium_store/service/GameClientService.java +++ b/spring_online_calculator/src/main/java/premium_store/service/GameClientService.java @@ -10,6 +10,8 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; +import premium_store.configuration.jwt.JwtException; +import premium_store.configuration.jwt.JwtProvider; import premium_store.controller.DTO.ClientDTO; import premium_store.controller.DTO.SupportClientDTO; import premium_store.controller.DTO.UserSignupDto; @@ -33,15 +35,18 @@ public class GameClientService implements UserDetailsService { private final TankRepository tankRepository; private final ValidatorUtil validatorUtil; private final PasswordEncoder passwordEncoder; + private final JwtProvider jwtProvider; public GameClientService(GameClientRepository gameClientRepository, TankRepository tankRepository, ValidatorUtil validatorUtil, - PasswordEncoder passwordEncoder) { + PasswordEncoder passwordEncoder, + JwtProvider jwtProvider) { this.gameClientRepository = gameClientRepository; this.tankRepository = tankRepository; this.validatorUtil = validatorUtil; this.passwordEncoder = passwordEncoder; + this.jwtProvider = jwtProvider; } @Transactional @@ -62,11 +67,6 @@ public class GameClientService implements UserDetailsService { return gameClientRepository.save(gameClient); } - @Transactional - public GameClient addClient(String login, String email, String password, Integer ballance, String passwordConfirm) { - return addClient(login, email, password, ballance, passwordConfirm, UserRole.USER); - } - @Transactional(readOnly = true) public GameClient findClient(Long id) { final Optional client = gameClientRepository.findById(id); @@ -158,6 +158,31 @@ public class GameClientService implements UserDetailsService { gameClientRepository.deleteAll(); } + public String loginAndGetToken(ClientDTO userDto) { + final GameClient user = findByLogin(userDto.getLogin()); + + if (user == null) { + throw new ClientNotFoundException(userDto.getLogin()); + } + + if (!passwordEncoder.matches(userDto.getPassword(), user.getPassword())) { + throw new ValidationException("Incorrect password"); + } + + return jwtProvider.generateToken(user.getLogin()); + } + + public UserDetails loadUserByToken(String token) throws UsernameNotFoundException { + if (!jwtProvider.isTokenValid(token)) { + throw new JwtException("Bad token"); + } + + final String userLogin = jwtProvider.getLoginFromToken(token) + .orElseThrow(() -> new JwtException("Token is not contain Login")); + + return loadUserByUsername(userLogin); + } + //метод загрузки пользователя по его логину @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { diff --git a/spring_online_calculator/src/main/java/premium_store/service/exception/ClientNotFoundException.java b/spring_online_calculator/src/main/java/premium_store/service/exception/ClientNotFoundException.java index 743e78f..7914489 100644 --- a/spring_online_calculator/src/main/java/premium_store/service/exception/ClientNotFoundException.java +++ b/spring_online_calculator/src/main/java/premium_store/service/exception/ClientNotFoundException.java @@ -4,4 +4,8 @@ public class ClientNotFoundException extends RuntimeException { public ClientNotFoundException(Long id) { super(String.format("Client with id [%s] is not found", id)); } + + public ClientNotFoundException(String login) { + super(String.format("User not found '%s'", login)); + } } \ No newline at end of file diff --git a/spring_online_calculator/src/main/java/premium_store/service/exception/UserExistsException.java b/spring_online_calculator/src/main/java/premium_store/service/exception/UserExistsException.java new file mode 100644 index 0000000..4ac2b8e --- /dev/null +++ b/spring_online_calculator/src/main/java/premium_store/service/exception/UserExistsException.java @@ -0,0 +1,7 @@ +package premium_store.service.exception; + +public class UserExistsException extends RuntimeException { + public UserExistsException(String login) { + super(String.format("User '%s' already exists", login)); + } +} \ No newline at end of file