diff --git a/API/API.csproj b/API/API.csproj index 55d898a..8947c33 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -9,16 +9,12 @@ - + - - - - - + diff --git a/API/Authentication/Interfaces/IColorAuthentication.cs b/API/Authentication/Interfaces/IColorAuthentication.cs new file mode 100644 index 0000000..874396a --- /dev/null +++ b/API/Authentication/Interfaces/IColorAuthentication.cs @@ -0,0 +1,9 @@ +using API.DTO.Base; +using DAL.Models; + +namespace API.Authentication.Interfaces +{ + public interface IColorAuthentication : IGenericAuthentication + { + } +} diff --git a/API/Authentication/Interfaces/IGenericAuthentication.cs b/API/Authentication/Interfaces/IGenericAuthentication.cs new file mode 100644 index 0000000..74698d9 --- /dev/null +++ b/API/Authentication/Interfaces/IGenericAuthentication.cs @@ -0,0 +1,13 @@ +using DAL.Models; + +namespace API.Authentication.Interfaces +{ + public interface IGenericAuthentication + { + bool canGetAll(User user); + bool canGet(TModel model, User user); + bool canAdd(T item, User user); + bool canUpdate(TModel model, User user); + bool canDelete(TModel model, User user); + } +} diff --git a/API/DTO/Base/ColorDTO.cs b/API/DTO/Base/ColorDTO.cs new file mode 100644 index 0000000..3137cdb --- /dev/null +++ b/API/DTO/Base/ColorDTO.cs @@ -0,0 +1,26 @@ +using DAL.Models; + +namespace API.DTO.Base +{ + public class ColorDTO : IAdaptable + { + public ulong id { get; set; } + public byte red { get; set; } + public byte blue { get; set; } + public byte green { get; set; } + public string name { get; set; } = null!; + public DateTime updated { get; set; } + public ulong updater { get; set; } + public Color adaptToModel() + { + return new Color + { + id = id, + red = red, + blue = blue, + green = green, + name = name + }; + } + } +} diff --git a/API/DTO/IAdaptable.cs b/API/DTO/IAdaptable.cs new file mode 100644 index 0000000..158b5e8 --- /dev/null +++ b/API/DTO/IAdaptable.cs @@ -0,0 +1,7 @@ +namespace API.DTO +{ + public interface IAdaptable + { + TModel adaptToModel(); + } +} diff --git a/API/Program.cs b/API/Program.cs index 2b2dc68..9a1b04d 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -1,3 +1,4 @@ +using API.Services; using DAL.Contexts; using Microsoft.EntityFrameworkCore; using System.Reflection; @@ -21,10 +22,9 @@ namespace API options.IncludeXmlComments(xmlPath, true); }); - builder.Services.AddDbContext(options => - { - options.UseMySQL(builder.Configuration["connectionString"] ?? throw new InvalidOperationException("Connection String is null")); - }); + builder.Services.AddDbContext(options => { options.UseMySQL(builder.Configuration["connectionString"] ?? throw new InvalidOperationException("Connection String is null")); }); + + builder.Services.AddTransient(); WebApplication app = builder.Build(); @@ -44,4 +44,4 @@ namespace API app.Run(); } } -} \ No newline at end of file +} diff --git a/API/Services/ColorService.cs b/API/Services/ColorService.cs new file mode 100644 index 0000000..2d89af9 --- /dev/null +++ b/API/Services/ColorService.cs @@ -0,0 +1,15 @@ +using API.Authentication.Interfaces; +using API.DTO.Base; +using DAL.Contexts; +using DAL.Models; +using DAL.Models.Audits; + +namespace API.Services +{ + public class ColorService : ServiceBase + { + public ColorService(ILogger logger, SASGContext context, IColorAuthentication auth) : base(logger, context, auth) + { + } + } +} diff --git a/API/Services/Interfaces/IGenericService.cs b/API/Services/Interfaces/IGenericService.cs new file mode 100644 index 0000000..f88ac86 --- /dev/null +++ b/API/Services/Interfaces/IGenericService.cs @@ -0,0 +1,16 @@ +using DAL.Models; +using System.Linq.Expressions; + +namespace API.Services.Interfaces +{ + public interface IGenericService + { + TModel? get(ulong id, User user); + IEnumerable? get(User user, Expression>? whereClause = null); + TModel? getNoAuthentication(ulong id); + IEnumerable getNoAuthentication(Expression>? whereClause = null); + TModel? add(T item, User user); + TModel? update(TModel model, User user); + TAudit? delete(TModel model, User user); + } +} diff --git a/API/Services/ServiceBase.cs b/API/Services/ServiceBase.cs new file mode 100644 index 0000000..56f449e --- /dev/null +++ b/API/Services/ServiceBase.cs @@ -0,0 +1,115 @@ +using API.Authentication.Interfaces; +using API.DTO; +using API.Services.Interfaces; +using DAL.Contexts; +using DAL.Models; +using System.Linq.Expressions; + +namespace API.Services +{ + public class ServiceBase : IGenericService + where TAuthentication : IGenericAuthentication + where TModel : Model + where TAudit : class + where TDTO : IAdaptable + { + private readonly TAuthentication _auth; + private readonly SASGContext _context; + private readonly ILogger _logger; + + public ServiceBase(ILogger logger, SASGContext context, TAuthentication auth) + { + _logger = logger; + _context = context; + _auth = auth; + } + + public TModel? get(ulong id, User user) + { + TModel? result = _context.Set().Find(id); + if (result == null) + return null; + + return _auth.canGet(result, user) ? result : null; + } + + public IEnumerable? get(User user, Expression>? whereClause = null) + { + if (!_auth.canGetAll(user)) + return null; + + return whereClause != null ? _context.Set().Where(whereClause) : _context.Set(); + } + + public TModel? getNoAuthentication(ulong id) + { + return _context.Set().Find(id); + } + + public IEnumerable getNoAuthentication(Expression>? whereClause = null) + { + return whereClause != null ? _context.Set().Where(whereClause) : _context.Set(); + } + + public TModel? add(TDTO item, User user) + { + if (!_auth.canAdd(item, user)) + return null; + + TModel model = item.adaptToModel(); + + model.updater = user.id; + model.updated = DateTime.Now; + _context.Add(model); + _context.SaveChanges(); + + return model; + } + + public TModel? update(TModel model, User user) + { + if (!_auth.canUpdate(model, user)) + return null; + + TModel? origModel = _context.Set().Find(model.id); + if (origModel == null) + return null; + + copyToAudit(origModel); + + origModel.updated = DateTime.Now; + origModel.updater = user.id; + + _context.SaveChanges(); + + return origModel; + } + + public TAudit? delete(TModel model, User user) + { + if (!_auth.canDelete(model, user)) + return null; + + TModel? origModel = _context.Set().Find(model.id); + if (origModel == null) + return null; + + copyToAudit(origModel); + + origModel.updated = DateTime.Now; + origModel.updater = user.id; + + copyToAudit(origModel); + + _context.Remove(origModel); + _context.SaveChanges(); + + return origModel.adaptToAudit(); + } + + private void copyToAudit(TModel model) + { + _context.Set().Add(model.adaptToAudit()); + } + } +} diff --git a/DAL/Models/Audits/AuditColor.cs b/DAL/Models/Audits/AuditColor.cs index 46fc213..d67f2f2 100644 --- a/DAL/Models/Audits/AuditColor.cs +++ b/DAL/Models/Audits/AuditColor.cs @@ -7,11 +7,8 @@ namespace DAL.Models.Audits [Index("id", Name = "audit_colors_colors_id_fk")] [Table("audit_colors")] [Keyless] - public class AuditColor + public class AuditColor : AuditModel { - [Column("id")] - public ulong id { get; set; } - [Column("red")] public byte red { get; set; } @@ -24,12 +21,5 @@ namespace DAL.Models.Audits [Column("name")] [MaxLength(64)] public string name { get; set; } = null!; - - [Column("updated")] - [DataType("datetime")] - public DateTime updated { get; set; } - - [Column("updater")] - public ulong updater { get; set; } } } diff --git a/DAL/Models/Audits/AuditModel.cs b/DAL/Models/Audits/AuditModel.cs new file mode 100644 index 0000000..76b9479 --- /dev/null +++ b/DAL/Models/Audits/AuditModel.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DAL.Models.Audits +{ + public abstract class AuditModel + { + [Column("id")] + public ulong id { get; set; } + + [Column("updated")] + [DataType("datetime")] + public DateTime updated { get; set; } + + [Column("updater")] + public ulong updater { get; set; } + } +} diff --git a/DAL/Models/Color.cs b/DAL/Models/Color.cs index a2c4d65..00a3c85 100644 --- a/DAL/Models/Color.cs +++ b/DAL/Models/Color.cs @@ -7,12 +7,8 @@ namespace DAL.Models { [Table("colors")] [Index("updater", Name = "colors_users_id_fk")] - public class Color + public class Color : Model { - [Key] - [Column("id")] - public ulong id { get; set; } - [Column("red")] public byte red { get; set; } @@ -26,15 +22,13 @@ namespace DAL.Models [MaxLength(64)] public string name { get; set; } = null!; - [Column("updated")] - [DataType("datetime")] - public DateTime updated { get; set; } - - [Column("updater")] - public ulong updater { get; set; } - public User updaterRelation { get; set; } = null!; public ICollection audits { get; set; } = new List(); + + public override AuditColor adaptToAudit() + { + throw new NotImplementedException(); + } } } diff --git a/DAL/Models/Model.cs b/DAL/Models/Model.cs new file mode 100644 index 0000000..90a67f6 --- /dev/null +++ b/DAL/Models/Model.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace DAL.Models +{ + public abstract class Model + { + [Key] + [Column("id")] + public ulong id { get; set; } + + [Column("updated")] + [DataType("datetime")] + public DateTime updated { get; set; } + + [Column("updater")] + public ulong updater { get; set; } + + public abstract TAudit adaptToAudit(); + } +}