Skip to content

feat(ui): restrict blog post editing to post author or Admin (#300)#302

Merged
mpaulosky merged 1 commit into
devfrom
squad/300-author-edit-acl
May 11, 2026
Merged

feat(ui): restrict blog post editing to post author or Admin (#300)#302
mpaulosky merged 1 commit into
devfrom
squad/300-author-edit-acl

Conversation

@mpaulosky

Copy link
Copy Markdown
Owner

Summary

Closes #300

Adds UI-level author ownership check to Edit.razor:

  • Only the post's author (matching Auth0 sub claim) or an Admin can edit
  • Non-owners are immediately redirected to /blog in OnParametersSetAsync
  • Admins retain unrestricted edit access

Changes

  • src/Web/Features/BlogPosts/Edit/Edit.razor — ACL check in OnParametersSetAsync after post load; AuthenticationStateProvider injected
  • tests/Web.Tests.Bunit/Features/EditAclTests.cs — bUnit tests for author/non-author/admin scenarios

Test Results

  • ✅ bUnit: 87/87 passed (+3 new ACL tests)
  • ✅ Architecture.Tests: 16/16
  • ✅ Web.Tests: 151/151
  • ✅ Integration tests: all passed

Working as Legolas (Frontend Developer) + Sam (Backend)

Add UI-level ownership check in Edit.razor:
- AuthenticationStateProvider injected; sub claim extracted in OnParametersSetAsync
- After loading post, check if current user is Admin OR post.AuthorId matches sub
- If neither, redirect to /blog immediately
- Admins retain unrestricted edit access

bUnit tests added for:
- author can edit own post
- non-owner Author redirected to /blog
- Admin can edit any post

Closes #300

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 11, 2026 20:13
@github-actions github-actions Bot added the squad Squad triage inbox — Lead will assign to a member label May 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🏗️ PR Added to Squad Triage Queue

This PR has been labeled with squad and added to the triage queue.

Next steps:

  • The squad Lead will review and assign to an appropriate team member
  • A squad:member label will be added after triage

If you know which squad member should handle this, you can add the appropriate squad:member label yourself.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an ownership-based UI access control check to the blog post edit page so that only the post’s author (Auth0 sub) or an Admin can edit, with bUnit coverage for the key scenarios.

Changes:

  • Added an ownership/Admin check in Edit.razor during OnParametersSetAsync, redirecting non-owners away after loading the post.
  • Introduced new bUnit tests validating redirect for non-owners and access for owners/Admins.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Web/Features/BlogPosts/Edit/Edit.razor Adds UI-level ownership/Admin gating when loading an edit model.
tests/Web.Tests.Bunit/Features/EditAclTests.cs Adds bUnit tests for owner/non-owner/admin edit access behavior.

Comment on lines 64 to +83
protected override async Task OnParametersSetAsync()
{
var result = await Sender.Send(new GetBlogPostByIdQuery(Id));
if (result.Success)
_model = result.Value is not null
? new PostFormModel { Title = result.Value.Title, Content = result.Value.Content }
: null;
{
if (result.Value is not null)
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
var userSub = user.FindFirst("sub")?.Value ?? string.Empty;
var isAdmin = user.IsInRole("Admin");
var isAuthor = result.Value.AuthorId == userSub;

if (!isAdmin && !isAuthor)
{
Navigation.NavigateTo("/blog");
return;
}

_model = new PostFormModel { Title = result.Value.Title, Content = result.Value.Content };
Comment on lines +73 to +76
var userSub = user.FindFirst("sub")?.Value ?? string.Empty;
var isAdmin = user.IsInRole("Admin");
var isAuthor = result.Value.AuthorId == userSub;

Comment on lines +77 to +81
if (!isAdmin && !isAuthor)
{
Navigation.NavigateTo("/blog");
return;
}
@github-actions

Copy link
Copy Markdown
Contributor

Test Results Summary

357 tests  +3   356 ✅ +3   19s ⏱️ ±0s
  6 suites ±0     1 💤 ±0 
  6 files   ±0     0 ❌ ±0 

Results for commit 1dfd970. ± Comparison against base commit 628110f.

@codecov

codecov Bot commented May 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.19%. Comparing base (628110f) to head (1dfd970).

Files with missing lines Patch % Lines
src/Web/Features/BlogPosts/Edit/Edit.razor 81.81% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #302      +/-   ##
==========================================
+ Coverage   83.08%   83.19%   +0.10%     
==========================================
  Files          47       47              
  Lines        1230     1238       +8     
  Branches      148      150       +2     
==========================================
+ Hits         1022     1030       +8     
- Misses        147      148       +1     
+ Partials       61       60       -1     
Files with missing lines Coverage Δ
src/Web/Features/BlogPosts/Edit/Edit.razor 78.78% <81.81%> (+6.78%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mpaulosky
mpaulosky merged commit 292fd26 into dev May 11, 2026
23 checks passed
@mpaulosky
mpaulosky deleted the squad/300-author-edit-acl branch May 11, 2026 20:20
@mpaulosky

Copy link
Copy Markdown
Owner Author

🚫 Lead gate verdict: REJECT / CHANGES REQUIRED

I cannot file a formal REQUEST_CHANGES review from this account because GitHub treats it as the PR author's own account, so I am posting the gate verdict here.

Blocking findings

  • At the live PR head (1dfd970), EditBlogPostCommand still carries only (Id, Title, Content) and EditBlogPostHandler updates the post without checking caller identity. The new check in Edit.razor is UI-only and is not the security boundary; any alternate code path that sends the command can still edit another author's post.
  • Issue [Sprint 19] feat(app): restrict blog post editing to post author or Admin #300 requires an unauthorized user to be redirected with an error or shown a 403. The current implementation silently redirects to /blog.

Signals reviewed

  • Copilot's primary security comment is correct.
  • CI is green.
  • Codecov is non-blocking here: project coverage increased by +0.10%.

🔄 Reviewer lockout

  • Original PR authors Legolas + Sam are locked out of the next revision cycle for this artifact.
  • Revision owner: Gandalf (Security / Auth).

Re-review requirements

  1. Enforce ownership/admin authorization in the server-side edit path (EditBlogPostCommand + EditBlogPostHandler, or equivalent authorization boundary).
  2. Add tests that prove unauthorized writes are rejected.
  3. Surface explicit denial feedback (403 or redirect with an error).

mpaulosky pushed a commit that referenced this pull request May 11, 2026
Summary: PRs #297, #298, #301, #302 merged. Issues #293, #296, #299,
#300 all closed. Sprint 19 complete.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky pushed a commit that referenced this pull request May 11, 2026
…ation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

squad Squad triage inbox — Lead will assign to a member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Sprint 19] feat(app): restrict blog post editing to post author or Admin

2 participants