From 9eb9483162b2d7495e956205b6442f237a6e3bf4 Mon Sep 17 00:00:00 2001 From: Cedric Hornberger Date: Wed, 8 Jul 2026 09:15:23 +0200 Subject: [PATCH] fix: validate splitPercentage bounds and cover default-split auth --- .../model/ExpenseChangeRequest.java | 5 +++++ .../app/xpensely_server/model/ExpenseInput.java | 5 +++++ .../controller/ExpenseListControllerTest.java | 15 +++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java index 1414a03..a6db39c 100644 --- a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java +++ b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseChangeRequest.java @@ -3,6 +3,8 @@ package de.zendric.app.xpensely_server.model; import java.time.LocalDate; import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -34,6 +36,9 @@ public class ExpenseChangeRequest { private Double otherPersonAmount; private SplitMode splitMode; + + @Min(0) + @Max(100) private Integer splitPercentage; @NotNull(message = "Date is required") diff --git a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java index 00531fa..fedadb4 100644 --- a/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java +++ b/src/main/java/de/zendric/app/xpensely_server/model/ExpenseInput.java @@ -3,6 +3,8 @@ package de.zendric.app.xpensely_server.model; import java.time.LocalDate; import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -34,6 +36,9 @@ public class ExpenseInput { private Double otherPersonAmount; private SplitMode splitMode; + + @Min(0) + @Max(100) private Integer splitPercentage; @NotNull(message = "Date is required") diff --git a/src/test/java/de/zendric/app/xpensely_Server/controller/ExpenseListControllerTest.java b/src/test/java/de/zendric/app/xpensely_Server/controller/ExpenseListControllerTest.java index 8da4b49..2b68fb3 100644 --- a/src/test/java/de/zendric/app/xpensely_Server/controller/ExpenseListControllerTest.java +++ b/src/test/java/de/zendric/app/xpensely_Server/controller/ExpenseListControllerTest.java @@ -333,6 +333,21 @@ class ExpenseListControllerTest { org.mockito.Mockito.verify(expenseListService).updateDefaultSplit(5L, 60); } + @Test + void updateDefaultSplit_nonMember_returns403() throws Exception { + AppUser owner = new AppUser(); owner.setId(1L); + AppUser stranger = new AppUser(); stranger.setId(2L); + ExpenseList list = new ExpenseList(); list.setId(5L); list.setOwner(owner); + + when(expenseListService.findById(5L)).thenReturn(Optional.of(list)); + when(authenticatedUserResolver.resolveCurrentUser(any())).thenReturn(stranger); + + mockMvc.perform(put("/api/expenselist/5/default-split") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"percentage\":60}")) + .andExpect(status().isForbidden()); + } + // --- Duplicate-username invite guard --- @Test