mirror of
https://github.com/usatiuk/y.git
synced 2025-10-29 02:37:49 +01:00
slightly better exception handling
This commit is contained in:
@@ -37,6 +37,7 @@ dependencies {
|
|||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
// For TestRestTemplate as default client can't handle UNAUTHORIZED response
|
// For TestRestTemplate as default client can't handle UNAUTHORIZED response
|
||||||
testImplementation 'org.apache.httpcomponents.client5:httpclient5:5.3'
|
testImplementation 'org.apache.httpcomponents.client5:httpclient5:5.3'
|
||||||
|
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.2.0'
|
||||||
|
|
||||||
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
|
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
|
||||||
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
|
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.usatiuk.tjv.y.server;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.ErrorTo;
|
||||||
|
import io.swagger.v3.core.converter.AnnotatedType;
|
||||||
|
import io.swagger.v3.core.converter.ModelConverters;
|
||||||
|
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
|
||||||
|
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
||||||
|
import io.swagger.v3.oas.annotations.info.Info;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
||||||
|
import io.swagger.v3.oas.models.media.Content;
|
||||||
|
import io.swagger.v3.oas.models.media.MediaType;
|
||||||
|
import io.swagger.v3.oas.models.media.Schema;
|
||||||
|
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||||
|
import org.springdoc.core.customizers.OpenApiCustomizer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@OpenAPIDefinition(info = @Info(title = "Y API", version = "v1"), security = {@SecurityRequirement(name = "bearerAuth")})
|
||||||
|
@SecurityScheme(
|
||||||
|
name = "bearerAuth",
|
||||||
|
type = SecuritySchemeType.HTTP,
|
||||||
|
bearerFormat = "JWT",
|
||||||
|
scheme = "bearer"
|
||||||
|
)
|
||||||
|
public class OpenAPIConfiguration {
|
||||||
|
private ApiResponse createApiResponse(String message, Schema schema) {
|
||||||
|
MediaType mediaType = new MediaType();
|
||||||
|
mediaType.schema(schema);
|
||||||
|
return new ApiResponse().description(message)
|
||||||
|
.content(new Content().addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, mediaType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OpenApiCustomizer customizer() {
|
||||||
|
return openApi -> {
|
||||||
|
Schema errorResponseSchema = ModelConverters.getInstance()
|
||||||
|
.resolveAsResolvedSchema(new AnnotatedType(ErrorTo.class)).schema;
|
||||||
|
openApi.getPaths().values().forEach(pathItem -> pathItem.readOperations().forEach(operation -> {
|
||||||
|
var apiResponses = operation.getResponses();
|
||||||
|
apiResponses.addApiResponse("500", createApiResponse("Server Error", errorResponseSchema));
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
package com.usatiuk.tjv.y.server.controller;
|
package com.usatiuk.tjv.y.server.controller;
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.dto.ErrorTo;
|
import com.usatiuk.tjv.y.server.dto.ErrorTo;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.BadInputException;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.ConflictException;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
@@ -39,7 +43,6 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ExceptionHandler(AuthenticationException.class)
|
@ExceptionHandler(AuthenticationException.class)
|
||||||
protected ResponseEntity<Object> handleAuthenticationException(AuthenticationException ex, WebRequest request) {
|
protected ResponseEntity<Object> handleAuthenticationException(AuthenticationException ex, WebRequest request) {
|
||||||
return handleExceptionInternal(ex,
|
return handleExceptionInternal(ex,
|
||||||
@@ -61,6 +64,35 @@ public class ApiExceptionHandler extends ResponseEntityExceptionHandler {
|
|||||||
new HttpHeaders(), HttpStatus.UNAUTHORIZED, request);
|
new HttpHeaders(), HttpStatus.UNAUTHORIZED, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(BadInputException.class)
|
||||||
|
protected ResponseEntity<Object> handleBadInputException(BadInputException ex, WebRequest request) {
|
||||||
|
return handleExceptionInternal(ex,
|
||||||
|
new ErrorTo(List.of(ex.getMessage()), HttpStatus.BAD_REQUEST.value()),
|
||||||
|
new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(ConflictException.class)
|
||||||
|
protected ResponseEntity<Object> handleConflictException(ConflictException ex, WebRequest request) {
|
||||||
|
return handleExceptionInternal(ex,
|
||||||
|
new ErrorTo(List.of(ex.getMessage()), HttpStatus.CONFLICT.value()),
|
||||||
|
new HttpHeaders(), HttpStatus.CONFLICT, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(NotFoundException.class)
|
||||||
|
protected ResponseEntity<Object> handleNotFoundException(NotFoundException ex, WebRequest request) {
|
||||||
|
return handleExceptionInternal(ex,
|
||||||
|
new ErrorTo(List.of(ex.getMessage()), HttpStatus.NOT_FOUND.value()),
|
||||||
|
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(EntityNotFoundException.class)
|
||||||
|
protected ResponseEntity<Object> handleEntityNotFoundException(EntityNotFoundException ex, WebRequest request) {
|
||||||
|
return handleExceptionInternal(ex,
|
||||||
|
new ErrorTo(List.of(ex.getMessage()), HttpStatus.NOT_FOUND.value()),
|
||||||
|
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ExceptionHandler(ResponseStatusException.class)
|
@ExceptionHandler(ResponseStatusException.class)
|
||||||
protected ResponseEntity<Object> handleResponseStatusException(ResponseStatusException ex, WebRequest request) {
|
protected ResponseEntity<Object> handleResponseStatusException(ResponseStatusException ex, WebRequest request) {
|
||||||
return handleExceptionInternal(ex,
|
return handleExceptionInternal(ex,
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
||||||
import com.usatiuk.tjv.y.server.service.PersonService;
|
import com.usatiuk.tjv.y.server.service.PersonService;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
import com.usatiuk.tjv.y.server.service.exceptions.ConflictException;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -22,22 +23,23 @@ public class PersonController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public PersonTo signup(@RequestBody PersonCreateTo signupRequest) throws UserAlreadyExistsException {
|
@SecurityRequirements(value = {})
|
||||||
|
public PersonTo signup(@RequestBody PersonCreateTo signupRequest) throws ConflictException {
|
||||||
return personService.signup(signupRequest);
|
return personService.signup(signupRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-username/{username}")
|
@GetMapping(path = "/by-username/{username}")
|
||||||
public PersonTo getByUsername(@PathVariable String username) throws UserNotFoundException {
|
public PersonTo getByUsername(@PathVariable String username) throws NotFoundException {
|
||||||
return personService.readByUsername(username);
|
return personService.readByUsername(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-uuid/{uuid}")
|
@GetMapping(path = "/by-uuid/{uuid}")
|
||||||
public PersonTo getByUuid(@PathVariable String uuid) throws UserNotFoundException {
|
public PersonTo getByUuid(@PathVariable String uuid) throws NotFoundException {
|
||||||
return personService.readByUuid(uuid);
|
return personService.readByUuid(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/self")
|
@GetMapping(path = "/self")
|
||||||
public PersonTo getSelf(Authentication authentication) throws UserNotFoundException {
|
public PersonTo getSelf(Authentication authentication) throws NotFoundException {
|
||||||
return personService.readSelf(authentication);
|
return personService.readSelf(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,23 +56,23 @@ public class PersonController {
|
|||||||
|
|
||||||
@DeleteMapping(path = "/by-uuid/{uuid}")
|
@DeleteMapping(path = "/by-uuid/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void deleteByUuid(@PathVariable String uuid) throws UserNotFoundException {
|
public void deleteByUuid(@PathVariable String uuid) throws NotFoundException {
|
||||||
personService.deleteByUuid(uuid);
|
personService.deleteByUuid(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Collection<PersonTo> getAll() throws UserNotFoundException {
|
public Collection<PersonTo> getAll() throws NotFoundException {
|
||||||
return personService.readAll();
|
return personService.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/followers")
|
@GetMapping(path = "/followers")
|
||||||
public Collection<PersonTo> getFollowers(Authentication authentication) throws UserNotFoundException {
|
public Collection<PersonTo> getFollowers(Authentication authentication) throws NotFoundException {
|
||||||
return personService.getFollowers(authentication);
|
return personService.getFollowers(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/following")
|
@GetMapping(path = "/following")
|
||||||
public Collection<PersonTo> getFollowing(Authentication authentication) throws UserNotFoundException {
|
public Collection<PersonTo> getFollowing(Authentication authentication) throws NotFoundException {
|
||||||
return personService.getFollowing(authentication);
|
return personService.getFollowing(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,25 +83,25 @@ public class PersonController {
|
|||||||
|
|
||||||
@PutMapping(path = "/admins/{uuid}")
|
@PutMapping(path = "/admins/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void addAdmin(@PathVariable String uuid) throws UserNotFoundException {
|
public void addAdmin(@PathVariable String uuid) throws NotFoundException {
|
||||||
personService.addAdmin(uuid);
|
personService.addAdmin(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/admins/{uuid}")
|
@DeleteMapping(path = "/admins/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void deleteAdmin(@PathVariable String uuid) throws UserNotFoundException {
|
public void deleteAdmin(@PathVariable String uuid) throws NotFoundException {
|
||||||
personService.removeAdmin(uuid);
|
personService.removeAdmin(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/following/{uuid}")
|
@PutMapping(path = "/following/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void addFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
public void addFollowing(Authentication authentication, @PathVariable String uuid) throws NotFoundException {
|
||||||
personService.addFollower(authentication, uuid);
|
personService.addFollower(authentication, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/following/{uuid}")
|
@DeleteMapping(path = "/following/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void deleteFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
public void deleteFollowing(Authentication authentication, @PathVariable String uuid) throws NotFoundException {
|
||||||
personService.removeFollower(authentication, uuid);
|
personService.removeFollower(authentication, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
import com.usatiuk.tjv.y.server.service.LoginTokenService;
|
import com.usatiuk.tjv.y.server.service.LoginTokenService;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@@ -19,6 +20,7 @@ public class TokenController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
|
@SecurityRequirements(value = {})
|
||||||
public TokenResponseTo request(@RequestBody TokenRequestTo tokenRequestTo) {
|
public TokenResponseTo request(@RequestBody TokenRequestTo tokenRequestTo) {
|
||||||
return loginTokenService.login(tokenRequestTo);
|
return loginTokenService.login(tokenRequestTo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ public class WebSecurityConfig {
|
|||||||
.authorizeHttpRequests((authorize) -> authorize
|
.authorizeHttpRequests((authorize) -> authorize
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll()
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.POST, "/token")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.POST, "/token")).permitAll()
|
||||||
|
.requestMatchers(mvc.pattern("/swagger-ui*/**")).permitAll()
|
||||||
|
.requestMatchers(mvc.pattern("/v3/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern("/error")).permitAll()
|
.requestMatchers(mvc.pattern("/error")).permitAll()
|
||||||
.anyRequest().hasAuthority(UserRoles.ROLE_USER.name()))
|
.anyRequest().hasAuthority(UserRoles.ROLE_USER.name()))
|
||||||
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Chat;
|
import com.usatiuk.tjv.y.server.entity.Chat;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.BadInputException;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -39,10 +39,10 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
var chat = new Chat();
|
var chat = new Chat();
|
||||||
|
|
||||||
if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName())))
|
if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName())))
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member");
|
throw new BadInputException("Creator of chat must be its member");
|
||||||
|
|
||||||
if (chatCreateTo.memberUuids().length == 1)
|
if (chatCreateTo.memberUuids().length == 1)
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator");
|
throw new BadInputException("Chat must have members other than its creator");
|
||||||
|
|
||||||
chat.setCreator(entityManager.getReference(Person.class, authentication.getName()));
|
chat.setCreator(entityManager.getReference(Person.class, authentication.getName()));
|
||||||
chat.setMembers(Arrays.stream(chatCreateTo.memberUuids()).map(
|
chat.setMembers(Arrays.stream(chatCreateTo.memberUuids()).map(
|
||||||
@@ -56,13 +56,13 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo) {
|
public ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo) {
|
||||||
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
|
|
||||||
if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName())))
|
if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName())))
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member");
|
throw new BadInputException("Creator of chat must be its member");
|
||||||
|
|
||||||
if (chatCreateTo.memberUuids().length <= 1)
|
if (chatCreateTo.memberUuids().length <= 1)
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator");
|
throw new BadInputException("Chat must have members other than its creator");
|
||||||
|
|
||||||
chat.setMembers(new ArrayList<>(Arrays.stream(chatCreateTo.memberUuids()).map(
|
chat.setMembers(new ArrayList<>(Arrays.stream(chatCreateTo.memberUuids()).map(
|
||||||
p -> entityManager.getReference(Person.class, p)
|
p -> entityManager.getReference(Person.class, p)
|
||||||
@@ -80,32 +80,32 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatTo getById(Long id) {
|
public ChatTo getById(Long id) {
|
||||||
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
return chatMapper.makeDto(chat);
|
return chatMapper.makeDto(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Long id) {
|
public void deleteById(Long id) {
|
||||||
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
chatRepository.delete(chat);
|
chatRepository.delete(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PersonTo> getMembers(Long id) {
|
public Collection<PersonTo> getMembers(Long id) {
|
||||||
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
return chat.getMembers().stream().map(personMapper::makeDto).toList();
|
return chat.getMembers().stream().map(personMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMemberOf(String personUuid, Long chatId) {
|
public boolean isMemberOf(String personUuid, Long chatId) {
|
||||||
var chat = chatRepository.findById(chatId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(chatId).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
var userRef = entityManager.getReference(Person.class, personUuid);
|
var userRef = entityManager.getReference(Person.class, personUuid);
|
||||||
return chat.getMembers().contains(userRef);
|
return chat.getMembers().contains(userRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCreatorOf(String personUuid, Long chatId) {
|
public boolean isCreatorOf(String personUuid, Long chatId) {
|
||||||
var chat = chatRepository.findById(chatId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(chatId).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
return Objects.equals(chat.getCreator().getUuid(), personUuid);
|
return Objects.equals(chat.getCreator().getUuid(), personUuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ import com.usatiuk.tjv.y.server.entity.Chat;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Message;
|
import com.usatiuk.tjv.y.server.entity.Message;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.MessageRepository;
|
import com.usatiuk.tjv.y.server.repository.MessageRepository;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -47,7 +46,7 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MessageTo update(Long id, MessageCreateTo msg) {
|
public MessageTo update(Long id, MessageCreateTo msg) {
|
||||||
var message = messageRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
var message = messageRepository.findById(id).orElseThrow(NotFoundException::new);
|
||||||
message.setContents(msg.contents());
|
message.setContents(msg.contents());
|
||||||
messageRepository.save(message);
|
messageRepository.save(message);
|
||||||
return messageMapper.makeDto(message);
|
return messageMapper.makeDto(message);
|
||||||
@@ -67,7 +66,7 @@ public class MessageServiceImpl implements MessageService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthorOf(String userUuid, Long messageId) {
|
public boolean isAuthorOf(String userUuid, Long messageId) {
|
||||||
var msg = messageRepository.findById(messageId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var msg = messageRepository.findById(messageId).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
return Objects.equals(msg.getAuthor().getUuid(), userUuid);
|
return Objects.equals(msg.getAuthor().getUuid(), userUuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,16 @@ import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Chat;
|
import com.usatiuk.tjv.y.server.entity.Chat;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
import com.usatiuk.tjv.y.server.service.exceptions.ConflictException;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
@Override
|
@Override
|
||||||
public PersonTo signup(PersonCreateTo signupRequest) {
|
public PersonTo signup(PersonCreateTo signupRequest) {
|
||||||
if (personRepository.existsByUsername(signupRequest.username()))
|
if (personRepository.existsByUsername(signupRequest.username()))
|
||||||
throw new UserAlreadyExistsException();
|
throw new ConflictException("User already exists with this username");
|
||||||
|
|
||||||
Person toCreate = new Person();
|
Person toCreate = new Person();
|
||||||
|
|
||||||
@@ -64,12 +63,12 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PersonTo readByUsername(String username) {
|
public PersonTo readByUsername(String username) {
|
||||||
return personMapper.makeDto(personRepository.findByUsername(username).orElseThrow(UserNotFoundException::new));
|
return personMapper.makeDto(personRepository.findByUsername(username).orElseThrow(NotFoundException::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PersonTo readByUuid(String uuid) {
|
public PersonTo readByUuid(String uuid) {
|
||||||
return personMapper.makeDto(personRepository.findById(uuid).orElseThrow(UserNotFoundException::new));
|
return personMapper.makeDto(personRepository.findById(uuid).orElseThrow(NotFoundException::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,8 +77,13 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public PersonTo update(Authentication authentication, PersonCreateTo person) {
|
public PersonTo update(Authentication authentication, PersonCreateTo person) {
|
||||||
var found = personRepository.findById(authentication.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
var found = personRepository.findById(authentication.getName()).orElseThrow(NotFoundException::new);
|
||||||
|
|
||||||
|
if (!Objects.equals(found.getUsername(), person.username()) && personRepository.existsByUsername(person.username()))
|
||||||
|
throw new ConflictException("User already exists with this username");
|
||||||
|
|
||||||
found.setUsername(person.username())
|
found.setUsername(person.username())
|
||||||
.setFullName(person.fullName());
|
.setFullName(person.fullName());
|
||||||
if (!person.password().isEmpty()) found.setPassword(passwordEncoder.encode(person.password()));
|
if (!person.password().isEmpty()) found.setPassword(passwordEncoder.encode(person.password()));
|
||||||
@@ -89,7 +93,7 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void deleteByUuid(String uuid) {
|
public void deleteByUuid(String uuid) {
|
||||||
var person = personRepository.findById(uuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
var person = personRepository.findById(uuid).orElseThrow(NotFoundException::new);
|
||||||
for (Chat c : person.getChats()) {
|
for (Chat c : person.getChats()) {
|
||||||
c.getMembers().remove(person);
|
c.getMembers().remove(person);
|
||||||
}
|
}
|
||||||
@@ -114,40 +118,40 @@ public class PersonServiceImpl implements PersonService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PersonTo> getFollowers(Authentication authentication) {
|
public Collection<PersonTo> getFollowers(Authentication authentication) {
|
||||||
return personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new)
|
return personRepository.findById(authentication.getName()).orElseThrow(NotFoundException::new)
|
||||||
.getFollowers().stream().map(personMapper::makeDto).toList();
|
.getFollowers().stream().map(personMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PersonTo> getFollowing(Authentication authentication) {
|
public Collection<PersonTo> getFollowing(Authentication authentication) {
|
||||||
return personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new)
|
return personRepository.findById(authentication.getName()).orElseThrow(NotFoundException::new)
|
||||||
.getFollowing().stream().map(personMapper::makeDto).toList();
|
.getFollowing().stream().map(personMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFollower(Authentication authentication, String followee) {
|
public void addFollower(Authentication authentication, String followee) {
|
||||||
var person = personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new);
|
var person = personRepository.findById(authentication.getName()).orElseThrow(NotFoundException::new);
|
||||||
person.getFollowing().add(entityManager.getReference(Person.class, followee));
|
person.getFollowing().add(entityManager.getReference(Person.class, followee));
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeFollower(Authentication authentication, String followee) {
|
public void removeFollower(Authentication authentication, String followee) {
|
||||||
var person = personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new);
|
var person = personRepository.findById(authentication.getName()).orElseThrow(NotFoundException::new);
|
||||||
person.getFollowing().remove(entityManager.getReference(Person.class, followee));
|
person.getFollowing().remove(entityManager.getReference(Person.class, followee));
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAdmin(String uuid) {
|
public void addAdmin(String uuid) {
|
||||||
var person = personRepository.findById(uuid).orElseThrow(UserNotFoundException::new);
|
var person = personRepository.findById(uuid).orElseThrow(NotFoundException::new);
|
||||||
person.setAdmin(true);
|
person.setAdmin(true);
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAdmin(String uuid) {
|
public void removeAdmin(String uuid) {
|
||||||
var person = personRepository.findById(uuid).orElseThrow(UserNotFoundException::new);
|
var person = personRepository.findById(uuid).orElseThrow(NotFoundException::new);
|
||||||
person.setAdmin(false);
|
person.setAdmin(false);
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import com.usatiuk.tjv.y.server.dto.converters.PostMapper;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.entity.Post;
|
import com.usatiuk.tjv.y.server.entity.Post;
|
||||||
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
||||||
|
import com.usatiuk.tjv.y.server.service.exceptions.NotFoundException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -39,7 +38,7 @@ public class PostServiceImpl implements PostService {
|
|||||||
@Override
|
@Override
|
||||||
public PostTo readById(Long id) {
|
public PostTo readById(Long id) {
|
||||||
return postMapper.makeDto(postRepository.findById(id)
|
return postMapper.makeDto(postRepository.findById(id)
|
||||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Post not found")));
|
.orElseThrow(() -> new NotFoundException("Post not found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,7 +58,7 @@ public class PostServiceImpl implements PostService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PostTo updatePost(Long id, PostCreateTo postCreateTo) {
|
public PostTo updatePost(Long id, PostCreateTo postCreateTo) {
|
||||||
var post = postRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
var post = postRepository.findById(id).orElseThrow(NotFoundException::new);
|
||||||
post.setText(postCreateTo.text());
|
post.setText(postCreateTo.text());
|
||||||
postRepository.save(post);
|
postRepository.save(post);
|
||||||
return postMapper.makeDto(post);
|
return postMapper.makeDto(post);
|
||||||
@@ -79,7 +78,7 @@ public class PostServiceImpl implements PostService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthorOf(String userUuid, Long postId) {
|
public boolean isAuthorOf(String userUuid, Long postId) {
|
||||||
var p = postRepository.findById(postId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var p = postRepository.findById(postId).orElseThrow(() -> new NotFoundException("Chat not found"));
|
||||||
return Objects.equals(p.getAuthor().getUuid(), userUuid);
|
return Objects.equals(p.getAuthor().getUuid(), userUuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.service.exceptions;
|
||||||
|
|
||||||
|
public class BadInputException extends RuntimeException {
|
||||||
|
public BadInputException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.service.exceptions;
|
||||||
|
|
||||||
|
public class ConflictException extends RuntimeException {
|
||||||
|
public ConflictException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.service.exceptions;
|
||||||
|
|
||||||
|
public class NotFoundException extends RuntimeException {
|
||||||
|
public NotFoundException() {
|
||||||
|
super("Requested data not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.service.exceptions;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
|
|
||||||
@ResponseStatus(HttpStatus.CONFLICT)
|
|
||||||
public class UserAlreadyExistsException extends RuntimeException {
|
|
||||||
public UserAlreadyExistsException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.service.exceptions;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
|
|
||||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
|
||||||
public class UserNotFoundException extends RuntimeException {
|
|
||||||
public UserNotFoundException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user