Add endpoint to delete payments

This commit is contained in:
2023-05-13 20:19:26 +02:00
parent 890c030109
commit 94fd3a5849
8 changed files with 93 additions and 22 deletions

View File

@@ -8,14 +8,12 @@ import net.kapcake.bankingservice.model.dtos.PaymentFilter;
import net.kapcake.bankingservice.security.UserDetailsImpl;
import net.kapcake.bankingservice.services.AccountService;
import net.kapcake.bankingservice.services.PaymentService;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@@ -35,6 +33,7 @@ public class BankingServiceController {
}
@PostMapping("/payment")
@ResponseStatus(HttpStatus.CREATED)
public PaymentDTO createPayment(@AuthenticationPrincipal UserDetailsImpl authenticatedUser, @RequestBody @Valid PaymentDTO paymentDTO, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
String errorString = getErrorString(bindingResult);
@@ -52,6 +51,11 @@ public class BankingServiceController {
return paymentService.getPaymentsForUser(authenticatedUser, paymentFilter);
}
@DeleteMapping("/payment/{id}")
public void deletePayment(@AuthenticationPrincipal UserDetailsImpl authenticatedUser, @PathVariable("id") Long id) {
paymentService.deletePayment(authenticatedUser, id);
}
private static String getErrorString(BindingResult bindingResult) {
StringBuilder builder = new StringBuilder("[");
List<ObjectError> allErrors = bindingResult.getAllErrors();

View File

@@ -1,5 +1,7 @@
package net.kapcake.bankingservice.controllers;
import net.kapcake.bankingservice.exceptions.AccessDeniedException;
import net.kapcake.bankingservice.exceptions.ResourceNotFoundException;
import net.kapcake.bankingservice.exceptions.ValidationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -9,11 +11,22 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class BankingServiceExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ValidationException.class})
protected ResponseEntity<Object> handlePaymentValidationException(ValidationException exception, WebRequest request) {
protected ResponseEntity<Object> handleValidationException(ValidationException exception, WebRequest request) {
return this.handleExceptionInternal(exception, exception.getMessage(),
new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
@ExceptionHandler({ResourceNotFoundException.class})
protected ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException exception, WebRequest request) {
return this.handleExceptionInternal(exception, exception.getMessage(),
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}
@ExceptionHandler({AccessDeniedException.class})
protected ResponseEntity<Object> handleAccessDeniedException(AccessDeniedException exception, WebRequest request) {
return this.handleExceptionInternal(exception, exception.getMessage(),
new HttpHeaders(), HttpStatus.FORBIDDEN, request);
}
}

View File

@@ -0,0 +1,7 @@
package net.kapcake.bankingservice.exceptions;
public class AccessDeniedException extends RuntimeException {
public AccessDeniedException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,7 @@
package net.kapcake.bankingservice.exceptions;
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}

View File

@@ -1,10 +1,7 @@
package net.kapcake.bankingservice.exceptions;
public class ValidationException extends IllegalArgumentException {
public class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
public ValidationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -16,7 +16,7 @@ public class User {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;

View File

@@ -1,10 +1,10 @@
package net.kapcake.bankingservice.services;
import net.kapcake.bankingservice.converters.PaymentConverter;
import net.kapcake.bankingservice.model.domain.Balance;
import net.kapcake.bankingservice.model.domain.BalanceType;
import net.kapcake.bankingservice.model.domain.BankAccount;
import net.kapcake.bankingservice.model.domain.Payment;
import net.kapcake.bankingservice.exceptions.AccessDeniedException;
import net.kapcake.bankingservice.exceptions.ResourceNotFoundException;
import net.kapcake.bankingservice.exceptions.ValidationException;
import net.kapcake.bankingservice.model.domain.*;
import net.kapcake.bankingservice.model.dtos.PaymentDTO;
import net.kapcake.bankingservice.model.dtos.PaymentFilter;
import net.kapcake.bankingservice.repositories.BalanceRepository;
@@ -79,7 +79,7 @@ public class PaymentService {
}
public List<PaymentDTO> getPaymentsForUser(UserDetailsImpl authenticatedUser, PaymentFilter paymentFilter) {
List<BankAccount> userBankAccounts = bankAccountRepository.findAllByUsers_username(authenticatedUser.getUsername());
List<BankAccount> userBankAccounts = authenticatedUser.user().getBankAccounts();
List<Payment> userPayments = paymentRepository.findAllByGiverAccountIn(userBankAccounts);
List<Payment> filteredPayments = getFilteredPayments(paymentFilter, userPayments);
@@ -109,4 +109,16 @@ public class PaymentService {
}
return filteredPayments;
}
public void deletePayment(UserDetailsImpl authenticatedUser, Long id) {
List<BankAccount> userBankAccounts = authenticatedUser.user().getBankAccounts();
Payment payment = paymentRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("A payment with the given id does not exist"));
if (userBankAccounts.stream().noneMatch(account -> account.getId().equals(payment.getGiverAccount().getId()))) {
throw new AccessDeniedException("The payment with id [" + id + "] is not owned by the authenticated user");
}
if (PaymentStatus.EXECUTED.equals(payment.getStatus())) {
throw new ValidationException("The payment to be deleted has already been executed");
}
paymentRepository.deleteById(id);
}
}