From c1ac80653b4ea0c751515c8ee768957e6ce351e0 Mon Sep 17 00:00:00 2001
From: Laura Neto <12862535+lauraneto@users.noreply.github.com>
Date: Thu, 24 Jul 2025 14:52:17 +0200
Subject: [PATCH] Use audit service instead of repository directly in services
(#19357)
* Introduce new AuditEntryService
- Moved logic related to the IAuditEntryRepository from the AuditService to the new service
- Introduced new Async methods
- Using ids (for easier transition from the previous Write method)
- Using keys
- Moved and updated integration tests related to the audit entries to a new test class `AuditEntryServiceTests`
- Added unit tests class `AuditEntryServiceTests` and added a few unit tests
- Added migration to add columns for `performingUserKey` and `affectedUserKey` and convert existing user ids
- Adjusted usages of the old AuditService.Write method to use the new one (mostly notification handlers)
* Audit service rework
- Added new async and paged methods
- Marked (now) redundant methods as obsolete
- Updated all of the usages to use the non-obsolete methods
- Added unit tests class `AuditServiceTests` and some unit tests
- Updated existing integration test
* Use the audit service instead of the repository directly in services
* Apply suggestions from code review
* Small improvement
* Update src/Umbraco.Core/Services/AuditService.cs
* Some minor adjustments following the merge
* Delete unnecessary file
* Small cleanup on the tests
* Remove changing user id to 0 (on audit) if user id is admin in media bulk save
* Remove reference to unused IUserIdKeyResolver in TemplateService
* Remove references to unused IShortStringHelper and GlobalSettings in FileService
---
src/Umbraco.Core/Services/AuditService.cs | 40 ++----
.../ContentBlueprintContainerService.cs | 4 +-
src/Umbraco.Core/Services/ContentService.cs | 49 +++++---
.../Services/ContentTypeContainerService.cs | 4 +-
.../Services/ContentTypeService.cs | 63 +++++++++-
...peServiceBaseOfTRepositoryTItemTService.cs | 47 +++++++-
.../Services/ContentVersionService.cs | 21 ++--
.../Services/DataTypeContainerService.cs | 4 +-
src/Umbraco.Core/Services/DataTypeService.cs | 114 ++++++++++++------
.../Services/DictionaryItemService.cs | 24 ++--
.../Services/EntityTypeContainerService.cs | 20 +--
src/Umbraco.Core/Services/FileService.cs | 94 +++++++++++++--
.../Services/FileServiceOperationBase.cs | 42 +++++--
src/Umbraco.Core/Services/LanguageService.cs | 21 ++--
.../Services/LocalizationService.cs | 5 -
src/Umbraco.Core/Services/MediaService.cs | 78 +++++++++++-
.../Services/MediaTypeContainerService.cs | 4 +-
src/Umbraco.Core/Services/MediaTypeService.cs | 67 +++++++++-
src/Umbraco.Core/Services/MemberService.cs | 81 ++++++++++++-
.../Services/MemberTypeService.cs | 63 +++++++++-
.../Services/PartialViewService.cs | 51 +++++++-
src/Umbraco.Core/Services/RelationService.cs | 77 ++++++++++--
src/Umbraco.Core/Services/ScriptService.cs | 47 +++++++-
.../Services/StylesheetService.cs | 47 +++++++-
src/Umbraco.Core/Services/TemplateService.cs | 74 +++++++++---
.../Services/AuditServiceTests.cs | 14 +--
26 files changed, 942 insertions(+), 213 deletions(-)
diff --git a/src/Umbraco.Core/Services/AuditService.cs b/src/Umbraco.Core/Services/AuditService.cs
index 342e62a004..33893dfd5d 100644
--- a/src/Umbraco.Core/Services/AuditService.cs
+++ b/src/Umbraco.Core/Services/AuditService.cs
@@ -16,9 +16,9 @@ namespace Umbraco.Cms.Core.Services.Implement;
///
public sealed class AuditService : RepositoryService, IAuditService
{
+ private readonly IUserIdKeyResolver _userIdKeyResolver;
private readonly IAuditRepository _auditRepository;
private readonly IEntityService _entityService;
- private readonly IUserService _userService;
///
/// Initializes a new instance of the class.
@@ -28,37 +28,15 @@ public sealed class AuditService : RepositoryService, IAuditService
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IAuditRepository auditRepository,
- IUserService userService,
+ IUserIdKeyResolver userIdKeyResolver,
IEntityService entityService)
: base(provider, loggerFactory, eventMessagesFactory)
{
_auditRepository = auditRepository;
- _userService = userService;
+ _userIdKeyResolver = userIdKeyResolver;
_entityService = entityService;
}
- ///
- /// Initializes a new instance of the class.
- ///
- [Obsolete("Use the non-obsolete constructor. Scheduled for removal in Umbraco 19.")]
- public AuditService(
- ICoreScopeProvider provider,
- ILoggerFactory loggerFactory,
- IEventMessagesFactory eventMessagesFactory,
- IAuditRepository auditRepository,
- IAuditEntryRepository auditEntryRepository,
- IUserService userService,
- IEntityService entityService)
- : this(
- provider,
- loggerFactory,
- eventMessagesFactory,
- auditRepository,
- userService,
- entityService)
- {
- }
-
///
public async Task> AddAsync(
AuditType type,
@@ -68,7 +46,9 @@ public sealed class AuditService : RepositoryService, IAuditService
string? comment = null,
string? parameters = null)
{
- var userId = (await _userService.GetAsync(userKey))?.Id;
+ int? userId = await _userIdKeyResolver.TryGetAsync(userKey) is { Success: true } userIdAttempt
+ ? userIdAttempt.Result
+ : null;
if (userId is null)
{
return Attempt.Fail(AuditLogOperationStatus.UserNotFound);
@@ -245,8 +225,7 @@ public sealed class AuditService : RepositoryService, IAuditService
ArgumentOutOfRangeException.ThrowIfNegative(skip);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(take);
- IUser? user = await _userService.GetAsync(userKey);
- if (user is null)
+ if (await _userIdKeyResolver.TryGetAsync(userKey) is not { Success: true } userIdAttempt)
{
return new PagedModel();
}
@@ -256,7 +235,7 @@ public sealed class AuditService : RepositoryService, IAuditService
sinceDate.HasValue ? Query().Where(x => x.CreateDate >= sinceDate) : null;
PagedModel result = GetItemsByUserInner(
- user.Id,
+ userIdAttempt.Result,
pageIndex,
pageSize,
orderDirection,
@@ -418,7 +397,7 @@ public sealed class AuditService : RepositoryService, IAuditService
AuditType[]? auditTypeFilter = null,
IQuery? customFilter = null)
{
- if (userId is < Constants.Security.SuperUserId)
+ if (userId < Constants.Security.SuperUserId)
{
return new PagedModel { Items = [], Total = 0 };
}
@@ -434,3 +413,4 @@ public sealed class AuditService : RepositoryService, IAuditService
scope.Complete();
}
}
+
diff --git a/src/Umbraco.Core/Services/ContentBlueprintContainerService.cs b/src/Umbraco.Core/Services/ContentBlueprintContainerService.cs
index e8d742b70e..046c475632 100644
--- a/src/Umbraco.Core/Services/ContentBlueprintContainerService.cs
+++ b/src/Umbraco.Core/Services/ContentBlueprintContainerService.cs
@@ -13,10 +13,10 @@ internal sealed class ContentBlueprintContainerService : EntityTypeContainerServ
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IDocumentBlueprintContainerRepository entityContainerRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IEntityRepository entityRepository,
IUserIdKeyResolver userIdKeyResolver)
- : base(provider, loggerFactory, eventMessagesFactory, entityContainerRepository, auditRepository, entityRepository, userIdKeyResolver)
+ : base(provider, loggerFactory, eventMessagesFactory, entityContainerRepository, auditService, entityRepository, userIdKeyResolver)
{
}
diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index 0c3b61a1c3..246682ec14 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.Services;
///
public class ContentService : RepositoryService, IContentService
{
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IContentTypeRepository _contentTypeRepository;
private readonly IDocumentBlueprintRepository _documentBlueprintRepository;
private readonly IDocumentRepository _documentRepository;
@@ -52,7 +52,7 @@ public class ContentService : RepositoryService, IContentService
IEventMessagesFactory eventMessagesFactory,
IDocumentRepository documentRepository,
IEntityRepository entityRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IContentTypeRepository contentTypeRepository,
IDocumentBlueprintRepository documentBlueprintRepository,
ILanguageRepository languageRepository,
@@ -68,7 +68,7 @@ public class ContentService : RepositoryService, IContentService
{
_documentRepository = documentRepository;
_entityRepository = entityRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_contentTypeRepository = contentTypeRepository;
_documentBlueprintRepository = documentBlueprintRepository;
_languageRepository = languageRepository;
@@ -87,8 +87,7 @@ public class ContentService : RepositoryService, IContentService
_logger = loggerFactory.CreateLogger();
}
- [Obsolete("Use non-obsolete constructor. Scheduled for removal in V17.")]
-
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public ContentService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -104,14 +103,16 @@ public class ContentService : RepositoryService, IContentService
ICultureImpactFactory cultureImpactFactory,
IUserIdKeyResolver userIdKeyResolver,
PropertyEditorCollection propertyEditorCollection,
- IIdKeyMap idKeyMap)
+ IIdKeyMap idKeyMap,
+ IOptionsMonitor optionsMonitor,
+ IRelationService relationService)
: this(
provider,
loggerFactory,
eventMessagesFactory,
documentRepository,
entityRepository,
- auditRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
contentTypeRepository,
documentBlueprintRepository,
languageRepository,
@@ -121,11 +122,12 @@ public class ContentService : RepositoryService, IContentService
userIdKeyResolver,
propertyEditorCollection,
idKeyMap,
- StaticServiceProvider.Instance.GetRequiredService>(),
- StaticServiceProvider.Instance.GetRequiredService())
+ optionsMonitor,
+ relationService)
{
}
- [Obsolete("Use non-obsolete constructor. Scheduled for removal in V17.")]
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public ContentService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -133,6 +135,7 @@ public class ContentService : RepositoryService, IContentService
IDocumentRepository documentRepository,
IEntityRepository entityRepository,
IAuditRepository auditRepository,
+ IAuditService auditService,
IContentTypeRepository contentTypeRepository,
IDocumentBlueprintRepository documentBlueprintRepository,
ILanguageRepository languageRepository,
@@ -140,14 +143,17 @@ public class ContentService : RepositoryService, IContentService
IShortStringHelper shortStringHelper,
ICultureImpactFactory cultureImpactFactory,
IUserIdKeyResolver userIdKeyResolver,
- PropertyEditorCollection propertyEditorCollection)
+ PropertyEditorCollection propertyEditorCollection,
+ IIdKeyMap idKeyMap,
+ IOptionsMonitor optionsMonitor,
+ IRelationService relationService)
: this(
provider,
loggerFactory,
eventMessagesFactory,
documentRepository,
entityRepository,
- auditRepository,
+ auditService,
contentTypeRepository,
documentBlueprintRepository,
languageRepository,
@@ -156,7 +162,9 @@ public class ContentService : RepositoryService, IContentService
cultureImpactFactory,
userIdKeyResolver,
propertyEditorCollection,
- StaticServiceProvider.Instance.GetRequiredService())
+ idKeyMap,
+ optionsMonitor,
+ relationService)
{
}
@@ -3084,7 +3092,20 @@ public class ContentService : RepositoryService, IContentService
#region Private Methods
private void Audit(AuditType type, int userId, int objectId, string? message = null, string? parameters = null) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, UmbracoObjectTypes.Document.GetName(), message, parameters));
+ AuditAsync(type, userId, objectId, message, parameters).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
+ {
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ UmbracoObjectTypes.Document.GetName(),
+ message,
+ parameters);
+ }
private string GetLanguageDetailsForAuditEntry(IEnumerable affectedCultures)
=> GetLanguageDetailsForAuditEntry(_languageRepository.GetMany(), affectedCultures);
diff --git a/src/Umbraco.Core/Services/ContentTypeContainerService.cs b/src/Umbraco.Core/Services/ContentTypeContainerService.cs
index a6ac5e811f..6258216c8e 100644
--- a/src/Umbraco.Core/Services/ContentTypeContainerService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeContainerService.cs
@@ -14,10 +14,10 @@ internal sealed class ContentTypeContainerService : EntityTypeContainerService
ContentService = contentService;
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public ContentTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IContentService contentService,
+ IContentTypeRepository repository,
+ IAuditRepository auditRepository,
+ IDocumentTypeContainerRepository entityContainerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ contentService,
+ repository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public ContentTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IContentService contentService,
+ IContentTypeRepository repository,
+ IAuditRepository auditRepository,
+ IAuditService auditService,
+ IDocumentTypeContainerRepository entityContainerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ contentService,
+ repository,
+ auditService,
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
protected override int[] ReadLockIds => ContentTypeLocks.ReadLockIds;
protected override int[] WriteLockIds => ContentTypeLocks.WriteLockIds;
diff --git a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
index cd72be54ab..58f3915d52 100644
--- a/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
+++ b/src/Umbraco.Core/Services/ContentTypeServiceBaseOfTRepositoryTItemTService.cs
@@ -1,6 +1,8 @@
using System.Globalization;
using System.Runtime.InteropServices;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Exceptions;
using Umbraco.Cms.Core.Models;
@@ -20,7 +22,7 @@ public abstract class ContentTypeServiceBase : ContentTypeSe
where TRepository : IContentTypeRepositoryBase
where TItem : class, IContentTypeComposition
{
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IEntityContainerRepository _containerRepository;
private readonly IEntityRepository _entityRepository;
private readonly IEventAggregator _eventAggregator;
@@ -32,7 +34,7 @@ public abstract class ContentTypeServiceBase : ContentTypeSe
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
TRepository repository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IEntityContainerRepository containerRepository,
IEntityRepository entityRepository,
IEventAggregator eventAggregator,
@@ -41,7 +43,7 @@ public abstract class ContentTypeServiceBase : ContentTypeSe
: base(provider, loggerFactory, eventMessagesFactory)
{
Repository = repository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_containerRepository = containerRepository;
_entityRepository = entityRepository;
_eventAggregator = eventAggregator;
@@ -49,6 +51,32 @@ public abstract class ContentTypeServiceBase : ContentTypeSe
_contentTypeFilters = contentTypeFilters;
}
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ protected ContentTypeServiceBase(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ TRepository repository,
+ IAuditRepository auditRepository,
+ IEntityContainerRepository containerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ containerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
protected TRepository Repository { get; }
protected abstract int[] WriteLockIds { get; }
protected abstract int[] ReadLockIds { get; }
@@ -1398,9 +1426,18 @@ public abstract class ContentTypeServiceBase : ContentTypeSe
#region Audit
- private void Audit(AuditType type, int userId, int objectId)
+ private void Audit(AuditType type, int userId, int objectId) =>
+ AuditAsync(type, userId, objectId).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId)
{
- _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetUmbracoObjectType(ContainedObjectType).GetName()));
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ ObjectTypes.GetUmbracoObjectType(ContainedObjectType).GetName());
}
#endregion
diff --git a/src/Umbraco.Core/Services/ContentVersionService.cs b/src/Umbraco.Core/Services/ContentVersionService.cs
index d6562351d7..5dddaad709 100644
--- a/src/Umbraco.Core/Services/ContentVersionService.cs
+++ b/src/Umbraco.Core/Services/ContentVersionService.cs
@@ -15,7 +15,7 @@ namespace Umbraco.Cms.Core.Services;
internal sealed class ContentVersionService : IContentVersionService
{
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IContentVersionCleanupPolicy _contentVersionCleanupPolicy;
private readonly IDocumentVersionRepository _documentVersionRepository;
private readonly IEventMessagesFactory _eventMessagesFactory;
@@ -32,7 +32,7 @@ internal sealed class ContentVersionService : IContentVersionService
IContentVersionCleanupPolicy contentVersionCleanupPolicy,
ICoreScopeProvider scopeProvider,
IEventMessagesFactory eventMessagesFactory,
- IAuditRepository auditRepository,
+ IAuditService auditService,
ILanguageRepository languageRepository,
IEntityService entityService,
IContentService contentService,
@@ -43,7 +43,7 @@ internal sealed class ContentVersionService : IContentVersionService
_contentVersionCleanupPolicy = contentVersionCleanupPolicy;
_scopeProvider = scopeProvider;
_eventMessagesFactory = eventMessagesFactory;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_languageRepository = languageRepository;
_entityService = entityService;
_contentService = contentService;
@@ -299,16 +299,19 @@ internal sealed class ContentVersionService : IContentVersionService
return versionsToDelete;
}
- private void Audit(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
+ private void Audit(AuditType type, int userId, int objectId, string? message = null, string? parameters = null) =>
+ AuditAsync(type, userId, objectId, message, parameters).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
{
- var entry = new AuditItem(
- objectId,
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
type,
- userId,
+ userKey,
+ objectId,
UmbracoObjectTypes.Document.GetName(),
message,
parameters);
-
- _auditRepository.Save(entry);
}
}
diff --git a/src/Umbraco.Core/Services/DataTypeContainerService.cs b/src/Umbraco.Core/Services/DataTypeContainerService.cs
index 0e6292f7f1..8b892226ef 100644
--- a/src/Umbraco.Core/Services/DataTypeContainerService.cs
+++ b/src/Umbraco.Core/Services/DataTypeContainerService.cs
@@ -13,10 +13,10 @@ internal sealed class DataTypeContainerService : EntityTypeContainerService _idKeyMap;
- [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
public DataTypeService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IDataTypeRepository dataTypeRepository,
IDataValueEditorFactory dataValueEditorFactory,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IContentTypeRepository contentTypeRepository,
+ IMediaTypeRepository mediaTypeRepository,
+ IMemberTypeRepository memberTypeRepository,
IIOHelper ioHelper,
Lazy idKeyMap)
- : this(
- provider,
- loggerFactory,
- eventMessagesFactory,
- dataTypeRepository,
- dataValueEditorFactory,
- auditRepository,
- contentTypeRepository,
- StaticServiceProvider.Instance.GetRequiredService(),
- StaticServiceProvider.Instance.GetRequiredService(),
- ioHelper,
- idKeyMap)
+ : base(provider, loggerFactory, eventMessagesFactory)
{
+ _dataValueEditorFactory = dataValueEditorFactory;
+ _dataTypeRepository = dataTypeRepository;
+ _auditService = auditService;
+ _contentTypeRepository = contentTypeRepository;
+ _mediaTypeRepository = mediaTypeRepository;
+ _memberTypeRepository = memberTypeRepository;
+ _ioHelper = ioHelper;
+ _idKeyMap = idKeyMap;
+
+ // resolve dependencies for obsolete methods through the static service provider, so they don't pollute the constructor signature
+ _dataTypeContainerService = StaticServiceProvider.Instance.GetRequiredService();
+ _dataTypeContainerRepository = StaticServiceProvider.Instance.GetRequiredService();
+ _userIdKeyResolver = StaticServiceProvider.Instance.GetRequiredService();
}
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public DataTypeService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -71,21 +75,48 @@ namespace Umbraco.Cms.Core.Services.Implement
IMemberTypeRepository memberTypeRepository,
IIOHelper ioHelper,
Lazy idKeyMap)
- : base(provider, loggerFactory, eventMessagesFactory)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ dataTypeRepository,
+ dataValueEditorFactory,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ contentTypeRepository,
+ mediaTypeRepository,
+ memberTypeRepository,
+ ioHelper,
+ idKeyMap)
{
- _dataValueEditorFactory = dataValueEditorFactory;
- _dataTypeRepository = dataTypeRepository;
- _auditRepository = auditRepository;
- _contentTypeRepository = contentTypeRepository;
- _mediaTypeRepository = mediaTypeRepository;
- _memberTypeRepository = memberTypeRepository;
- _ioHelper = ioHelper;
- _idKeyMap = idKeyMap;
+ }
- // resolve dependencies for obsolete methods through the static service provider, so they don't pollute the constructor signature
- _dataTypeContainerService = StaticServiceProvider.Instance.GetRequiredService();
- _dataTypeContainerRepository = StaticServiceProvider.Instance.GetRequiredService();
- _userIdKeyResolver = StaticServiceProvider.Instance.GetRequiredService();
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public DataTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IDataTypeRepository dataTypeRepository,
+ IDataValueEditorFactory dataValueEditorFactory,
+ IAuditRepository auditRepository,
+ IAuditService auditService,
+ IContentTypeRepository contentTypeRepository,
+ IMediaTypeRepository mediaTypeRepository,
+ IMemberTypeRepository memberTypeRepository,
+ IIOHelper ioHelper,
+ Lazy idKeyMap)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ dataTypeRepository,
+ dataValueEditorFactory,
+ auditService,
+ contentTypeRepository,
+ mediaTypeRepository,
+ memberTypeRepository,
+ ioHelper,
+ idKeyMap)
+ {
}
#region Containers
@@ -474,8 +505,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Notifications.Publish(new DataTypeMovedNotification(moveEventInfo, eventMessages).WithStateFrom(movingDataTypeNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Move, currentUserId, toMove.Id);
+ await AuditAsync(AuditType.Move, userKey, toMove.Id);
scope.Complete();
}
@@ -597,7 +627,7 @@ namespace Umbraco.Cms.Core.Services.Implement
: DataTypeOperationStatus.Success;
},
userKey,
- AuditType.New);
+ AuditType.Save);
///
/// Saves a collection of
@@ -705,8 +735,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Notifications.Publish(new DataTypeDeletedNotification(dataType, eventMessages).WithStateFrom(deletingDataTypeNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Delete, currentUserId, dataType.Id);
+ await AuditAsync(AuditType.Delete, userKey, dataType.Id);
scope.Complete();
@@ -902,7 +931,7 @@ namespace Umbraco.Cms.Core.Services.Implement
scope.Notifications.Publish(new DataTypeSavedNotification(dataType, eventMessages).WithStateFrom(savingDataTypeNotification));
- Audit(auditType, currentUserId, dataType.Id);
+ await AuditAsync(auditType, userKey, dataType.Id);
scope.Complete();
return Attempt.SucceedWithStatus(DataTypeOperationStatus.Success, dataType);
@@ -915,7 +944,20 @@ namespace Umbraco.Cms.Core.Services.Implement
{ Result: var intId } => _dataTypeRepository.Get(intId),
};
- private void Audit(AuditType type, int userId, int objectId)
- => _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.DataType)));
+ private void Audit(AuditType type, int userId, int objectId) =>
+ AuditAsync(type, userId, objectId).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId)
+ {
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+ await AuditAsync(type, userKey, objectId);
+ }
+
+ private async Task AuditAsync(AuditType type, Guid userKey, int objectId) =>
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ UmbracoObjectTypes.DataType.GetName());
}
}
diff --git a/src/Umbraco.Core/Services/DictionaryItemService.cs b/src/Umbraco.Core/Services/DictionaryItemService.cs
index 467f4ea26a..c8cb2605b5 100644
--- a/src/Umbraco.Core/Services/DictionaryItemService.cs
+++ b/src/Umbraco.Core/Services/DictionaryItemService.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Cms.Core.Services;
internal sealed class DictionaryItemService : RepositoryService, IDictionaryItemService
{
private readonly IDictionaryRepository _dictionaryRepository;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly ILanguageService _languageService;
private readonly IUserIdKeyResolver _userIdKeyResolver;
@@ -21,13 +21,13 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IDictionaryRepository dictionaryRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
ILanguageService languageService,
IUserIdKeyResolver userIdKeyResolver)
: base(provider, loggerFactory, eventMessagesFactory)
{
_dictionaryRepository = dictionaryRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_languageService = languageService;
_userIdKeyResolver = userIdKeyResolver;
}
@@ -199,8 +199,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
new DictionaryItemDeletedNotification(dictionaryItem, eventMessages)
.WithStateFrom(deletingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Delete, "Delete DictionaryItem", currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
+ await AuditAsync(AuditType.Delete, "Delete DictionaryItem", userKey, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();
return Attempt.SucceedWithStatus(DictionaryItemOperationStatus.Success, dictionaryItem);
@@ -261,8 +260,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
scope.Notifications.Publish(
new DictionaryItemMovedNotification(moveEventInfo, eventMessages).WithStateFrom(movingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Move, "Move DictionaryItem", currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
+ await AuditAsync(AuditType.Move, "Move DictionaryItem", userKey, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();
return Attempt.SucceedWithStatus(DictionaryItemOperationStatus.Success, dictionaryItem);
@@ -322,8 +320,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
scope.Notifications.Publish(
new DictionaryItemSavedNotification(dictionaryItem, eventMessages).WithStateFrom(savingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(auditType, auditMessage, currentUserId, dictionaryItem.Id, nameof(DictionaryItem));
+ await AuditAsync(auditType, auditMessage, userKey, dictionaryItem.Id, nameof(DictionaryItem));
scope.Complete();
return Attempt.SucceedWithStatus(DictionaryItemOperationStatus.Success, dictionaryItem);
@@ -339,8 +336,13 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
}
}
- private void Audit(AuditType type, string message, int userId, int objectId, string? entityType) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, entityType, message));
+ private async Task AuditAsync(AuditType type, string message, Guid userKey, int objectId, string? entityType) =>
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ entityType,
+ message);
private bool HasValidParent(IDictionaryItem dictionaryItem)
=> dictionaryItem.ParentId.HasValue == false || _dictionaryRepository.Get(dictionaryItem.ParentId.Value) != null;
diff --git a/src/Umbraco.Core/Services/EntityTypeContainerService.cs b/src/Umbraco.Core/Services/EntityTypeContainerService.cs
index 575ff11f2e..46532ad067 100644
--- a/src/Umbraco.Core/Services/EntityTypeContainerService.cs
+++ b/src/Umbraco.Core/Services/EntityTypeContainerService.cs
@@ -14,7 +14,7 @@ internal abstract class EntityTypeContainerService _auditRepository.Save(new AuditItem(objectId, type, userId, ContainerObjectType.GetName()));
+ private async Task AuditAsync(AuditType type, Guid userKey, int objectId) =>
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ ContainerObjectType.GetName());
private void ReadLock(ICoreScope scope)
{
diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs
index eae1944b5d..cf0873c2e8 100644
--- a/src/Umbraco.Core/Services/FileService.cs
+++ b/src/Umbraco.Core/Services/FileService.cs
@@ -1,7 +1,9 @@
using System.Text.RegularExpressions;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Models;
@@ -22,7 +24,7 @@ namespace Umbraco.Cms.Core.Services;
public class FileService : RepositoryService, IFileService
{
private const string PartialViewHeader = "@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage";
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IPartialViewRepository _partialViewRepository;
private readonly IScriptRepository _scriptRepository;
@@ -31,6 +33,31 @@ public class FileService : RepositoryService, IFileService
private readonly ITemplateRepository _templateRepository;
private readonly IUserIdKeyResolver _userIdKeyResolver;
+ public FileService(
+ ICoreScopeProvider uowProvider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IStylesheetRepository stylesheetRepository,
+ IScriptRepository scriptRepository,
+ IPartialViewRepository partialViewRepository,
+ IAuditService auditService,
+ IHostingEnvironment hostingEnvironment,
+ ITemplateService templateService,
+ ITemplateRepository templateRepository,
+ IUserIdKeyResolver userIdKeyResolver)
+ : base(uowProvider, loggerFactory, eventMessagesFactory)
+ {
+ _stylesheetRepository = stylesheetRepository;
+ _scriptRepository = scriptRepository;
+ _partialViewRepository = partialViewRepository;
+ _auditService = auditService;
+ _hostingEnvironment = hostingEnvironment;
+ _templateService = templateService;
+ _templateRepository = templateRepository;
+ _userIdKeyResolver = userIdKeyResolver;
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public FileService(
ICoreScopeProvider uowProvider,
ILoggerFactory loggerFactory,
@@ -45,16 +72,50 @@ public class FileService : RepositoryService, IFileService
IUserIdKeyResolver userIdKeyResolver,
IShortStringHelper shortStringHelper,
IOptions globalSettings)
- : base(uowProvider, loggerFactory, eventMessagesFactory)
+ : this(
+ uowProvider,
+ loggerFactory,
+ eventMessagesFactory,
+ stylesheetRepository,
+ scriptRepository,
+ partialViewRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ hostingEnvironment,
+ templateService,
+ templateRepository,
+ userIdKeyResolver)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public FileService(
+ ICoreScopeProvider uowProvider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IStylesheetRepository stylesheetRepository,
+ IScriptRepository scriptRepository,
+ IPartialViewRepository partialViewRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ IHostingEnvironment hostingEnvironment,
+ ITemplateService templateService,
+ ITemplateRepository templateRepository,
+ IUserIdKeyResolver userIdKeyResolver,
+ IShortStringHelper shortStringHelper,
+ IOptions globalSettings)
+ : this(
+ uowProvider,
+ loggerFactory,
+ eventMessagesFactory,
+ stylesheetRepository,
+ scriptRepository,
+ partialViewRepository,
+ auditService,
+ hostingEnvironment,
+ templateService,
+ templateRepository,
+ userIdKeyResolver)
{
- _stylesheetRepository = stylesheetRepository;
- _scriptRepository = scriptRepository;
- _partialViewRepository = partialViewRepository;
- _auditRepository = auditRepository;
- _hostingEnvironment = hostingEnvironment;
- _templateService = templateService;
- _templateRepository = templateRepository;
- _userIdKeyResolver = userIdKeyResolver;
}
#region Stylesheets
@@ -70,7 +131,18 @@ public class FileService : RepositoryService, IFileService
}
private void Audit(AuditType type, int userId, int objectId, string? entityType) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, entityType));
+ AuditAsync(type, userId, objectId, entityType).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? entityType)
+ {
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ entityType);
+ }
///
[Obsolete("Please use IStylesheetService for stylesheet operations - will be removed in Umbraco 15")]
diff --git a/src/Umbraco.Core/Services/FileServiceOperationBase.cs b/src/Umbraco.Core/Services/FileServiceOperationBase.cs
index e7b392d949..88501af28a 100644
--- a/src/Umbraco.Core/Services/FileServiceOperationBase.cs
+++ b/src/Umbraco.Core/Services/FileServiceOperationBase.cs
@@ -1,4 +1,6 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
@@ -16,14 +18,41 @@ public abstract class FileServiceOperationBase _logger;
private readonly IUserIdKeyResolver _userIdKeyResolver;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
- protected FileServiceOperationBase(ICoreScopeProvider provider, ILoggerFactory loggerFactory, IEventMessagesFactory eventMessagesFactory, TRepository repository, ILogger logger, IUserIdKeyResolver userIdKeyResolver, IAuditRepository auditRepository)
+ protected FileServiceOperationBase(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ TRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService)
: base(provider, loggerFactory, eventMessagesFactory, repository)
{
_logger = logger;
_userIdKeyResolver = userIdKeyResolver;
- _auditRepository = auditRepository;
+ _auditService = auditService;
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ protected FileServiceOperationBase(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ TRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditRepository auditRepository)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
}
protected abstract TOperationStatus Success { get; }
@@ -249,10 +278,7 @@ public abstract class FileServiceOperationBase await _auditService.AddAsync(type, userKey, -1, EntityType);
private string GetFilePath(string? parentPath, string fileName)
=> Path.Join(parentPath, fileName);
diff --git a/src/Umbraco.Core/Services/LanguageService.cs b/src/Umbraco.Core/Services/LanguageService.cs
index 01a249dbd0..e32b2c988e 100644
--- a/src/Umbraco.Core/Services/LanguageService.cs
+++ b/src/Umbraco.Core/Services/LanguageService.cs
@@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.Services;
internal sealed class LanguageService : RepositoryService, ILanguageService
{
private readonly ILanguageRepository _languageRepository;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IUserIdKeyResolver _userIdKeyResolver;
private readonly IIsoCodeValidator _isoCodeValidator;
@@ -22,13 +22,13 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
ILanguageRepository languageRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IUserIdKeyResolver userIdKeyResolver,
IIsoCodeValidator isoCodeValidator)
: base(provider, loggerFactory, eventMessagesFactory)
{
_languageRepository = languageRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_userIdKeyResolver = userIdKeyResolver;
_isoCodeValidator = isoCodeValidator;
}
@@ -160,8 +160,7 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
scope.Notifications.Publish(
new LanguageDeletedNotification(language, eventMessages).WithStateFrom(deletingLanguageNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Delete, "Delete Language", currentUserId, language.Id, UmbracoObjectTypes.Language.GetName());
+ await AuditAsync(AuditType.Delete, "Delete Language", userKey, language.Id, UmbracoObjectTypes.Language.GetName());
scope.Complete();
return Attempt.SucceedWithStatus(LanguageOperationStatus.Success, language);
}
@@ -213,16 +212,20 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
scope.Notifications.Publish(
new LanguageSavedNotification(language, eventMessages).WithStateFrom(savingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(auditType, auditMessage, currentUserId, language.Id, UmbracoObjectTypes.Language.GetName());
+ await AuditAsync(auditType, auditMessage, userKey, language.Id, UmbracoObjectTypes.Language.GetName());
scope.Complete();
return Attempt.SucceedWithStatus(LanguageOperationStatus.Success, language);
}
}
- private void Audit(AuditType type, string message, int userId, int objectId, string? entityType) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, entityType, message));
+ private async Task AuditAsync(AuditType type, string message, Guid userKey, int objectId, string? entityType) =>
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ entityType,
+ message);
private bool HasInvalidFallbackLanguage(ILanguage language)
{
diff --git a/src/Umbraco.Core/Services/LocalizationService.cs b/src/Umbraco.Core/Services/LocalizationService.cs
index 989b8f8206..0e0d2ad922 100644
--- a/src/Umbraco.Core/Services/LocalizationService.cs
+++ b/src/Umbraco.Core/Services/LocalizationService.cs
@@ -17,7 +17,6 @@ namespace Umbraco.Cms.Core.Services;
[Obsolete("Please use ILanguageService and IDictionaryItemService for localization. Will be removed in V15.")]
internal class LocalizationService : RepositoryService, ILocalizationService
{
- private readonly IAuditRepository _auditRepository;
private readonly IDictionaryRepository _dictionaryRepository;
private readonly ILanguageRepository _languageRepository;
private readonly ILanguageService _languageService;
@@ -30,14 +29,12 @@ internal class LocalizationService : RepositoryService, ILocalizationService
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IDictionaryRepository dictionaryRepository,
- IAuditRepository auditRepository,
ILanguageRepository languageRepository)
: this(
provider,
loggerFactory,
eventMessagesFactory,
dictionaryRepository,
- auditRepository,
languageRepository,
StaticServiceProvider.Instance.GetRequiredService(),
StaticServiceProvider.Instance.GetRequiredService(),
@@ -51,7 +48,6 @@ internal class LocalizationService : RepositoryService, ILocalizationService
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IDictionaryRepository dictionaryRepository,
- IAuditRepository auditRepository,
ILanguageRepository languageRepository,
ILanguageService languageService,
IDictionaryItemService dictionaryItemService,
@@ -59,7 +55,6 @@ internal class LocalizationService : RepositoryService, ILocalizationService
: base(provider, loggerFactory, eventMessagesFactory)
{
_dictionaryRepository = dictionaryRepository;
- _auditRepository = auditRepository;
_languageRepository = languageRepository;
_languageService = languageService;
_dictionaryItemService = dictionaryItemService;
diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs
index f2ee90696b..2ff78811f3 100644
--- a/src/Umbraco.Core/Services/MediaService.cs
+++ b/src/Umbraco.Core/Services/MediaService.cs
@@ -1,5 +1,7 @@
using System.Globalization;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
@@ -22,7 +24,7 @@ namespace Umbraco.Cms.Core.Services
{
private readonly IMediaRepository _mediaRepository;
private readonly IMediaTypeRepository _mediaTypeRepository;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IEntityRepository _entityRepository;
private readonly IShortStringHelper _shortStringHelper;
private readonly IUserIdKeyResolver _userIdKeyResolver;
@@ -37,7 +39,7 @@ namespace Umbraco.Cms.Core.Services
ILoggerFactory loggerFactory,
IEventMessagesFactory eventMessagesFactory,
IMediaRepository mediaRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IMediaTypeRepository mediaTypeRepository,
IEntityRepository entityRepository,
IShortStringHelper shortStringHelper,
@@ -46,13 +48,66 @@ namespace Umbraco.Cms.Core.Services
{
_mediaFileManager = mediaFileManager;
_mediaRepository = mediaRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_mediaTypeRepository = mediaTypeRepository;
_entityRepository = entityRepository;
_shortStringHelper = shortStringHelper;
_userIdKeyResolver = userIdKeyResolver;
}
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MediaService(
+ ICoreScopeProvider provider,
+ MediaFileManager mediaFileManager,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMediaRepository mediaRepository,
+ IAuditRepository auditRepository,
+ IMediaTypeRepository mediaTypeRepository,
+ IEntityRepository entityRepository,
+ IShortStringHelper shortStringHelper,
+ IUserIdKeyResolver userIdKeyResolver)
+ : this(
+ provider,
+ mediaFileManager,
+ loggerFactory,
+ eventMessagesFactory,
+ mediaRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ mediaTypeRepository,
+ entityRepository,
+ shortStringHelper,
+ userIdKeyResolver)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MediaService(
+ ICoreScopeProvider provider,
+ MediaFileManager mediaFileManager,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMediaRepository mediaRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ IMediaTypeRepository mediaTypeRepository,
+ IEntityRepository entityRepository,
+ IShortStringHelper shortStringHelper,
+ IUserIdKeyResolver userIdKeyResolver)
+ : this(
+ provider,
+ mediaFileManager,
+ loggerFactory,
+ eventMessagesFactory,
+ mediaRepository,
+ auditService,
+ mediaTypeRepository,
+ entityRepository,
+ shortStringHelper,
+ userIdKeyResolver)
+ {
+ }
+
#endregion
#region Count
@@ -788,7 +843,7 @@ namespace Umbraco.Cms.Core.Services
scope.Notifications.Publish(new MediaSavedNotification(mediasA, messages).WithStateFrom(savingNotification));
// TODO: See note about suppressing events in content service
scope.Notifications.Publish(new MediaTreeChangeNotification(treeChanges, messages));
- Audit(AuditType.Save, userId == -1 ? 0 : userId, Constants.System.Root, "Bulk save media");
+ Audit(AuditType.Save, userId, Constants.System.Root, "Bulk save media");
scope.Complete();
}
@@ -1235,9 +1290,20 @@ namespace Umbraco.Cms.Core.Services
#region Private Methods
- private void Audit(AuditType type, int userId, int objectId, string? message = null)
+ private void Audit(AuditType type, int userId, int objectId, string? message = null) =>
+ AuditAsync(type, userId, objectId, message).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
{
- _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.Media), message));
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ UmbracoObjectTypes.Media.GetName(),
+ message,
+ parameters);
}
#endregion
diff --git a/src/Umbraco.Core/Services/MediaTypeContainerService.cs b/src/Umbraco.Core/Services/MediaTypeContainerService.cs
index 6aeb9af484..548b38b70d 100644
--- a/src/Umbraco.Core/Services/MediaTypeContainerService.cs
+++ b/src/Umbraco.Core/Services/MediaTypeContainerService.cs
@@ -14,10 +14,10 @@ internal sealed class MediaTypeContainerService : EntityTypeContainerService MediaService = mediaService;
+ contentTypeFilters)
+ {
+ MediaService = mediaService;
+ }
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MediaTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMediaService mediaService,
+ IMediaTypeRepository mediaTypeRepository,
+ IAuditRepository auditRepository,
+ IMediaTypeContainerRepository entityContainerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ mediaService,
+ mediaTypeRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MediaTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMediaService mediaService,
+ IMediaTypeRepository mediaTypeRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ IMediaTypeContainerRepository entityContainerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ mediaService,
+ mediaTypeRepository,
+ auditService,
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
protected override int[] ReadLockIds => MediaTypeLocks.ReadLockIds;
diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs
index e88881be42..588eefcc96 100644
--- a/src/Umbraco.Core/Services/MemberService.cs
+++ b/src/Umbraco.Core/Services/MemberService.cs
@@ -1,4 +1,6 @@
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Membership;
@@ -19,9 +21,10 @@ namespace Umbraco.Cms.Core.Services
private readonly IMemberRepository _memberRepository;
private readonly IMemberTypeRepository _memberTypeRepository;
private readonly IMemberGroupRepository _memberGroupRepository;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IMemberGroupService _memberGroupService;
private readonly Lazy _idKeyMap;
+ private readonly IUserIdKeyResolver _userIdKeyResolver;
#region Constructor
@@ -33,18 +36,72 @@ namespace Umbraco.Cms.Core.Services
IMemberRepository memberRepository,
IMemberTypeRepository memberTypeRepository,
IMemberGroupRepository memberGroupRepository,
- IAuditRepository auditRepository,
- Lazy idKeyMap)
+ IAuditService auditService,
+ Lazy idKeyMap,
+ IUserIdKeyResolver userIdKeyResolver)
: base(provider, loggerFactory, eventMessagesFactory)
{
_memberRepository = memberRepository;
_memberTypeRepository = memberTypeRepository;
_memberGroupRepository = memberGroupRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_idKeyMap = idKeyMap;
+ _userIdKeyResolver = userIdKeyResolver;
_memberGroupService = memberGroupService ?? throw new ArgumentNullException(nameof(memberGroupService));
}
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MemberService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMemberGroupService memberGroupService,
+ IMemberRepository memberRepository,
+ IMemberTypeRepository memberTypeRepository,
+ IMemberGroupRepository memberGroupRepository,
+ IAuditRepository auditRepository,
+ Lazy idKeyMap)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ memberGroupService,
+ memberRepository,
+ memberTypeRepository,
+ memberGroupRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ idKeyMap,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MemberService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMemberGroupService memberGroupService,
+ IMemberRepository memberRepository,
+ IMemberTypeRepository memberTypeRepository,
+ IMemberGroupRepository memberGroupRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ Lazy idKeyMap,
+ IUserIdKeyResolver userIdKeyResolver)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ memberGroupService,
+ memberRepository,
+ memberTypeRepository,
+ memberGroupRepository,
+ auditService,
+ idKeyMap,
+ userIdKeyResolver)
+ {
+ }
+
#endregion
#region Count
@@ -1139,7 +1196,21 @@ namespace Umbraco.Cms.Core.Services
#region Private Methods
- private void Audit(AuditType type, int userId, int objectId, string? message = null) => _auditRepository.Save(new AuditItem(objectId, type, userId, ObjectTypes.GetName(UmbracoObjectTypes.Member), message));
+ private void Audit(AuditType type, int userId, int objectId, string? message = null) =>
+ AuditAsync(type, userId, objectId, message).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
+ {
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ UmbracoObjectTypes.Member.GetName(),
+ message,
+ parameters);
+ }
private IMember? GetMemberFromRepository(Guid id)
=> _idKeyMap.Value.GetIdForKey(id, UmbracoObjectTypes.Member) switch
diff --git a/src/Umbraco.Core/Services/MemberTypeService.cs b/src/Umbraco.Core/Services/MemberTypeService.cs
index c8313ad618..228a10a026 100644
--- a/src/Umbraco.Core/Services/MemberTypeService.cs
+++ b/src/Umbraco.Core/Services/MemberTypeService.cs
@@ -1,4 +1,6 @@
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
@@ -20,7 +22,7 @@ public class MemberTypeService : ContentTypeServiceBase(),
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public MemberTypeService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IMemberService memberService,
+ IMemberTypeRepository memberTypeRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ IMemberTypeContainerRepository entityContainerRepository,
+ IEntityRepository entityRepository,
+ IEventAggregator eventAggregator,
+ IUserIdKeyResolver userIdKeyResolver,
+ ContentTypeFilterCollection contentTypeFilters)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ memberService,
+ memberTypeRepository,
+ auditService,
+ entityContainerRepository,
+ entityRepository,
+ eventAggregator,
+ userIdKeyResolver,
+ contentTypeFilters)
+ {
+ }
+
// beware! order is important to avoid deadlocks
protected override int[] ReadLockIds { get; } = { Constants.Locks.MemberTypes };
diff --git a/src/Umbraco.Core/Services/PartialViewService.cs b/src/Umbraco.Core/Services/PartialViewService.cs
index 9543f45f28..043eac5ac4 100644
--- a/src/Umbraco.Core/Services/PartialViewService.cs
+++ b/src/Umbraco.Core/Services/PartialViewService.cs
@@ -1,4 +1,6 @@
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
@@ -14,6 +16,19 @@ public class PartialViewService : FileServiceOperationBase logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService,
+ PartialViewSnippetCollection snippetCollection)
+ : base(provider, loggerFactory, eventMessagesFactory, repository, logger, userIdKeyResolver, auditService)
+ => _snippetCollection = snippetCollection;
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public PartialViewService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -23,8 +38,40 @@ public class PartialViewService : FileServiceOperationBase _snippetCollection = snippetCollection;
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ snippetCollection)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public PartialViewService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IPartialViewRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ PartialViewSnippetCollection snippetCollection)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ auditService,
+ snippetCollection)
+ {
+ }
protected override string[] AllowedFileExtensions { get; } = { ".cshtml" };
diff --git a/src/Umbraco.Core/Services/RelationService.cs b/src/Umbraco.Core/Services/RelationService.cs
index 456a3bb8dc..35adb2e217 100644
--- a/src/Umbraco.Core/Services/RelationService.cs
+++ b/src/Umbraco.Core/Services/RelationService.cs
@@ -1,4 +1,6 @@
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
@@ -13,7 +15,7 @@ namespace Umbraco.Cms.Core.Services;
public class RelationService : RepositoryService, IRelationService
{
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly IUserIdKeyResolver _userIdKeyResolver;
private readonly IEntityService _entityService;
private readonly IRelationRepository _relationRepository;
@@ -26,17 +28,62 @@ public class RelationService : RepositoryService, IRelationService
IEntityService entityService,
IRelationRepository relationRepository,
IRelationTypeRepository relationTypeRepository,
- IAuditRepository auditRepository,
+ IAuditService auditService,
IUserIdKeyResolver userIdKeyResolver)
: base(uowProvider, loggerFactory, eventMessagesFactory)
{
_relationRepository = relationRepository;
_relationTypeRepository = relationTypeRepository;
- _auditRepository = auditRepository;
+ _auditService = auditService;
_userIdKeyResolver = userIdKeyResolver;
_entityService = entityService ?? throw new ArgumentNullException(nameof(entityService));
}
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public RelationService(
+ ICoreScopeProvider uowProvider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IEntityService entityService,
+ IRelationRepository relationRepository,
+ IRelationTypeRepository relationTypeRepository,
+ IAuditRepository auditRepository,
+ IUserIdKeyResolver userIdKeyResolver)
+ : this(
+ uowProvider,
+ loggerFactory,
+ eventMessagesFactory,
+ entityService,
+ relationRepository,
+ relationTypeRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ userIdKeyResolver)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public RelationService(
+ ICoreScopeProvider uowProvider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IEntityService entityService,
+ IRelationRepository relationRepository,
+ IRelationTypeRepository relationTypeRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ IUserIdKeyResolver userIdKeyResolver)
+ : this(
+ uowProvider,
+ loggerFactory,
+ eventMessagesFactory,
+ entityService,
+ relationRepository,
+ relationTypeRepository,
+ auditService,
+ userIdKeyResolver)
+ {
+ }
+
///
public IRelation? GetById(int id)
{
@@ -601,8 +648,7 @@ public class RelationService : RepositoryService, IRelationService
}
_relationTypeRepository.Save(relationType);
- var currentUser = await _userIdKeyResolver.GetAsync(userKey);
- Audit(auditType, currentUser, relationType.Id, auditMessage);
+ await AuditAsync(auditType, userKey, relationType.Id, auditMessage);
scope.Complete();
scope.Notifications.Publish(
new RelationTypeSavedNotification(relationType, eventMessages).WithStateFrom(savingNotification));
@@ -666,8 +712,7 @@ public class RelationService : RepositoryService, IRelationService
}
_relationTypeRepository.Delete(relationType);
- var currentUser = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Delete, currentUser, relationType.Id, "Deleted relation type");
+ await AuditAsync(AuditType.Delete, userKey, relationType.Id, "Deleted relation type");
scope.Notifications.Publish(new RelationTypeDeletedNotification(relationType, eventMessages).WithStateFrom(deletingNotification));
scope.Complete();
return Attempt.SucceedWithStatus(RelationTypeOperationStatus.Success, relationType);
@@ -744,7 +789,23 @@ public class RelationService : RepositoryService, IRelationService
}
private void Audit(AuditType type, int userId, int objectId, string? message = null) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, UmbracoObjectTypes.RelationType.GetName(), message));
+ AuditAsync(type, userId, objectId, message).GetAwaiter().GetResult();
+
+ private async Task AuditAsync(AuditType type, int userId, int objectId, string? message = null, string? parameters = null)
+ {
+ Guid userKey = await _userIdKeyResolver.GetAsync(userId);
+
+ await AuditAsync(type, userKey, objectId, message, parameters);
+ }
+
+ private async Task AuditAsync(AuditType type, Guid userKey, int objectId, string? message = null, string? parameters = null) =>
+ await _auditService.AddAsync(
+ type,
+ userKey,
+ objectId,
+ UmbracoObjectTypes.RelationType.GetName(),
+ message,
+ parameters);
#endregion
}
diff --git a/src/Umbraco.Core/Services/ScriptService.cs b/src/Umbraco.Core/Services/ScriptService.cs
index e64822c1e1..91a89298b2 100644
--- a/src/Umbraco.Core/Services/ScriptService.cs
+++ b/src/Umbraco.Core/Services/ScriptService.cs
@@ -1,4 +1,6 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
@@ -10,6 +12,19 @@ namespace Umbraco.Cms.Core.Services;
public class ScriptService : FileServiceOperationBase, IScriptService
{
+ public ScriptService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IScriptRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService)
+ : base(provider, loggerFactory, eventMessagesFactory, repository, logger, userIdKeyResolver, auditService)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public ScriptService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -18,7 +33,35 @@ public class ScriptService : FileServiceOperationBase logger,
IUserIdKeyResolver userIdKeyResolver,
IAuditRepository auditRepository)
- : base(provider, loggerFactory, eventMessagesFactory, repository, logger, userIdKeyResolver, auditRepository)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public ScriptService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IScriptRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService,
+ IAuditRepository auditRepository)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ auditService)
{
}
diff --git a/src/Umbraco.Core/Services/StylesheetService.cs b/src/Umbraco.Core/Services/StylesheetService.cs
index 08bab2a84a..2137de92b8 100644
--- a/src/Umbraco.Core/Services/StylesheetService.cs
+++ b/src/Umbraco.Core/Services/StylesheetService.cs
@@ -1,4 +1,6 @@
-using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
@@ -10,6 +12,19 @@ namespace Umbraco.Cms.Core.Services;
public class StylesheetService : FileServiceOperationBase, IStylesheetService
{
+ public StylesheetService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IStylesheetRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService)
+ : base(provider, loggerFactory, eventMessagesFactory, repository, logger, userIdKeyResolver, auditService)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public StylesheetService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -18,7 +33,35 @@ public class StylesheetService : FileServiceOperationBase logger,
IUserIdKeyResolver userIdKeyResolver,
IAuditRepository auditRepository)
- : base(provider, loggerFactory, eventMessagesFactory, repository, logger, userIdKeyResolver, auditRepository)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public StylesheetService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IStylesheetRepository repository,
+ ILogger logger,
+ IUserIdKeyResolver userIdKeyResolver,
+ IAuditService auditService,
+ IAuditRepository auditRepository)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ repository,
+ logger,
+ userIdKeyResolver,
+ auditService)
{
}
diff --git a/src/Umbraco.Core/Services/TemplateService.cs b/src/Umbraco.Core/Services/TemplateService.cs
index 80391c28b5..cfb70aefe5 100644
--- a/src/Umbraco.Core/Services/TemplateService.cs
+++ b/src/Umbraco.Core/Services/TemplateService.cs
@@ -1,4 +1,6 @@
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
@@ -16,11 +18,26 @@ public class TemplateService : RepositoryService, ITemplateService
{
private readonly IShortStringHelper _shortStringHelper;
private readonly ITemplateRepository _templateRepository;
- private readonly IAuditRepository _auditRepository;
+ private readonly IAuditService _auditService;
private readonly ITemplateContentParserService _templateContentParserService;
- private readonly IUserIdKeyResolver _userIdKeyResolver;
- private readonly IDefaultViewContentProvider _defaultViewContentProvider;
+ public TemplateService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IShortStringHelper shortStringHelper,
+ ITemplateRepository templateRepository,
+ IAuditService auditService,
+ ITemplateContentParserService templateContentParserService)
+ : base(provider, loggerFactory, eventMessagesFactory)
+ {
+ _shortStringHelper = shortStringHelper;
+ _templateRepository = templateRepository;
+ _auditService = auditService;
+ _templateContentParserService = templateContentParserService;
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
public TemplateService(
ICoreScopeProvider provider,
ILoggerFactory loggerFactory,
@@ -31,14 +48,38 @@ public class TemplateService : RepositoryService, ITemplateService
ITemplateContentParserService templateContentParserService,
IUserIdKeyResolver userIdKeyResolver,
IDefaultViewContentProvider defaultViewContentProvider)
- : base(provider, loggerFactory, eventMessagesFactory)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ shortStringHelper,
+ templateRepository,
+ StaticServiceProvider.Instance.GetRequiredService(),
+ templateContentParserService)
+ {
+ }
+
+ [Obsolete("Use the non-obsolete constructor instead. Scheduled removal in v19.")]
+ public TemplateService(
+ ICoreScopeProvider provider,
+ ILoggerFactory loggerFactory,
+ IEventMessagesFactory eventMessagesFactory,
+ IShortStringHelper shortStringHelper,
+ ITemplateRepository templateRepository,
+ IAuditService auditService,
+ IAuditRepository auditRepository,
+ ITemplateContentParserService templateContentParserService,
+ IUserIdKeyResolver userIdKeyResolver,
+ IDefaultViewContentProvider defaultViewContentProvider)
+ : this(
+ provider,
+ loggerFactory,
+ eventMessagesFactory,
+ shortStringHelper,
+ templateRepository,
+ auditService,
+ templateContentParserService)
{
- _shortStringHelper = shortStringHelper;
- _templateRepository = templateRepository;
- _auditRepository = auditRepository;
- _templateContentParserService = templateContentParserService;
- _userIdKeyResolver = userIdKeyResolver;
- _defaultViewContentProvider = defaultViewContentProvider;
}
///
@@ -81,8 +122,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingEvent));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.New, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
+ await Audit(AuditType.New, userKey, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
}
@@ -270,8 +310,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateSavedNotification(template, eventMessages).WithStateFrom(savingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(auditType, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
+ await Audit(auditType, userKey, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
return Attempt.SucceedWithStatus(TemplateOperationStatus.Success, template);
}
@@ -391,8 +430,8 @@ public class TemplateService : RepositoryService, ITemplateService
}
}
- private void Audit(AuditType type, int userId, int objectId, string? entityType) =>
- _auditRepository.Save(new AuditItem(objectId, type, userId, entityType));
+ private Task Audit(AuditType type, Guid userKey, int objectId, string? entityType) =>
+ _auditService.AddAsync(type, userKey, objectId, entityType);
private async Task> DeleteAsync(Func> getTemplate, Guid userKey)
{
@@ -424,8 +463,7 @@ public class TemplateService : RepositoryService, ITemplateService
scope.Notifications.Publish(
new TemplateDeletedNotification(template, eventMessages).WithStateFrom(deletingNotification));
- var currentUserId = await _userIdKeyResolver.GetAsync(userKey);
- Audit(AuditType.Delete, currentUserId, template.Id, UmbracoObjectTypes.Template.GetName());
+ await Audit(AuditType.Delete, userKey, template.Id, UmbracoObjectTypes.Template.GetName());
scope.Complete();
return Attempt.SucceedWithStatus(TemplateOperationStatus.Success, template);
}
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/AuditServiceTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/AuditServiceTests.cs
index d5fdaa7537..ed7ad3bcd4 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/AuditServiceTests.cs
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/AuditServiceTests.cs
@@ -23,7 +23,7 @@ public class AuditServiceTests
private Mock _scopeProviderMock;
private Mock _auditRepositoryMock;
private Mock _entityServiceMock;
- private Mock _userServiceMock;
+ private Mock _userIdKeyResolverMock;
[SetUp]
public void Setup()
@@ -31,14 +31,14 @@ public class AuditServiceTests
_scopeProviderMock = new Mock(MockBehavior.Strict);
_auditRepositoryMock = new Mock(MockBehavior.Strict);
_entityServiceMock = new Mock(MockBehavior.Strict);
- _userServiceMock = new Mock(MockBehavior.Strict);
+ _userIdKeyResolverMock = new Mock(MockBehavior.Strict);
_auditService = new AuditService(
_scopeProviderMock.Object,
Mock.Of(MockBehavior.Strict),
Mock.Of(MockBehavior.Strict),
_auditRepositoryMock.Object,
- _userServiceMock.Object,
+ _userIdKeyResolverMock.Object,
_entityServiceMock.Object);
}
@@ -59,10 +59,8 @@ public class AuditServiceTests
Assert.AreEqual(parameters, item.Parameters);
});
- Mock mockUser = new Mock();
- mockUser.Setup(x => x.Id).Returns(Constants.Security.SuperUserId);
-
- _userServiceMock.Setup(x => x.GetAsync(Constants.Security.SuperUserKey)).ReturnsAsync(mockUser.Object);
+ _userIdKeyResolverMock.Setup(x => x.TryGetAsync(Constants.Security.SuperUserKey))
+ .ReturnsAsync(Attempt.Succeed(Constants.Security.SuperUserId));
var result = await _auditService.AddAsync(
type,
@@ -79,7 +77,7 @@ public class AuditServiceTests
[Test]
public async Task AddAsync_Does_Not_Succeed_When_Non_Existing_User_Is_Provided()
{
- _userServiceMock.Setup(x => x.GetAsync(It.IsAny())).ReturnsAsync((IUser?)null);
+ _userIdKeyResolverMock.Setup(x => x.TryGetAsync(It.IsAny())).ReturnsAsync(Attempt.Fail());
var result = await _auditService.AddAsync(
AuditType.Publish,