Fix missing return in authorization

This commit is contained in:
2025-10-06 17:09:43 +03:00
parent 0a4bd23d30
commit 1e16cf892d
2 changed files with 65 additions and 26 deletions

View File

@@ -1,7 +1,7 @@
meta { meta {
name: Login as admin name: Login as admin
type: http type: http
seq: 5 seq: 3
} }
post { post {

View File

@@ -183,7 +183,7 @@ public class PostController(
// If not the resource owner // If not the resource owner
var userId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; var userId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
if (userId != post.Author.Id) Forbid(); if (userId != post.Author.Id) return Forbid();
if (fileRecord.FinishedDate != null) if (fileRecord.FinishedDate != null)
return Problem(statusCode: StatusCodes.Status400BadRequest, return Problem(statusCode: StatusCodes.Status400BadRequest,
@@ -354,10 +354,7 @@ public class PostController(
var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin); var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin);
// If neither the admin nor the resource owner // If neither the admin nor the resource owner
if (!isAdmin && userId != post.Author.Id) if (!isAdmin && userId != post.Author.Id) return Forbid();
{
Forbid();
}
// Clean up the file record first // Clean up the file record first
var fullPath = Path.Combine(env.ContentRootPath, post.File.FilePath); var fullPath = Path.Combine(env.ContentRootPath, post.File.FilePath);
@@ -383,6 +380,8 @@ public class PostController(
[HttpPatch("{id:int}")] [HttpPatch("{id:int}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<PostDto>> Update(int id, EditPostDto dto) public async Task<ActionResult<PostDto>> Update(int id, EditPostDto dto)
{ {
@@ -393,11 +392,7 @@ public class PostController(
var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin); var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin);
// If neither the admin nor the resource owner // If neither the admin nor the resource owner
if (!isAdmin && userId != post.Author.Id) if (!isAdmin && userId != post.Author.Id) return Forbid();
{
Forbid();
}
if (!string.IsNullOrEmpty(dto.Title)) if (!string.IsNullOrEmpty(dto.Title))
post.Title = dto.Title; post.Title = dto.Title;
@@ -424,12 +419,22 @@ public class PostController(
return Ok(PostDto.FromPost(updated, fileUrl)); return Ok(PostDto.FromPost(updated, fileUrl));
} }
/// <summary>
/// Create a comment under the specified post.
/// </summary>
/// <param name="postId">Post ID</param>
/// <param name="dto">Comment data</param>
/// <response code="201">New comment data</response>
/// <response code="400">If request is malformed</response>
/// <response code="401">If authentication is missing</response>
/// <response code="403">If authorization is missing</response>
/// <response code="404">If post is not found</response>
[HttpPost("{postId:int}/comments")] [HttpPost("{postId:int}/comments")]
[Authorize] [Authorize(Roles = UserRoles.Regular)]
[ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public async Task<ActionResult<PostDto>> CreateComment(int postId, CreateCommentDto dto) public async Task<ActionResult<PostDto>> CreateComment(int postId, CreateCommentDto dto)
{ {
var userId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; var userId = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
@@ -439,11 +444,18 @@ public class PostController(
var post = await postService.GetById(postId); var post = await postService.GetById(postId);
if (post == null) return NotFound(); if (post == null) return NotFound();
var created = await commentService.Create(dto.Text, user, post); var created = await commentService.Create(dto.Text, user, post);
return CreatedAtAction(nameof(GetComment), new {postId = postId, commentId = created.Id}, CommentDto.FromComment(created)); return CreatedAtAction(nameof(GetComment), new {postId = postId, commentId = created.Id}, CommentDto.FromComment(created));
} }
/// <summary>
/// Get specific post comment.
/// </summary>
/// <param name="postId">Post ID</param>
/// <param name="commentId">Comment ID</param>
/// <response code="200">Comment data</response>
/// <response code="400">If request is malformed</response>
/// <response code="404">If post or comment is not found</response>
[HttpGet("{postId:int}/comments/{commentId:int}")] [HttpGet("{postId:int}/comments/{commentId:int}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -459,6 +471,14 @@ public class PostController(
return Ok(CommentDto.FromComment(comment)); return Ok(CommentDto.FromComment(comment));
} }
/// <summary>
/// Get paginated list of specific post comments.
/// </summary>
/// <param name="postId">Post ID</param>
/// <param name="pageNumber">Page number</param>
/// <response code="200">Paginated list of comments</response>
/// <response code="400">If request is malformed</response>
/// <response code="404">If post is not found</response>
[HttpGet("{postId:int}/comments")] [HttpGet("{postId:int}/comments")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -476,11 +496,22 @@ public class PostController(
return Ok(new PagedList<CommentDto>(newItems, list.CurrentPage, list.PageSize, list.TotalCount)); return Ok(new PagedList<CommentDto>(newItems, list.CurrentPage, list.PageSize, list.TotalCount));
} }
/// <summary>
[Authorize] /// Delete a specific comment under a specific post.
/// </summary>
/// <param name="postId">Post ID</param>
/// <param name="commentId">Comment ID</param>
/// <response code="204">If comment was deleted successfully</response>
/// <response code="400">If request is malformed</response>
/// <response code="401">If authentication is missing</response>
/// <response code="403">If authorization is missing</response>
/// <response code="404">If post or comment is not found</response>
[Authorize(Roles = UserRoles.Regular)]
[HttpDelete("{postId:int}/comments/{commentId:int}")] [HttpDelete("{postId:int}/comments/{commentId:int}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> DeleteComment(int postId, int commentId) public async Task<ActionResult> DeleteComment(int postId, int commentId)
{ {
@@ -494,19 +525,30 @@ public class PostController(
var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin); var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin);
// If neither the admin nor the resource owner // If neither the admin nor the resource owner
if (!isAdmin && userId != comment.Author.Id) if (!isAdmin && userId != comment.Author.Id) return Forbid();
{
Forbid();
}
var deleted = await commentService.Delete(comment); var deleted = await commentService.Delete(comment);
if (!deleted) return NotFound(); if (!deleted) return NotFound();
return NoContent(); return NoContent();
} }
[Authorize] /// <summary>
/// Update a specific comment under a specific post.
/// </summary>
/// <param name="postId">Post ID</param>
/// <param name="commentId">Comment ID</param>
/// <param name="dto">Comment data</param>
/// <response code="200">New comment data</response>
/// <response code="400">If request is malformed</response>
/// <response code="401">If authentication is missing</response>
/// <response code="403">If authorization is missing</response>
/// <response code="404">If post or comment is not found</response>
[Authorize(Roles = UserRoles.Regular)]
[HttpPatch("{postId:int}/comments/{commentId:int}")] [HttpPatch("{postId:int}/comments/{commentId:int}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<CommentDto>> Update(int postId, int commentId, EditCommentDto dto) public async Task<ActionResult<CommentDto>> Update(int postId, int commentId, EditCommentDto dto)
{ {
@@ -520,10 +562,7 @@ public class PostController(
var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin); var isAdmin = HttpContext.User.IsInRole(UserRoles.Admin);
// If neither the admin nor the resource owner // If neither the admin nor the resource owner
if (!isAdmin && userId != comment.Author.Id) if (!isAdmin && userId != comment.Author.Id) return Forbid();
{
Forbid();
}
comment.Text = dto.Text; comment.Text = dto.Text;