diff --git a/API/Controllers/CRUDBase.cs b/API/Controllers/CRUDBase.cs new file mode 100644 index 0000000..2c299bb --- /dev/null +++ b/API/Controllers/CRUDBase.cs @@ -0,0 +1,141 @@ +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 UserService UserService; + public readonly TService Service; + + 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)); + } + } +} diff --git a/API/Services/ServiceBase.cs b/API/Services/ServiceBase.cs index fdc26c6..aaf01de 100644 --- a/API/Services/ServiceBase.cs +++ b/API/Services/ServiceBase.cs @@ -3,6 +3,7 @@ using API.DTO; using API.Services.Interfaces; using DAL.Contexts; using DAL.Models; +using DAL.Models.Audits; using System.Linq.Expressions; namespace API.Services @@ -10,7 +11,7 @@ namespace API.Services public class ServiceBase : IGenericService where TAuthentication : IGenericAuthentication where TModel : Model - where TAudit : class + where TAudit : AuditModel where TDTO : IAdaptable { private readonly TAuthentication _auth;