feat(API): Adds TagController class

This commit is contained in:
MrFastwind
2024-10-14 18:48:24 +02:00
committed by REDCODE
parent 8c42051461
commit b1bb076906
3 changed files with 169 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
using Lactose.Mapper;
using Lactose.Models;
using Lactose.Repositories;
using Lactose.Services;
using Lactose.Types;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Extensions;
namespace Lactose.Controllers;
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TagController(
ILogger<TagController> logger,
LactoseAuthService authService,
ITagRepository tagRepository
) : ControllerBase {
[HttpGet("id")]
public ActionResult<TagDto> Get(Guid id, bool children = false, bool ancestors = false) {
Tag? tag = tagRepository.Find(id);
if (tag == null) { return NotFound(); }
var tagDto = TagsMapper.ToTagDto(tag);
tagDto.Parent = tag.Parent == null ? null : TagsMapper.ToTagDto(tag.Parent);
if (children) {
tagDto.Children = [];
tagRepository.GetChildren(tag.Id).ForEach(t => tagDto.Children.Add(TagsMapper.ToTagDto(t)));
}
//TODO: Protect from overflow
if (ancestors) {
Tag? index = tag.Parent;
TagDto? indexDto = tagDto;
List<Tag> ancestorsTags = [];
// This is redundant, because circular references shouldn't be present
while (index != null && !ancestorsTags.Contains(tag)) {
ancestorsTags.Add(index);
indexDto.Parent = TagsMapper.ToTagDto(index);
index = index.Parent;
indexDto = indexDto.Parent;
}
}
return tagDto;
}
[HttpGet]
public ActionResult<List<TagDto>> GetAll(string? search, uint? page, uint? pageSize) {
search ??= string.Empty;
List<Tag> tags = tagRepository.Search(search, page, pageSize);
List<TagDto> tagsDto = [];
tags.ForEach(
t => {
var tagDto = TagsMapper.ToTagDto(t);
tagDto.Parent = t.Parent == null ? null : TagsMapper.ToTagDto(t.Parent);
tagsDto.Add(tagDto);
}
);
return tagsDto;
}
[HttpPost]
public ActionResult Update([FromBody] TagUpdateDto tagDto) {
LactoseAuthenticatedUser? user = authService.GetUserData(User);
if (user == null) {
logger.LogWarning(@"Anonymous User hasn't enough permissions to create a Tag. it shouldn't be here");
return Unauthorized("Unauthorized");
}
if (user.AccessLevel != EAccessLevel.Admin && user.AccessLevel != EAccessLevel.Curator) {
return Unauthorized("Unauthorized");
}
Tag? tag = tagRepository.Find(tagDto.Id);
if (tag == null) { return NotFound(); }
if (!tagDto.Name.IsNullOrEmpty()) { tag.Name = tagDto.Name!; }
if (tagDto.Parent != null) {
if (tagDto.Parent.Equals(Guid.Empty)) { tag.Parent = null; }
Tag? parent = tagRepository.Find(tagDto.Parent.Value);
if (parent != null) { tag.Parent = parent; } else { return NotFound("Parent tag was not found"); }
}
tagRepository.Save();
return Ok();
}
[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("{id}")]
public ActionResult Delete(Guid id) {
throw new NotImplementedException("Tag:Delete is not implemented yet");
}
}
public class TagDto {
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public TagDto? Parent { get; set; }
public List<TagDto>? Children { get; set; }
}
public class TagUpdateDto {
public Guid Id { get; set; }
public string? Name { get; set; }
public Guid? Parent { get; set; }
}

View File

@@ -0,0 +1,14 @@
using Lactose.Controllers;
using Lactose.Models;
namespace Lactose.Mapper;
public static class TagsMapper {
public static TagDto ToTagDto(Tag tag) {
return new TagDto() {
Id = tag.Id,
Name = tag.Name,
Parent = null
};
}
}

View File

@@ -0,0 +1,36 @@
using Lactose.Models;
namespace Lactose.Repositories;
public interface ITagRepository : IDisposable {
/// <summary>
/// Search for tags that are like the given <paramref name="searchQuery"/>
/// </summary>
/// <param name="searchQuery">the search query</param>
/// <param name="page"> the number of the page for the given query</param>
/// <param name="pageSize">the size of the page</param>
/// <returns>list of tags of type <see cref="Tag"/> with the size <paramref name="pageSize"/></returns>
List<Tag> Search(string searchQuery, uint? page, uint? pageSize);
/// <summary>
/// Returns all the tags
/// </summary>
/// <returns></returns>
IEnumerable<Tag> GetAll();
/// <summary>
/// Find a specific Tag given the id
/// </summary>
/// <param name="id">identifier of the tag</param>
/// <returns>the <see cref="Tag"/> or null</returns>
Tag? Find(Guid id);
/// <summary>
/// Return the list of the children of the given tag
/// </summary>
/// <param name="id">identifier of the tag</param>
/// <returns>the list of <see cref="Tag"/>, could be empty</returns>
List<Tag> GetChildren(Guid id);
void Save();
}