diff --git a/FoodsharingSiegen.Contracts/Entity/Audit.cs b/FoodsharingSiegen.Contracts/Entity/Audit.cs index 2646f2f..0e6d3e5 100644 --- a/FoodsharingSiegen.Contracts/Entity/Audit.cs +++ b/FoodsharingSiegen.Contracts/Entity/Audit.cs @@ -12,7 +12,7 @@ namespace FoodsharingSiegen.Contracts.Entity /// /// Gets or sets the value of the created (ab) /// - public DateTime? Created { get; set; } + public DateTime Created { get; set; } /// /// Gets or sets the value of the data 1 (ab) diff --git a/FoodsharingSiegen.Server/Data/AuditHelper.cs b/FoodsharingSiegen.Server/Data/AuditHelper.cs new file mode 100644 index 0000000..0f36d78 --- /dev/null +++ b/FoodsharingSiegen.Server/Data/AuditHelper.cs @@ -0,0 +1,40 @@ +using FoodsharingSiegen.Contracts.Entity; + +namespace FoodsharingSiegen.Server.Data +{ + public static class AuditHelper + { + public static string CreateText(Audit audit) + { + switch (audit.Type) + { + case AuditType.SaveProfile: + return "hat das eigene Profil gespeichert."; + case AuditType.SetOwnPassword: + return "hat das eigene Passwort geändert."; + case AuditType.CreateUser: + return $"hat den User {audit.Data1} erstellt."; + case AuditType.UpdateUser: + return $"hat den User {audit.Data1} gespeichert."; + case AuditType.RemoveUser: + return $"hat den User {audit.Data1} gelöscht."; + case AuditType.SetUserPassword: + return $"hat das Passwort von {audit.Data1} geändert."; + case AuditType.CreateProspect: + return $"hat den Neuling {audit.Data1} erstellt."; + case AuditType.EditProspect: + return $"hat den Neuling {audit.Data1} bearbeitet."; + case AuditType.AddInteraction: + return $"hat dem Neuling {audit.Data1} folgendes hinzugefügt: {audit.Data2}"; + case AuditType.RemoveInteraction: + return $"hat eine Interaktion bei {audit.Data1} gelöscht."; + break; + case AuditType.None: + default: + return $"{audit.Data1}, {audit.Data2}"; + } + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Data/Service/AuditService.cs b/FoodsharingSiegen.Server/Data/Service/AuditService.cs index ad46c9b..cbeeaa5 100644 --- a/FoodsharingSiegen.Server/Data/Service/AuditService.cs +++ b/FoodsharingSiegen.Server/Data/Service/AuditService.cs @@ -1,6 +1,7 @@ using FoodsharingSiegen.Contracts; using FoodsharingSiegen.Contracts.Entity; using FoodsharingSiegen.Server.Auth; +using Microsoft.EntityFrameworkCore; namespace FoodsharingSiegen.Server.Data.Service { @@ -36,6 +37,7 @@ namespace FoodsharingSiegen.Server.Data.Service { var audit = new Audit { + Created = DateTime.Now, Type = type, UserID = CurrentUser?.Id, Data1 = data1, @@ -66,11 +68,11 @@ namespace FoodsharingSiegen.Server.Data.Service /// The count /// The type /// A task containing an operation result of list audit - public async Task>> Load(int count, AuditType? type) + public async Task>> Load(int count, AuditType? type = null) { try { - var query = Context.Audits?.OrderBy(x => x.Created).AsQueryable(); + var query = Context.Audits?.Include(x => x.User).OrderByDescending(x => x.Created).AsQueryable(); if (count > 0) query = query?.Take(count); diff --git a/FoodsharingSiegen.Server/Data/Service/ProspectService.cs b/FoodsharingSiegen.Server/Data/Service/ProspectService.cs index 7385771..387baab 100644 --- a/FoodsharingSiegen.Server/Data/Service/ProspectService.cs +++ b/FoodsharingSiegen.Server/Data/Service/ProspectService.cs @@ -46,6 +46,8 @@ namespace FoodsharingSiegen.Server.Data.Service await Context.SaveChangesAsync(); + await AuditService.Insert(AuditType.AddInteraction, targetProspect.Name, interaction.Type.ToString()); + // Detatch entities Context.Entry(targetProspect).State = EntityState.Detached; Context.Entry(interaction).State = EntityState.Detached; @@ -130,6 +132,8 @@ namespace FoodsharingSiegen.Server.Data.Service Context.Interactions.Remove(new Interaction { Id = interactionId }); await Context.SaveChangesAsync(); + await AuditService.Insert(AuditType.RemoveInteraction, "?"); + return new OperationResult(); } catch (Exception e) @@ -161,6 +165,8 @@ namespace FoodsharingSiegen.Server.Data.Service var saveR = await Context.SaveChangesAsync(); if(saveR < 1) return new OperationResult(new Exception("Fehler beim speichern")); + + await AuditService.Insert(AuditType.EditProspect, prospect.Name); return new OperationResult(); } catch (Exception e) diff --git a/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.Designer.cs b/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.Designer.cs new file mode 100644 index 0000000..9e61d00 --- /dev/null +++ b/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.Designer.cs @@ -0,0 +1,195 @@ +// +using System; +using FoodsharingSiegen.Server.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace FoodsharingSiegen.Server.Migrations +{ + [DbContext(typeof(FsContext))] + [Migration("20220523083959_AuditDate")] + partial class AuditDate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.1"); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Data1") + .HasColumnType("TEXT"); + + b.Property("Data2") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UserID") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserID"); + + b.ToTable("Audits"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Interaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Alert") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Info") + .HasColumnType("TEXT"); + + b.Property("NotNeeded") + .HasColumnType("INTEGER"); + + b.Property("ProspectID") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UserID") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ProspectID"); + + b.HasIndex("UserID"); + + b.ToTable("Interactions"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Prospect", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("FsId") + .HasColumnType("INTEGER"); + + b.Property("Memo") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Prospects"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("EncryptedPassword") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ForceLogout") + .HasColumnType("INTEGER"); + + b.Property("Groups") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Mail") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Memo") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Verified") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Audit", b => + { + b.HasOne("FoodsharingSiegen.Contracts.Entity.User", "User") + .WithMany() + .HasForeignKey("UserID"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Interaction", b => + { + b.HasOne("FoodsharingSiegen.Contracts.Entity.Prospect", "Prospect") + .WithMany("Interactions") + .HasForeignKey("ProspectID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FoodsharingSiegen.Contracts.Entity.User", "User") + .WithMany("Interactions") + .HasForeignKey("UserID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Prospect"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.Prospect", b => + { + b.Navigation("Interactions"); + }); + + modelBuilder.Entity("FoodsharingSiegen.Contracts.Entity.User", b => + { + b.Navigation("Interactions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.cs b/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.cs new file mode 100644 index 0000000..da9ce94 --- /dev/null +++ b/FoodsharingSiegen.Server/Migrations/20220523083959_AuditDate.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace FoodsharingSiegen.Server.Migrations +{ + public partial class AuditDate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Created", + table: "Audits", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + oldClrType: typeof(DateTime), + oldType: "TEXT", + oldNullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Created", + table: "Audits", + type: "TEXT", + nullable: true, + oldClrType: typeof(DateTime), + oldType: "TEXT"); + } + } +} diff --git a/FoodsharingSiegen.Server/Migrations/FsContextModelSnapshot.cs b/FoodsharingSiegen.Server/Migrations/FsContextModelSnapshot.cs index 5b44231..d405483 100644 --- a/FoodsharingSiegen.Server/Migrations/FsContextModelSnapshot.cs +++ b/FoodsharingSiegen.Server/Migrations/FsContextModelSnapshot.cs @@ -23,7 +23,7 @@ namespace FoodsharingSiegen.Server.Migrations .ValueGeneratedOnAdd() .HasColumnType("TEXT"); - b.Property("Created") + b.Property("Created") .HasColumnType("TEXT"); b.Property("Data1") diff --git a/FoodsharingSiegen.Server/Pages/AuditView.razor b/FoodsharingSiegen.Server/Pages/AuditView.razor new file mode 100644 index 0000000..3b9f1ad --- /dev/null +++ b/FoodsharingSiegen.Server/Pages/AuditView.razor @@ -0,0 +1,25 @@ +@page "/audit" + +@using FoodsharingSiegen.Server.BaseClasses +@using FoodsharingSiegen.Contracts.Entity +@using FoodsharingSiegen.Server.Data +@using FoodsharingSiegen.Server.Data.Service + +@inherits FsBase + +Aktivitäten + +

