feat(app): restrict blog post editing to post author or Admin (#300)#304
Merged
mpaulosky merged 6 commits intoMay 11, 2026
Merged
Conversation
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>
- Add ResultErrorCode.Unauthorized = 5 to domain enum - Extend EditBlogPostCommand with CallerUserId and CallerIsAdmin - EditBlogPostHandler enforces: post.Author.Id == CallerUserId OR CallerIsAdmin - Edit.razor stores caller identity from AuthStateProvider and passes it in command - Edit.razor redirects to /blog on Unauthorized error code - All existing tests updated for new command constructor - New tests: AdminCanEditAnyPost, AuthorCanEditOwnPost, DifferentNonAdminUser_ReturnsUnauthorized - Leave decisions inbox note for Legolas on contract changes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Unit test (#300) - Fix HandleSubmit: Unauthorized result now shows user-friendly inline error 'You don't have permission to edit this post.' instead of silently navigating to /blog (the old code also set _error after navigating, which the user would never see) - Add bUnit test EditShowsErrorWhenServerReturnsUnauthorized: verifies the permission-denied message appears and navigation does not fire when the server returns ResultErrorCode.Unauthorized - Update agent histories for Legolas and Aragorn Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
🏗️ PR Added to Squad Triage QueueThis PR has been labeled with Next steps:
|
There was a problem hiding this comment.
Pull request overview
Implements end-to-end authorization for editing blog posts so only the original post author or an Admin can edit, with both backend enforcement (handler) and frontend UX guardrails (Edit page + bUnit coverage).
Changes:
- Added
ResultErrorCode.Unauthorizedand enforced author/Admin checks inEditBlogPostHandler. - Extended
EditBlogPostCommandto include caller context (CallerUserId,CallerIsAdmin) and updated validators/tests accordingly. - Added frontend load-time redirect + submit-time unauthorized messaging, with new bUnit ACL tests.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/Web.Tests/Handlers/EditBlogPostHandlerTests.cs | Updates existing edit tests and adds coverage for author/admin/unauthorized edit outcomes. |
| tests/Web.Tests/Features/BlogPosts/Commands/UpdateBlogPostCommandValidatorTests.cs | Updates validator tests to use the new EditBlogPostCommand signature. |
| tests/Web.Tests/Features/BlogPosts/Commands/EditBlogPostCommandValidatorTests.cs | Updates validator tests to use the new EditBlogPostCommand signature. |
| tests/Web.Tests/Behaviors/ValidationBehaviorTests.cs | Updates validation behavior tests to use the new EditBlogPostCommand signature. |
| tests/Web.Tests.Bunit/Features/EditAclTests.cs | Adds bUnit tests covering edit ACL redirect/allow/admin and unauthorized UX. |
| src/Web/Features/BlogPosts/Edit/EditBlogPostHandler.cs | Adds server-side authorization enforcement returning Unauthorized when caller isn’t author/admin. |
| src/Web/Features/BlogPosts/Edit/EditBlogPostCommand.cs | Extends the edit command with caller identity/admin context. |
| src/Web/Features/BlogPosts/Edit/Edit.razor | Adds load-time ownership check + submit-time unauthorized message handling. |
| src/Domain/Abstractions/Result.cs | Adds Unauthorized = 5 to the shared result error codes. |
| .squad/agents/legolas/history.md | Documents frontend approach and testing notes for issue #300. |
| .squad/agents/aragorn/history.md | Documents backend approach and related implementation notes. |
| } | ||
| else | ||
| { | ||
| _model = null; |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Kept instance fields _callerUserId and _callerIsAdmin from PR branch (needed for HandleSubmit) - Kept full EditShowsErrorWhenServerReturnsUnauthorized test from PR branch - Dev branch changes merged successfully Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mpaulosky
enabled auto-merge (squash)
May 11, 2026 20:36
mpaulosky
deleted the
squad/300-restrict-blog-post-edit-to-author-or-admin
branch
May 11, 2026 20:37
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #304 +/- ##
==========================================
+ Coverage 83.19% 83.33% +0.13%
==========================================
Files 47 47
Lines 1238 1248 +10
Branches 150 152 +2
==========================================
+ Hits 1030 1040 +10
Misses 148 148
Partials 60 60
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #300
Full-stack implementation restricting blog post editing to the post's original author or an Admin. This is the complete solution combining Aragorn's backend enforcement with Legolas's frontend UX.
Working as Legolas (Frontend Developer) + incorporating Aragorn (Backend Developer) changes.
Changes
Backend (Aragorn)
ResultErrorCode.Unauthorized = 5— new enum value insrc/Domain/Abstractions/Result.csEditBlogPostCommand— extended withCallerUserIdandCallerIsAdminparametersEditBlogPostHandler— authorization check: returnsUnauthorizedifCallerUserId != post.Author.Idand not AdminFrontend (Legolas)
Edit.razorload-time check — after post loads, compares Auth0subclaim withpost.AuthorId; redirects non-owners to/blog(unless Admin)Edit.razorsubmit-time —HandleSubmitpasses_callerUserIdand_callerIsAdminin the command; onUnauthorizedresponse shows inline user-friendly error instead of silent navigationEditAclTests.cs) — 4 tests: redirect non-owner, allow owner, allow Admin, server-side Unauthorized shows error messageTest Results