From cfb3260e0e13cdd512a48a3ac6bd898df8b24c18 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 7 Apr 2026 13:40:43 +0200 Subject: [PATCH] fix(api): add input validation to PersonNameAliasDTO Adds @NotBlank @Size(max=255) on lastName, @NotNull on type, @Valid on controller parameter. Blank/null input now returns 400 instead of reaching the DB constraint. 2 new controller tests. Co-Authored-By: Claude Sonnet 4.6 --- .../controller/PersonController.java | 2 +- .../familienarchiv/dto/PersonNameAliasDTO.java | 9 ++++++--- .../controller/PersonControllerTest.java | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java b/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java index 78da866a..6210f529 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/controller/PersonController.java @@ -104,7 +104,7 @@ public class PersonController { @PostMapping("/{id}/aliases") @RequirePermission(Permission.WRITE_ALL) - public PersonNameAlias addAlias(@PathVariable UUID id, @RequestBody PersonNameAliasDTO dto) { + public PersonNameAlias addAlias(@PathVariable UUID id, @Valid @RequestBody PersonNameAliasDTO dto) { return personService.addAlias(id, dto); } diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dto/PersonNameAliasDTO.java b/backend/src/main/java/org/raddatz/familienarchiv/dto/PersonNameAliasDTO.java index 2ce8a04d..a25ad2f0 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/dto/PersonNameAliasDTO.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/dto/PersonNameAliasDTO.java @@ -1,9 +1,12 @@ package org.raddatz.familienarchiv.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import org.raddatz.familienarchiv.model.PersonNameAliasType; public record PersonNameAliasDTO( - String lastName, - String firstName, - PersonNameAliasType type + @NotBlank @Size(max = 255) String lastName, + @Size(max = 255) String firstName, + @NotNull PersonNameAliasType type ) {} diff --git a/backend/src/test/java/org/raddatz/familienarchiv/controller/PersonControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/controller/PersonControllerTest.java index cf29b596..bd41be36 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/controller/PersonControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/controller/PersonControllerTest.java @@ -458,4 +458,22 @@ class PersonControllerTest { mockMvc.perform(delete("/api/persons/{id}/aliases/{aliasId}", UUID.randomUUID(), UUID.randomUUID())) .andExpect(status().isForbidden()); } + + @Test + @WithMockUser(authorities = "WRITE_ALL") + void addAlias_returns400_whenLastNameIsBlank() throws Exception { + mockMvc.perform(post("/api/persons/{id}/aliases", UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"lastName\":\"\",\"type\":\"BIRTH\"}")) + .andExpect(status().isBadRequest()); + } + + @Test + @WithMockUser(authorities = "WRITE_ALL") + void addAlias_returns400_whenTypeIsNull() throws Exception { + mockMvc.perform(post("/api/persons/{id}/aliases", UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"lastName\":\"de Gruyter\"}")) + .andExpect(status().isBadRequest()); + } }