Compare commits
4 commits
ec8f49ea00
...
94a6f234c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94a6f234c5 | ||
|
|
a4bdcda165 | ||
|
|
e86ab4f209 | ||
|
|
faf9e0f7af |
18 changed files with 181 additions and 15 deletions
|
|
@ -43,16 +43,16 @@ dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
implementation("org.flywaydb:flyway-core")
|
implementation("org.flywaydb:flyway-core")
|
||||||
implementation("org.flywaydb:flyway-database-postgresql:11.10.0")
|
implementation("org.flywaydb:flyway-database-postgresql:11.10.0")
|
||||||
implementation("org.mapstruct:mapstruct:1.6.3")
|
|
||||||
implementation("org.postgresql:postgresql")
|
implementation("org.postgresql:postgresql")
|
||||||
implementation("org.apache.logging.log4j:log4j-api:2.22.1")
|
implementation("org.apache.logging.log4j:log4j-api:2.22.1")
|
||||||
implementation("org.apache.logging.log4j:log4j-core:2.22.1")
|
implementation("org.apache.logging.log4j:log4j-core:2.22.1")
|
||||||
implementation("org.slf4j:slf4j-api:2.0.13")
|
implementation("org.slf4j:slf4j-api:2.0.13")
|
||||||
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6")
|
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6")
|
||||||
runtimeOnly("org.apache.logging.log4j:log4j-slf4j-impl:2.22.1")
|
runtimeOnly("org.apache.logging.log4j:log4j-slf4j-impl:2.22.1")
|
||||||
annotationProcessor("org.mapstruct:mapstruct-processor:1.6.3")
|
|
||||||
compileOnly("org.projectlombok:lombok")
|
compileOnly("org.projectlombok:lombok")
|
||||||
annotationProcessor("org.projectlombok:lombok")
|
annotationProcessor("org.projectlombok:lombok")
|
||||||
|
annotationProcessor("org.mapstruct:mapstruct-processor:1.6.3")
|
||||||
|
implementation("org.mapstruct:mapstruct:1.6.3")
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
testImplementation("org.springframework.security:spring-security-test")
|
testImplementation("org.springframework.security:spring-security-test")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ package ru.team58.profileservice.controller;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import ru.team58.profileservice.controller.exceptions.BadRequestException;
|
||||||
|
import ru.team58.profileservice.controller.exceptions.UnauthorizedException;
|
||||||
|
import ru.team58.profileservice.controller.exceptions.UserNotFoundException;
|
||||||
import ru.team58.profileservice.controller.schemes.CreateUserRequest;
|
import ru.team58.profileservice.controller.schemes.CreateUserRequest;
|
||||||
import ru.team58.profileservice.controller.schemes.GetUserResponse;
|
import ru.team58.profileservice.controller.schemes.GetUserResponse;
|
||||||
import ru.team58.profileservice.controller.schemes.UpdateUserRequest;
|
import ru.team58.profileservice.controller.schemes.UpdateUserRequest;
|
||||||
|
|
@ -9,6 +12,7 @@ import ru.team58.profileservice.controller.schemes.UserResponse;
|
||||||
import ru.team58.profileservice.mapper.UserMapper;
|
import ru.team58.profileservice.mapper.UserMapper;
|
||||||
import ru.team58.profileservice.service.UserDTO;
|
import ru.team58.profileservice.service.UserDTO;
|
||||||
import ru.team58.profileservice.service.UserService;
|
import ru.team58.profileservice.service.UserService;
|
||||||
|
import ru.team58.profileservice.service.exceptions.UserAlreadyExistsException;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -20,33 +24,88 @@ public class UserController {
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public UserResponse getMe(Principal principal) {
|
public UserResponse getMe(Principal principal) {
|
||||||
|
if (principal == null) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
userService.getByUsername(principal.getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
return UserMapper.INSTANCE.toUserResponse(userService.getByUsername(principal.getName()));
|
return UserMapper.INSTANCE.toUserResponse(userService.getByUsername(principal.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/")
|
@PutMapping("/")
|
||||||
public void updateMe(Principal principal, @RequestBody UpdateUserRequest request) {
|
public void updateMe(Principal principal, @RequestBody UpdateUserRequest request) {
|
||||||
|
if (principal == null) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
userService.getByUsername(principal.getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
userService.updateUser(UserMapper.INSTANCE.toUserDTO(request));
|
userService.updateUser(UserMapper.INSTANCE.toUserDTO(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/")
|
@DeleteMapping("/")
|
||||||
public void deleteMe(Principal principal) {
|
public void deleteMe(Principal principal) {
|
||||||
UserDTO user = userService.getByUsername(principal.getName());
|
if (principal == null) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDTO user;
|
||||||
|
|
||||||
|
try {
|
||||||
|
user = userService.getByUsername(principal.getName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
userService.deleteUser(user.getId());
|
userService.deleteUser(user.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/")
|
@PostMapping("/")
|
||||||
public void createMe(@RequestBody CreateUserRequest request) {
|
public void createMe(@RequestBody CreateUserRequest request) {
|
||||||
userService.createUser(UserMapper.INSTANCE.toUserDTO(request));
|
UserDTO user = UserMapper.INSTANCE.toUserDTO(request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
userService.createUser(user);
|
||||||
|
} catch (UserAlreadyExistsException ex) {
|
||||||
|
throw new ru.team58.profileservice.controller.exceptions.UserAlreadyExistsException();
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
throw new BadRequestException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public GetUserResponse getUser(@PathVariable UUID id) {
|
public GetUserResponse getUser(@PathVariable UUID id) {
|
||||||
UserDTO user = userService.getById(id);
|
UserDTO user;
|
||||||
|
|
||||||
|
try {
|
||||||
|
user = userService.getById(id);
|
||||||
|
} catch (ru.team58.profileservice.service.exceptions.UserNotFoundException ex) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
return UserMapper.INSTANCE.toGetUserResponse(user);
|
return UserMapper.INSTANCE.toGetUserResponse(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public void deleteUser(@PathVariable UUID id) {
|
public void deleteUser(Principal principal, @PathVariable UUID id) {
|
||||||
userService.deleteUser(id);
|
// TODO: Add checking role
|
||||||
|
if (principal == null) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
userService.deleteUser(id);
|
||||||
|
} catch (ru.team58.profileservice.service.exceptions.UserNotFoundException ex) {
|
||||||
|
throw new UserNotFoundException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.team58.profileservice.controller.advice;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ErrorDetails {
|
||||||
|
private String message;
|
||||||
|
private int status;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package ru.team58.profileservice.controller.advice;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import ru.team58.profileservice.controller.exceptions.*;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class UserControllerExceptionHandler {
|
||||||
|
@ExceptionHandler(UserNotFoundException.class)
|
||||||
|
public ResponseEntity<ErrorDetails> handleUserNotFoundException(UserNotFoundException ex) {
|
||||||
|
ErrorDetails errorDetails = new ErrorDetails("User not found", HttpStatus.FORBIDDEN.value());
|
||||||
|
return new ResponseEntity<>(errorDetails, HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(UserAlreadyExistsException.class)
|
||||||
|
public ResponseEntity<ErrorDetails> handleUserAlreadyExistsException(UserAlreadyExistsException ex) {
|
||||||
|
ErrorDetails errorDetails = new ErrorDetails("User already exists", HttpStatus.BAD_REQUEST.value());
|
||||||
|
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(BadRequestException.class)
|
||||||
|
public ResponseEntity<ErrorDetails> handleBadRequestException(BadRequestException ex) {
|
||||||
|
ErrorDetails errorDetails = new ErrorDetails("Bad Request", HttpStatus.BAD_REQUEST.value());
|
||||||
|
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(ForbiddenException.class)
|
||||||
|
public ResponseEntity<ErrorDetails> handleForbiddenException(ForbiddenException ex) {
|
||||||
|
ErrorDetails errorDetails = new ErrorDetails("Forbidden", HttpStatus.FORBIDDEN.value());
|
||||||
|
return new ResponseEntity<>(errorDetails, HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(UnauthorizedException.class)
|
||||||
|
public ResponseEntity<ErrorDetails> handleUnauthorizedException(UnauthorizedException ex) {
|
||||||
|
ErrorDetails errorDetails = new ErrorDetails("Unauthorized", HttpStatus.UNAUTHORIZED.value());
|
||||||
|
return new ResponseEntity<>(errorDetails, HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package ru.team58.profileservice.controller.exceptions;
|
||||||
|
|
||||||
|
public class BadRequestException extends RuntimeException {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package ru.team58.profileservice.controller.exceptions;
|
||||||
|
|
||||||
|
public class ForbiddenException extends RuntimeException {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package ru.team58.profileservice.controller.exceptions;
|
||||||
|
|
||||||
|
public class UnauthorizedException extends RuntimeException {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package ru.team58.profileservice.controller.exceptions;
|
||||||
|
|
||||||
|
public class UserAlreadyExistsException extends BadRequestException{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package ru.team58.profileservice.controller.exceptions;
|
||||||
|
|
||||||
|
public class UserNotFoundException extends ForbiddenException {
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
package ru.team58.profileservice.controller.schemes;
|
package ru.team58.profileservice.controller.schemes;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
public class CreateUserRequest {
|
public class CreateUserRequest {
|
||||||
String username;
|
String username;
|
||||||
String firstName;
|
String firstName;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
package ru.team58.profileservice.controller.schemes;
|
package ru.team58.profileservice.controller.schemes;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
public class GetUserResponse {
|
public class GetUserResponse {
|
||||||
String username;
|
String username;
|
||||||
String firstName;
|
String firstName;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
package ru.team58.profileservice.controller.schemes;
|
package ru.team58.profileservice.controller.schemes;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
public class UpdateUserRequest {
|
public class UpdateUserRequest {
|
||||||
UUID id;
|
UUID id;
|
||||||
String username;
|
String username;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
package ru.team58.profileservice.controller.schemes;
|
package ru.team58.profileservice.controller.schemes;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
public class UserResponse {
|
public class UserResponse {
|
||||||
UUID id;
|
UUID id;
|
||||||
String username;
|
String username;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package ru.team58.profileservice.mapper;
|
package ru.team58.profileservice.mapper;
|
||||||
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
import ru.team58.profileservice.controller.schemes.CreateUserRequest;
|
import ru.team58.profileservice.controller.schemes.CreateUserRequest;
|
||||||
import ru.team58.profileservice.controller.schemes.GetUserResponse;
|
import ru.team58.profileservice.controller.schemes.GetUserResponse;
|
||||||
|
|
@ -9,12 +10,13 @@ import ru.team58.profileservice.controller.schemes.UserResponse;
|
||||||
import ru.team58.profileservice.persistence.entity.UserEntity;
|
import ru.team58.profileservice.persistence.entity.UserEntity;
|
||||||
import ru.team58.profileservice.service.UserDTO;
|
import ru.team58.profileservice.service.UserDTO;
|
||||||
|
|
||||||
@Mapper
|
@Mapper(componentModel = "spring")
|
||||||
public interface UserMapper {
|
public interface UserMapper {
|
||||||
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
|
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
|
||||||
|
|
||||||
UserDTO toUserDTO(UserEntity entity);
|
UserDTO toUserDTO(UserEntity entity);
|
||||||
UserDTO toUserDTO(UpdateUserRequest request);
|
UserDTO toUserDTO(UpdateUserRequest request);
|
||||||
|
@Mapping(target = "id", ignore = true)
|
||||||
UserDTO toUserDTO(CreateUserRequest request);
|
UserDTO toUserDTO(CreateUserRequest request);
|
||||||
|
|
||||||
UserEntity toUserEntity(UserDTO dto);
|
UserEntity toUserEntity(UserDTO dto);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package ru.team58.profileservice.persistence.entity;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import ru.team58.profileservice.service.UserDTO;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -17,17 +16,17 @@ public class UserEntity {
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "id", nullable = false)
|
@Column(name = "id", nullable = false)
|
||||||
@GeneratedValue(strategy = GenerationType.UUID)
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
UUID id;
|
private UUID id;
|
||||||
|
|
||||||
@Column(name = "username", nullable = false)
|
@Column(name = "username", nullable = false)
|
||||||
String username;
|
private String username;
|
||||||
|
|
||||||
@Column(name = "firstName", nullable = false)
|
@Column(name = "firstName", nullable = false)
|
||||||
String firstName;
|
private String firstName;
|
||||||
|
|
||||||
@Column(name = "lastName", nullable = false)
|
@Column(name = "lastName", nullable = false)
|
||||||
String lastName;
|
private String lastName;
|
||||||
|
|
||||||
@Column(name = "email", nullable = false)
|
@Column(name = "email", nullable = false)
|
||||||
String email;
|
private String email;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ spring.datasource.url=jdbc:postgresql://localhost:5432/userdb
|
||||||
spring.datasource.username=userdb
|
spring.datasource.username=userdb
|
||||||
spring.datasource.password=1205
|
spring.datasource.password=1205
|
||||||
|
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=validate
|
||||||
|
|
||||||
## Flyway
|
## Flyway
|
||||||
spring.flyway.enabled=true
|
spring.flyway.enabled=true
|
||||||
|
|
|
||||||
5
src/main/resources/db/migration/V1_0_1__AlterUser.sql
Normal file
5
src/main/resources/db/migration/V1_0_1__AlterUser.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE "users"
|
||||||
|
ALTER COLUMN username SET NOT NULL,
|
||||||
|
ALTER COLUMN "firstName" SET NOT NULL,
|
||||||
|
ALTER COLUMN "lastName" SET NOT NULL,
|
||||||
|
ALTER COLUMN "email" SET NOT NULL;
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE "users"
|
||||||
|
DROP COLUMN "hashed_password";
|
||||||
Loading…
Add table
Add a link
Reference in a new issue