From 2d4230c001777ea51851ffcec64b976840132207 Mon Sep 17 00:00:00 2001 From: Mole Date: Fri, 8 Nov 2024 08:58:38 +0100 Subject: [PATCH] Include create date in audit item (#17447) --- src/Umbraco.Core/Models/AuditItem.cs | 15 ++++++++ .../Repositories/Implement/AuditRepository.cs | 12 +++--- .../Repositories/AuditRepositoryTest.cs | 38 ++++++++++++++++++- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Models/AuditItem.cs b/src/Umbraco.Core/Models/AuditItem.cs index bbfca724aa..7b4eff86e6 100644 --- a/src/Umbraco.Core/Models/AuditItem.cs +++ b/src/Umbraco.Core/Models/AuditItem.cs @@ -7,6 +7,21 @@ public sealed class AuditItem : EntityBase, IAuditItem /// /// Initializes a new instance of the class. /// + public AuditItem(int objectId, AuditType type, int userId, string? entityType, DateTime createDate, string? comment = null, string? parameters = null) + { + DisableChangeTracking(); + + Id = objectId; + Comment = comment; + AuditType = type; + UserId = userId; + EntityType = entityType; + Parameters = parameters; + CreateDate = createDate; + + EnableChangeTracking(); + } + public AuditItem(int objectId, AuditType type, int userId, string? entityType, string? comment = null, string? parameters = null) { DisableChangeTracking(); diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/AuditRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/AuditRepository.cs index f11e17a236..09fa3d1029 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/AuditRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/AuditRepository.cs @@ -29,7 +29,7 @@ internal class AuditRepository : EntityRepositoryBase, IAuditRe List? dtos = Database.Fetch(sql); - return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList(); + return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Datestamp, x.Comment, x.Parameters)).ToList(); } public void CleanLogs(int maximumAgeOfLogsInMinutes) @@ -104,7 +104,7 @@ internal class AuditRepository : EntityRepositoryBase, IAuditRe totalRecords = page.TotalItems; var items = page.Items.Select( - dto => new AuditItem(dto.NodeId, Enum.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters)).ToList(); + dto => new AuditItem(dto.NodeId, Enum.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Datestamp, dto.Comment, dto.Parameters)).ToList(); // map the DateStamp for (var i = 0; i < items.Count; i++) @@ -144,12 +144,12 @@ internal class AuditRepository : EntityRepositoryBase, IAuditRe protected override IAuditItem? PerformGet(int id) { Sql sql = GetBaseQuery(false); - sql.Where(GetBaseWhereClause(), new { Id = id }); + sql.Where(GetBaseWhereClause(), new { id = id }); LogDto? dto = Database.First(sql); return dto == null ? null - : new AuditItem(dto.NodeId, Enum.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters); + : new AuditItem(dto.NodeId, Enum.Parse(dto.Header), dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Datestamp, dto.Comment, dto.Parameters); } protected override IEnumerable PerformGetAll(params int[]? ids) => throw new NotImplementedException(); @@ -162,7 +162,7 @@ internal class AuditRepository : EntityRepositoryBase, IAuditRe List? dtos = Database.Fetch(sql); - return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Comment, x.Parameters)).ToList(); + return dtos.Select(x => new AuditItem(x.NodeId, Enum.Parse(x.Header), x.UserId ?? Constants.Security.UnknownUserId, x.EntityType, x.Datestamp, x.Comment, x.Parameters)).ToList(); } protected override Sql GetBaseQuery(bool isCount) @@ -184,7 +184,7 @@ internal class AuditRepository : EntityRepositoryBase, IAuditRe return sql; } - protected override string GetBaseWhereClause() => "id = @id"; + protected override string GetBaseWhereClause() => "umbracoLog.id = @id"; protected override IEnumerable GetDeleteClauses() => throw new NotImplementedException(); } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs index 57f484adf2..8e7eed1f28 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/AuditRepositoryTest.cs @@ -1,11 +1,11 @@ // Copyright (c) Umbraco. // See LICENSE for more details. -using System.Linq; using Microsoft.Extensions.Logging; using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Persistence.Repositories; using Umbraco.Cms.Infrastructure.Persistence; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; @@ -24,6 +24,10 @@ public class AuditRepositoryTest : UmbracoIntegrationTest private ILogger _logger; + private IAuditRepository AuditRepository => GetRequiredService(); + + private IAuditItem GetAuditItem(int id) => new AuditItem(id, AuditType.System, -1, UmbracoObjectTypes.Document.GetName(), "This is a System audit trail"); + [Test] public void Can_Add_Audit_Entry() { @@ -40,6 +44,38 @@ public class AuditRepositoryTest : UmbracoIntegrationTest } } + [Test] + public void Has_Create_Date_When_Get_By_Id() + { + using var scope = ScopeProvider.CreateScope(); + + AuditRepository.Save(GetAuditItem(1)); + var auditEntry = AuditRepository.Get(1); + Assert.That(auditEntry.CreateDate, Is.Not.EqualTo(default(DateTime))); + } + + [Test] + public void Has_Create_Date_When_Get_By_Query() + { + using var scope = ScopeProvider.CreateScope(); + + AuditRepository.Save(GetAuditItem(1)); + var auditEntry = AuditRepository.Get(AuditType.System, ScopeProvider.CreateQuery().Where(x => x.Id == 1)).FirstOrDefault(); + Assert.That(auditEntry, Is.Not.Null); + Assert.That(auditEntry.CreateDate, Is.Not.EqualTo(default(DateTime))); + } + + [Test] + public void Has_Create_Date_When_Get_By_Paged_Query() + { + using var scope = ScopeProvider.CreateScope(); + + AuditRepository.Save(GetAuditItem(1)); + var auditEntry = AuditRepository.GetPagedResultsByQuery(ScopeProvider.CreateQuery().Where(x => x.Id == 1),0, 10, out long total, Direction.Ascending, null, null).FirstOrDefault(); + Assert.That(auditEntry, Is.Not.Null); + Assert.That(auditEntry.CreateDate, Is.Not.EqualTo(default(DateTime))); + } + [Test] public void Get_Paged_Items() {