From 6c4d10d12faceab20a1987fbb411bf82da39f541 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 31 May 2026 12:43:52 +0200 Subject: [PATCH] test(security): lock READ_ALL -> 403 on comment-write endpoints (#697) Round out the "read-only users can't write anything" boundary: a READ_ALL principal is forbidden from posting a block comment, replying, and editing a comment (the prior tests only used a no-authority principal for create). Co-Authored-By: Claude Opus 4.8 --- .../comment/CommentControllerTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/backend/src/test/java/org/raddatz/familienarchiv/document/comment/CommentControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/document/comment/CommentControllerTest.java index 473b1a7a..7b047617 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/document/comment/CommentControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/document/comment/CommentControllerTest.java @@ -94,6 +94,15 @@ class CommentControllerTest { .andExpect(status().isForbidden()); } + @Test + @WithMockUser(authorities = "READ_ALL") + void postBlockComment_returns403_whenUserHasOnlyReadAllPermission() throws Exception { + UUID blockId = UUID.randomUUID(); + mockMvc.perform(post("/api/documents/" + DOC_ID + "/transcription-blocks/" + blockId + "/comments").with(csrf()) + .contentType(MediaType.APPLICATION_JSON).content(COMMENT_JSON)) + .andExpect(status().isForbidden()); + } + @Test @WithMockUser(authorities = "ANNOTATE_ALL") void postBlockComment_returns201_whenHasAnnotatePermission() throws Exception { @@ -142,6 +151,16 @@ class CommentControllerTest { .andExpect(status().isUnauthorized()); } + @Test + @WithMockUser(authorities = "READ_ALL") + void replyToBlockComment_returns403_whenUserHasOnlyReadAllPermission() throws Exception { + UUID blockId = UUID.randomUUID(); + mockMvc.perform(post("/api/documents/" + DOC_ID + "/transcription-blocks/" + blockId + + "/comments/" + COMMENT_ID + "/replies").with(csrf()) + .contentType(MediaType.APPLICATION_JSON).content(COMMENT_JSON)) + .andExpect(status().isForbidden()); + } + @Test @WithMockUser(authorities = "ANNOTATE_ALL") void replyToBlockComment_returns201_whenHasPermission() throws Exception { @@ -181,6 +200,14 @@ class CommentControllerTest { .andExpect(status().isUnauthorized()); } + @Test + @WithMockUser(authorities = "READ_ALL") + void editComment_returns403_whenUserHasOnlyReadAllPermission() throws Exception { + mockMvc.perform(patch("/api/documents/" + DOC_ID + "/comments/" + COMMENT_ID).with(csrf()) + .contentType(MediaType.APPLICATION_JSON).content(COMMENT_JSON)) + .andExpect(status().isForbidden()); + } + @Test @WithMockUser(authorities = "ANNOTATE_ALL") void editComment_returns200_whenHasPermission() throws Exception {