fix(work-orders): enforce author-only comment edits per SH-122

Remove the undocumented Admin override so only the original comment author can edit, matching the ticket acceptance criteria.
This commit is contained in:
Arthur Bassi 2026-07-23 13:07:23 -03:00
parent 5158403543
commit 7ad24a5dfe
4 changed files with 18 additions and 27 deletions

View file

@ -296,9 +296,8 @@ namespace Api.SeaHavenIndustries.Controllers
try try
{ {
var actorId = User.FindFirstValue(ClaimTypes.NameIdentifier); var actorId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var isAdmin = User.IsInRole("Admin");
var comment = await _workOrderCommentService.UpdateCommentAsync( var comment = await _workOrderCommentService.UpdateCommentAsync(
id, commentId, request, actorId, isAdmin); id, commentId, request, actorId);
return Ok(comment); return Ok(comment);
} }
catch (WorkOrderBoardValidationException ex) when (ex.Code == "NotFound") catch (WorkOrderBoardValidationException ex) when (ex.Code == "NotFound")

View file

@ -65,8 +65,7 @@ namespace SeaHaven.Services.Implementation
int workOrderId, int workOrderId,
int commentId, int commentId,
WorkOrderCommentCreateDto request, WorkOrderCommentCreateDto request,
string? actorId, string? actorId)
bool isAdmin)
{ {
var workOrder = await _detailData.GetWorkOrderForMediaAsync(workOrderId); var workOrder = await _detailData.GetWorkOrderForMediaAsync(workOrderId);
if (workOrder == null) if (workOrder == null)
@ -89,7 +88,7 @@ namespace SeaHaven.Services.Implementation
var isAuthor = !string.IsNullOrWhiteSpace(actorId) var isAuthor = !string.IsNullOrWhiteSpace(actorId)
&& string.Equals(comment.UserId, actorId, StringComparison.Ordinal); && string.Equals(comment.UserId, actorId, StringComparison.Ordinal);
if (!isAuthor && !isAdmin) if (!isAuthor)
throw new WorkOrderBoardValidationException("Forbidden", "You are not allowed to edit this comment."); throw new WorkOrderBoardValidationException("Forbidden", "You are not allowed to edit this comment.");
comment.Commenttext = request.Text.Trim(); comment.Commenttext = request.Text.Trim();

View file

@ -11,7 +11,6 @@ namespace SeaHaven.Services.Interfaces
int workOrderId, int workOrderId,
int commentId, int commentId,
WorkOrderCommentCreateDto request, WorkOrderCommentCreateDto request,
string? actorId, string? actorId);
bool isAdmin);
} }
} }

View file

@ -478,8 +478,7 @@ public class WorkOrderCommentServiceTests
1, 1,
comment.Id, comment.Id,
new WorkOrderCommentCreateDto { Text = " Updated note " }, new WorkOrderCommentCreateDto { Text = " Updated note " },
"user-author", "user-author");
isAdmin: false);
Assert.Equal("Updated note", result.Text); Assert.Equal("Updated note", result.Text);
Assert.Equal("user-author", result.AuthorId); Assert.Equal("user-author", result.AuthorId);
@ -487,23 +486,22 @@ public class WorkOrderCommentServiceTests
} }
[Fact] [Fact]
public async Task UpdateComment_Admin_CanEditOthers() public async Task UpdateComment_AdminNonAuthor_ThrowsForbidden()
{ {
var (_, service, comment) = await SeedEditableCommentAsync(); var (_, service, comment) = await SeedEditableCommentAsync();
var result = await service.UpdateCommentAsync( var ex = await Assert.ThrowsAsync<WorkOrderBoardValidationException>(() =>
1, service.UpdateCommentAsync(
comment.Id, 1,
new WorkOrderCommentCreateDto { Text = "Admin edit" }, comment.Id,
"admin-user", new WorkOrderCommentCreateDto { Text = "Admin edit" },
isAdmin: true); "admin-user"));
Assert.Equal("Admin edit", result.Text); Assert.Equal("Forbidden", ex.Code);
Assert.Equal("user-author", result.AuthorId);
} }
[Fact] [Fact]
public async Task UpdateComment_NonAuthorNonAdmin_ThrowsForbidden() public async Task UpdateComment_NonAuthor_ThrowsForbidden()
{ {
var (_, service, comment) = await SeedEditableCommentAsync(); var (_, service, comment) = await SeedEditableCommentAsync();
@ -512,8 +510,7 @@ public class WorkOrderCommentServiceTests
1, 1,
comment.Id, comment.Id,
new WorkOrderCommentCreateDto { Text = "Nope" }, new WorkOrderCommentCreateDto { Text = "Nope" },
"other-user", "other-user"));
isAdmin: false));
Assert.Equal("Forbidden", ex.Code); Assert.Equal("Forbidden", ex.Code);
} }
@ -530,8 +527,7 @@ public class WorkOrderCommentServiceTests
1, 1,
comment.Id, comment.Id,
new WorkOrderCommentCreateDto { Text = "Nope" }, new WorkOrderCommentCreateDto { Text = "Nope" },
"user-author", "user-author"));
isAdmin: false));
Assert.Equal("NotEditable", ex.Code); Assert.Equal("NotEditable", ex.Code);
} }
@ -546,8 +542,7 @@ public class WorkOrderCommentServiceTests
1, 1,
comment.Id, comment.Id,
new WorkOrderCommentCreateDto { Text = "Nope" }, new WorkOrderCommentCreateDto { Text = "Nope" },
"user-author", "user-author"));
isAdmin: false));
Assert.Equal("ReadOnly", ex.Code); Assert.Equal("ReadOnly", ex.Code);
} }
@ -564,8 +559,7 @@ public class WorkOrderCommentServiceTests
2, 2,
comment.Id, comment.Id,
new WorkOrderCommentCreateDto { Text = "Nope" }, new WorkOrderCommentCreateDto { Text = "Nope" },
"user-author", "user-author"));
isAdmin: false));
Assert.Equal("NotFound", ex.Code); Assert.Equal("NotFound", ex.Code);
} }