diff --git a/api/src/main/java/com/wbrawner/budgetserver/budget/BudgetController.java b/api/src/main/java/com/wbrawner/budgetserver/budget/BudgetController.java index 8028fbb..c80480d 100644 --- a/api/src/main/java/com/wbrawner/budgetserver/budget/BudgetController.java +++ b/api/src/main/java/com/wbrawner/budgetserver/budget/BudgetController.java @@ -9,7 +9,6 @@ import com.wbrawner.budgetserver.user.UserRepository; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.Authorization; -import org.hibernate.Hibernate; import org.springframework.data.domain.PageRequest; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -160,6 +159,10 @@ public class BudgetController { return ResponseEntity.notFound().build(); } + if (userPermission.getPermission().isNotAtLeast(Permission.MANAGE)) { + return ResponseEntity.status(403).build(); + } + var budget = userPermission.getBudget(); if (budget == null) { return ResponseEntity.notFound().build(); @@ -173,30 +176,48 @@ public class BudgetController { budget.setDescription(request.description); } + var users = new ArrayList(); if (!request.getUsers().isEmpty()) { request.getUsers().forEach(userPermissionRequest -> { - var requestedUser = userRepository.findById(userPermissionRequest.getUser()).orElse(null); - if (requestedUser != null) { - userPermissionsRepository.save(new UserPermission(budget, requestedUser, userPermissionRequest.getPermission())); - } + userRepository.findById(userPermissionRequest.getUser()).ifPresent(requestedUser -> + users.add(userPermissionsRepository.save( + new UserPermission( + budget, + requestedUser, + userPermissionRequest.getPermission() + ) + )) + ); }); + } else { + users.addAll(userPermissionsRepository.findAllByBudget(budget, null)); } - userPermissionsRepository.findAllByUserAndBudget(getCurrentUser() !!, budget, null) - return ResponseEntity.ok(BudgetResponse(budgetRepository.save(budget), users)) + + return ResponseEntity.ok(new BudgetResponse(budgetRepository.save(budget), users)); } @DeleteMapping(value = "/{id}", produces = {MediaType.TEXT_PLAIN_VALUE}) @ApiOperation(value = "deleteBudget", nickname = "deleteBudget", tags = {"Budgets"}) - open fun + public ResponseEntity deleteBudget(@PathVariable long id) { + var user = getCurrentUser(); + if (user == null) { + return ResponseEntity.status(401).build(); + } - deleteBudget(@PathVariable id:Long):ResponseEntity + var userPermission = userPermissionsRepository.findAllByUserAndBudget_Id(user, id, null).get(0); + if (userPermission == null) { + return ResponseEntity.notFound().build(); + } - { - val budget = userPermissionsRepository.findAllByUserAndBudget_Id(getCurrentUser() !!, id, null) - .firstOrNull() - ?.budget - ?:return ResponseEntity.notFound().build() - budgetRepository.delete(budget) - return ResponseEntity.ok().build() + if (userPermission.getPermission().isNotAtLeast(Permission.MANAGE)) { + return ResponseEntity.status(403).build(); + } + + var budget = userPermission.getBudget(); + if (budget == null) { + return ResponseEntity.notFound().build(); + } + budgetRepository.delete(budget); + return ResponseEntity.noContent().build(); } } diff --git a/api/src/main/java/com/wbrawner/budgetserver/permission/Permission.java b/api/src/main/java/com/wbrawner/budgetserver/permission/Permission.java new file mode 100644 index 0000000..3107965 --- /dev/null +++ b/api/src/main/java/com/wbrawner/budgetserver/permission/Permission.java @@ -0,0 +1,24 @@ +package com.wbrawner.budgetserver.permission; + +public enum Permission { + /** + * The user can read the content but cannot make any modifications. + */ + READ, + /** + * The user can read and write the content but cannot make any modifications to the container of the content. + */ + WRITE, + /** + * The user can read and write the content, and make modifications to the container of the content including things like name, description, and other users' permissions (with the exception of the owner user, whose role can never be removed by a user with only MANAGE permissions). + */ + MANAGE, + /** + * The user has complete control over the resource. There can only be a single owner user at any given time. + */ + OWNER; + + public boolean isNotAtLeast(Permission wanted) { + return ordinal() < wanted.ordinal(); + } +} diff --git a/api/src/main/java/com/wbrawner/budgetserver/permission/UserPermission.kt b/api/src/main/java/com/wbrawner/budgetserver/permission/UserPermission.kt index 772dd53..5e8d435 100644 --- a/api/src/main/java/com/wbrawner/budgetserver/permission/UserPermission.kt +++ b/api/src/main/java/com/wbrawner/budgetserver/permission/UserPermission.kt @@ -31,12 +31,6 @@ data class UserPermissionKey( var userId: Long? = null ) : Serializable -enum class Permission { - READ, - WRITE, - OWNER -} - data class UserPermissionResponse( val user: UserResponse, val permission: Permission