Reduce duplication of logic in BudgetController

This commit is contained in:
William Brawner 2020-12-29 06:26:38 -07:00
parent e160fd372e
commit 377f2b61f7

View file

@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.wbrawner.budgetserver.Utils.getCurrentUser; import static com.wbrawner.budgetserver.Utils.getCurrentUser;
@ -77,43 +78,18 @@ public class BudgetController {
@GetMapping(value = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE}) @GetMapping(value = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "getBudget", nickname = "getBudget", tags = {"Budgets"}) @ApiOperation(value = "getBudget", nickname = "getBudget", tags = {"Budgets"})
public ResponseEntity<BudgetResponse> getBudget(@PathVariable long id) { public ResponseEntity<BudgetResponse> getBudget(@PathVariable long id) {
var user = getCurrentUser(); return getBudgetWithPermission(id, Permission.READ, (budget) ->
if (user == null) { ResponseEntity.ok(new BudgetResponse(budget, userPermissionsRepository.findAllByBudget(budget, null)))
return ResponseEntity.status(401).build(); );
}
var userPermission = userPermissionsRepository.findByUserAndBudget_Id(user, id).orElse(null);
if (userPermission == null) {
return ResponseEntity.notFound().build();
}
var budget = userPermission.getBudget();
if (budget == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(new BudgetResponse(budget, userPermissionsRepository.findAllByBudget(budget, null)));
} }
@GetMapping(value = "/{id}/balance", produces = {MediaType.APPLICATION_JSON_VALUE}) @GetMapping(value = "/{id}/balance", produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "getBudgetBalance", nickname = "getBudgetBalance", tags = {"Budgets"}) @ApiOperation(value = "getBudgetBalance", nickname = "getBudgetBalance", tags = {"Budgets"})
public ResponseEntity<BudgetBalanceResponse> getBudgetBalance(@PathVariable long id) { public ResponseEntity<BudgetBalanceResponse> getBudgetBalance(@PathVariable long id) {
var user = getCurrentUser(); return getBudgetWithPermission(id, Permission.READ, (budget) -> {
if (user == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
var userPermission = userPermissionsRepository.findByUserAndBudget_Id(user, id).orElse(null);
if (userPermission == null) {
return ResponseEntity.notFound().build();
}
var budget = userPermission.getBudget();
if (budget == null) {
return ResponseEntity.notFound().build();
}
var balance = transactionRepository.sumBalanceByBudgetId(budget.getId(), getFirstOfMonth()); var balance = transactionRepository.sumBalanceByBudgetId(budget.getId(), getFirstOfMonth());
return ResponseEntity.ok(new BudgetBalanceResponse(budget.getId(), balance)); return ResponseEntity.ok(new BudgetBalanceResponse(budget.getId(), balance));
});
} }
@PostMapping(value = "", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE}) @PostMapping(value = "", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
@ -150,25 +126,7 @@ public class BudgetController {
@PutMapping(value = "/{id}", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE}) @PutMapping(value = "/{id}", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "updateBudget", nickname = "updateBudget", tags = {"Budgets"}) @ApiOperation(value = "updateBudget", nickname = "updateBudget", tags = {"Budgets"})
public ResponseEntity<BudgetResponse> updateBudget(@PathVariable long id, @RequestBody BudgetRequest request) { public ResponseEntity<BudgetResponse> updateBudget(@PathVariable long id, @RequestBody BudgetRequest request) {
var user = getCurrentUser(); return getBudgetWithPermission(id, Permission.MANAGE, (budget) -> {
if (user == null) {
return ResponseEntity.status(401).build();
}
var userPermission = userPermissionsRepository.findByUserAndBudget_Id(user, id).orElse(null);
if (userPermission == null) {
return ResponseEntity.notFound().build();
}
if (userPermission.getPermission().isNotAtLeast(Permission.MANAGE)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
var budget = userPermission.getBudget();
if (budget == null) {
return ResponseEntity.notFound().build();
}
if (request.name != null) { if (request.name != null) {
budget.setName(request.name); budget.setName(request.name);
} }
@ -194,30 +152,42 @@ public class BudgetController {
} }
return ResponseEntity.ok(new BudgetResponse(budgetRepository.save(budget), users)); return ResponseEntity.ok(new BudgetResponse(budgetRepository.save(budget), users));
});
} }
@DeleteMapping(value = "/{id}", produces = {MediaType.TEXT_PLAIN_VALUE}) @DeleteMapping(value = "/{id}", produces = {MediaType.TEXT_PLAIN_VALUE})
@ApiOperation(value = "deleteBudget", nickname = "deleteBudget", tags = {"Budgets"}) @ApiOperation(value = "deleteBudget", nickname = "deleteBudget", tags = {"Budgets"})
public ResponseEntity<Void> deleteBudget(@PathVariable long id) { public ResponseEntity<Void> deleteBudget(@PathVariable long id) {
var user = getCurrentUser(); return getBudgetWithPermission(id, Permission.MANAGE, (budget) -> {
if (user == null) { budgetRepository.delete(budget);
return ResponseEntity.status(401).build(); return ResponseEntity.ok().build();
});
} }
var userPermission = userPermissionsRepository.findByUserAndBudget_Id(user, id).orElse(null); private <T> ResponseEntity<T> getBudgetWithPermission(
long budgetId,
Permission permission,
Function<Budget, ResponseEntity<T>> callback
) {
var user = getCurrentUser();
if (user == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
var userPermission = userPermissionsRepository.findByUserAndBudget_Id(user, budgetId).orElse(null);
if (userPermission == null) { if (userPermission == null) {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} }
if (userPermission.getPermission().isNotAtLeast(Permission.MANAGE)) { if (userPermission.getPermission().isNotAtLeast(permission)) {
return ResponseEntity.status(403).build(); return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
} }
var budget = userPermission.getBudget(); var budget = userPermission.getBudget();
if (budget == null) { if (budget == null) {
return ResponseEntity.notFound().build(); return ResponseEntity.notFound().build();
} }
budgetRepository.delete(budget);
return ResponseEntity.ok().build(); return callback.apply(budget);
} }
} }