Files
MilkyShots/Lactose/Controllers/TagController.cs
2024-11-11 16:38:32 +01:00

120 lines
3.7 KiB
C#

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; }
}