Browse Source

fixed alarm comment update flow validation

pull/15715/head
dashevchenko 1 month ago
parent
commit
ae2fdf85f2
  1. 12
      application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java
  2. 5
      application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java

12
application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java

@ -78,7 +78,10 @@ public class AlarmCommentController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
Alarm alarm = checkAlarmInfoId(alarmId, Operation.WRITE);
checkUserCommentOwnership(alarmComment, Operation.WRITE);
if (alarmComment.getId() != null) {
AlarmComment existingAlarmComment = checkAlarmCommentId(alarmComment.getId(), alarmId);
checkUserCommentOwnership(existingAlarmComment, Operation.WRITE);
}
alarmComment.setAlarmId(alarmId);
alarmComment.setType(AlarmCommentType.OTHER);
return tbAlarmCommentService.saveAlarmComment(alarm, alarmComment, getCurrentUser());
@ -125,7 +128,12 @@ public class AlarmCommentController extends BaseController {
private void checkUserCommentOwnership(AlarmComment alarmComment, Operation operation) throws ThingsboardException {
if (alarmComment.getUserId() != null && !alarmComment.getUserId().equals(getCurrentUser().getId())) {
throw new ThingsboardException("User is not allowed to " + operation.name().toLowerCase() + " other user's comment",
String action = switch (operation) {
case WRITE -> "edit";
case DELETE -> "delete";
default -> "perform this operation with";
};
throw new ThingsboardException("User is not allowed to " + action + " other user's comment",
ThingsboardErrorCode.PERMISSION_DENIED);
}
}

5
application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java

@ -172,10 +172,13 @@ public class AlarmCommentControllerTest extends AbstractControllerTest {
JsonNode newComment = JacksonUtil.newObjectNode().set("text", new TextNode("Tenant rewrite attempt"));
alarmComment.setComment(newComment);
// Simulate the real attack: the attacker controls the request body and would omit (or spoof)
// the userId. Ownership must be enforced against the persisted comment, not the body.
alarmComment.setUserId(null);
doPost("/api/alarm/" + alarm.getId() + "/comment", alarmComment)
.andExpect(status().isForbidden())
.andExpect(statusReason(containsString("User is not allowed to write other user's comment")));
.andExpect(statusReason(containsString("User is not allowed to edit other user's comment")));
testNotifyEntityNever(alarm.getId(), alarmComment);
}

Loading…
Cancel
Save