using API.Authentication.Interfaces; using API.DTO; using API.Services; using DAL.Models; using DAL.Models.Audits; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; using MUser = DAL.Models.User; namespace API.Controllers { public class CRUDBase : ControllerBase where TAuthentication : IGenericAuthentication where TModel : Model where TAuditModel : AuditModel where TDTO : IAdaptable, new() where TUpdateDTO : IUpdateAdaptable where TService : ServiceBase { public readonly ILogger Logger; public readonly TService Service; public readonly UserService UserService; public CRUDBase(ILogger logger, UserService userService, TService service) { Logger = logger; UserService = userService; Service = service; } [HttpGet] public virtual ActionResult> get() { MUser? user = getUser(User); if (user == null) return Unauthorized(); IEnumerable? result = Service.get(user); if (result == null) return Forbid(); List dtos = []; Parallel.ForEach(result, item => { TDTO dto = new TDTO(); dto.adaptFromModel(item); dtos.Add(dto); }); return Ok(dtos); } [HttpGet("{id}")] public virtual ActionResult get(ulong id) { MUser? user = getUser(User); if (user == null) return Unauthorized(); TModel? result = Service.get(id, user); if (result == null) return Forbid(); TDTO dto = new TDTO(); dto.adaptFromModel(result); return Ok(dto); } [HttpPost] public virtual ActionResult add(TDTO createDTO) { MUser? user = getUser(User); if (user == null) return Unauthorized(); TModel? result = Service.add(createDTO, user); if (result == null) return Forbid(); TDTO dto = new TDTO(); dto.adaptFromModel(result); return Ok(dto); } [HttpPut("{id}")] public virtual ActionResult update(ulong id, TUpdateDTO updateDTO) { MUser? user = getUser(User); if (user == null) return Unauthorized(); TModel? result = Service.get(id, user); if (result == null) return Forbid(); updateDTO.adaptModel(ref result); TModel? newResult = Service.update(result, user); if (newResult == null) return Forbid(); TDTO dto = new TDTO(); dto.adaptFromModel(newResult); return Ok(dto); } [HttpDelete("{id}")] public virtual ActionResult delete(ulong id) { MUser? user = getUser(User); if (user == null) return Unauthorized(); TModel? result = Service.get(id, user); if (result == null) return Forbid(); TAuditModel? auditModel = Service.delete(result, user); if (auditModel == null) return Forbid(); // todo in the future we should return the audit return NoContent(); } [NonAction] public MUser? getUser(ClaimsPrincipal user) { Claim? idClaim = user.FindFirst(ClaimTypes.NameIdentifier); if (idClaim == null) return null; return UserService.getNoAuthentication(UInt64.Parse(idClaim.Value)); } } }