165 lines
6.6 KiB
C#
165 lines
6.6 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using T120B165_ImgBoard.Dtos.Comment;
|
|
using T120B165_ImgBoard.Dtos.Tag;
|
|
using T120B165_ImgBoard.Models;
|
|
using T120B165_ImgBoard.Services;
|
|
using T120B165_ImgBoard.Utils;
|
|
|
|
namespace T120B165_ImgBoard.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/tags")]
|
|
public class TagController(
|
|
ITagService tagService,
|
|
IPostService postService,
|
|
ICommentService commentService) : ControllerBase
|
|
{
|
|
/// <summary>
|
|
/// Creates a new tag.
|
|
/// </summary>
|
|
/// <param name="dto">New tag data.</param>
|
|
/// <response code="201">Returns the newly created tag</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="409">If tag already exists with such name</response>
|
|
[HttpPost]
|
|
[Authorize(Roles = UserRoles.Admin)]
|
|
[ProducesResponseType(StatusCodes.Status201Created)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
|
[ProducesResponseType(StatusCodes.Status409Conflict)]
|
|
public async Task<ActionResult<TagDto>> Create(CreateTagDto dto)
|
|
{
|
|
// Check if tag exists, if it does, throw a conflict
|
|
var existingTag = await tagService.GetByName(dto.Name);
|
|
if (existingTag != null)
|
|
{
|
|
return Problem(
|
|
detail: "Tag with such name already exists.",
|
|
statusCode: StatusCodes.Status409Conflict
|
|
);
|
|
}
|
|
|
|
var createdTag = await tagService.Create(dto.Type, dto.Name);
|
|
return CreatedAtAction(nameof(Get), new { name = createdTag.Name }, TagDto.FromTag(createdTag));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a paginated list of tags.
|
|
/// </summary>
|
|
/// <param name="page">The page number</param>
|
|
/// <response code="200">Returns paginated list</response>
|
|
/// <response code="400">If request is malformed</response>
|
|
[HttpGet]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
public async Task<ActionResult<PagedList<TagDto>>> GetAll(int page = 1)
|
|
{
|
|
var list = await tagService.GetAll(page);
|
|
var newItems = list.Items.Select(TagDto.FromTag).ToList();
|
|
return Ok(new PagedList<TagDto>(newItems, list.CurrentPage, list.PageSize, list.TotalCount));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get specific tag by name.
|
|
/// </summary>
|
|
/// <param name="name">The tag name</param>
|
|
/// <response code="200">The tag data</response>
|
|
/// <response code="400">If request is malformed</response>
|
|
/// <response code="404">If tag does not exist</response>
|
|
[HttpGet("{name}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<TagDto>> Get(string name)
|
|
{
|
|
var tag = await tagService.GetByName(name);
|
|
if (tag == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
return Ok(TagDto.FromTag(tag));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete specified tag.
|
|
/// </summary>
|
|
/// <param name="name">The tag name</param>
|
|
/// <response code="204">Indicates tag deletion success</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 tag does not exist</response>
|
|
[HttpDelete("{name}")]
|
|
[Authorize(Roles = UserRoles.Admin)]
|
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult> Delete(string name)
|
|
{
|
|
var deleted = await tagService.DeleteByName(name);
|
|
if (!deleted) return NotFound();
|
|
return NoContent();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update specified tag.
|
|
/// </summary>
|
|
/// <param name="name">The tag name</param>
|
|
/// <param name="dto">The new tag data</param>
|
|
/// <response code="200">Indicates tag update success</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 tag does not exist</response>
|
|
[HttpPatch("{name}")]
|
|
[Authorize(Roles = UserRoles.Admin)]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<TagDto>> Update(string name, EditTagDto dto)
|
|
{
|
|
var tag = await tagService.GetByName(name);
|
|
if (tag == null) return NotFound();
|
|
var updatedTag = await tagService.Update(tag, dto.Type);
|
|
return Ok(TagDto.FromTag(updatedTag));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Get specific tag, specific post comment.
|
|
/// </summary>
|
|
/// <param name="tagName">Tag name</param>
|
|
/// <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 tag or post or comment is not found</response>
|
|
[HttpGet("{tagName}/posts/{postId:int}/comments/{commentId:int}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<CommentDto>> GetComment(string tagName, int postId, int commentId)
|
|
{
|
|
var tag = await tagService.GetByName(tagName);
|
|
if (tag == null) return NotFound();
|
|
|
|
var entry = await postService.GetById(postId);
|
|
if (entry == null) return NotFound();
|
|
|
|
if (entry.Tags.All(t => t.Name != tag.Name)) return NotFound();
|
|
|
|
var comment = await commentService.GetById(commentId);
|
|
if (comment == null || entry.Id != comment.OriginalPost.Id) return NotFound();
|
|
|
|
return Ok(CommentDto.FromComment(comment));
|
|
}
|
|
}
|