From 8082d60ffe163a987f25ad7ab9950dc645eb9193 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Mon, 8 Jun 2026 17:48:35 +0300 Subject: [PATCH] update alarm comment moderation logic: delete is allowed for author or tenant admin only --- .../controller/AlarmCommentController.java | 17 ++++++++++++----- .../controller/AlarmCommentControllerTest.java | 12 ++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java index adc29df05f..998ca1cfa5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java @@ -81,11 +81,7 @@ public class AlarmCommentController extends BaseController { Alarm alarm = checkAlarmInfoId(alarmId, Operation.WRITE); SecurityUser currentUser = getCurrentUser(); if (alarmComment.getId() != null) { - AlarmComment existingAlarmComment = checkAlarmCommentId(alarmComment.getId(), alarmId); - if (existingAlarmComment.getUserId() != null && !existingAlarmComment.getUserId().equals(currentUser.getId())) { - throw new ThingsboardException("User is not allowed to edit other user's comment", - ThingsboardErrorCode.PERMISSION_DENIED); - } + checkUserPermission(alarmComment, alarmId, "edit", currentUser); } alarmComment.setAlarmId(alarmId); alarmComment.setType(AlarmCommentType.OTHER); @@ -104,6 +100,9 @@ public class AlarmCommentController extends BaseController { AlarmCommentId alarmCommentId = new AlarmCommentId(toUUID(strCommentId)); AlarmComment alarmComment = checkAlarmCommentId(alarmCommentId, alarmId); SecurityUser currentUser = getCurrentUser(); + if (!currentUser.isTenantAdmin()) { + checkUserPermission(alarmComment, alarmId, "delete", currentUser); + } tbAlarmCommentService.deleteAlarmComment(alarm, alarmComment, currentUser); } @@ -131,4 +130,12 @@ public class AlarmCommentController extends BaseController { return checkNotNull(alarmCommentService.findAlarmComments(alarm.getTenantId(), alarmId, pageLink)); } + private void checkUserPermission(AlarmComment alarmComment, AlarmId alarmId, String operation, SecurityUser currentUser) throws ThingsboardException { + AlarmComment existingAlarmComment = checkAlarmCommentId(alarmComment.getId(), alarmId); + if (existingAlarmComment.getUserId() != null && !existingAlarmComment.getUserId().equals(currentUser.getId())) { + throw new ThingsboardException("User is not allowed to " + operation + " other user's comment", + ThingsboardErrorCode.PERMISSION_DENIED); + } + } + } diff --git a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index 9b997cd8ad..bebfe832e8 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -235,7 +235,7 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { } @Test - public void testDeleteOthersAlarmCommentIsAllowedForUserWithAlarmWritePermission() throws Exception { + public void testDeleteOthersAlarmCommentIsAllowedForAuthorOrTenantAdmin() throws Exception { loginCustomerUser(); AlarmComment alarmComment = createAlarmComment(alarm.getId()); @@ -243,15 +243,19 @@ public class AlarmCommentControllerTest extends AbstractControllerTest { Mockito.reset(tbClusterService, auditLogService); doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) - .andExpect(status().isOk()); + .andExpect(status().isForbidden()) + .andExpect(statusReason(containsString("User is not allowed to delete other user's comment"))); + loginTenantAdmin(); + doDelete("/api/alarm/" + alarm.getId() + "/comment/" + alarmComment.getId()) + .andExpect(status().isOk()); AlarmComment expectedAlarmComment = AlarmComment.builder() .alarmId(alarm.getId()) .type(AlarmCommentType.SYSTEM) .comment(JacksonUtil.newObjectNode().put("text", String.format("Comment was deleted by user %s", - SECOND_CUSTOMER_USER_EMAIL))) + TENANT_ADMIN_EMAIL))) .build(); - testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, secondCustomerUserId, SECOND_CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); + testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment); } @Test