Aktivitäten

+ + + + + + + @((context as Audit).User?.Name) @(AuditHelper.CreateText(context)) + + + + \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Pages/AuditView.razor.cs b/FoodsharingSiegen.Server/Pages/AuditView.razor.cs new file mode 100644 index 0000000..2b9a1b9 --- /dev/null +++ b/FoodsharingSiegen.Server/Pages/AuditView.razor.cs @@ -0,0 +1,46 @@ +using FoodsharingSiegen.Contracts.Entity; +using FoodsharingSiegen.Server.Data.Service; +using Microsoft.AspNetCore.Components; + +namespace FoodsharingSiegen.Server.Pages +{ + /// + /// The audit view class (a. beging, 23.05.2022) + /// + public partial class AuditView + { + #region Dependencies (Injected) + + /// + /// Gets or sets the value of the audit service (ab) + /// + [Inject] public AuditService? AuditService { get; set; } + + #endregion + + #region Public Properties + + /// + /// Gets or sets the value of the audits (ab) + /// + private List? Audits { get; set; } + + #endregion + + #region Override OnInitializedAsync + + /// + /// Ons the initialized (a. beging, 23.05.2022) + /// + protected override async Task OnInitializedAsync() + { + var loadR = await AuditService?.Load(100)!; + if (loadR.Success) + Audits = loadR.Data; + + await base.OnInitializedAsync(); + } + + #endregion + } +} \ No newline at end of file diff --git a/FoodsharingSiegen.Server/Pages/Profile.razor b/FoodsharingSiegen.Server/Pages/Profile.razor index 94a328d..e4f226c 100644 --- a/FoodsharingSiegen.Server/Pages/Profile.razor +++ b/FoodsharingSiegen.Server/Pages/Profile.razor @@ -9,7 +9,7 @@

Mein Profil

- + diff --git a/FoodsharingSiegen.Server/Shared/NavMenu.razor b/FoodsharingSiegen.Server/Shared/NavMenu.razor index 17864db..70b1dd9 100644 --- a/FoodsharingSiegen.Server/Shared/NavMenu.razor +++ b/FoodsharingSiegen.Server/Shared/NavMenu.razor @@ -24,6 +24,11 @@ Benutzer
+