diff --git a/src/Umbraco.Core/Auditing/AuditEventHandler.cs b/src/Umbraco.Core/Auditing/AuditEventHandler.cs
index ff8c1b7b7d..9cc231ce5f 100644
--- a/src/Umbraco.Core/Auditing/AuditEventHandler.cs
+++ b/src/Umbraco.Core/Auditing/AuditEventHandler.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Threading;
using System.Web;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
@@ -11,19 +12,18 @@ namespace Umbraco.Core.Auditing
{
internal class AuditEventHandler : ApplicationEventHandler
{
- private IAuditService AuditService => ApplicationContext.Current.Services.AuditService;
+ // yada we should inject these
+ private IAuditService AuditServiceInstance => ApplicationContext.Current.Services.AuditService;
+ private IUserService UserServiceInstance => ApplicationContext.Current.Services.UserService;
private IUser PerformingUser
{
get
{
- if (HttpContext.Current == null) return new User { Id = 0, Name = "(no user)", Email = "" };
-
- var httpContext = new HttpContextWrapper(HttpContext.Current);
- var identity = httpContext.GetCurrentIdentity(false);
- if (identity == null) return new User { Id = 0, Name = "(no user)", Email = "" };
-
- return ApplicationContext.Current.Services.UserService.GetUserById(Convert.ToInt32(identity.Id));
+ var identity = Thread.CurrentPrincipal?.GetUmbracoIdentity();
+ return identity == null
+ ? new User { Id = 0, Name = "(no user)", Email = "" }
+ : UserServiceInstance.GetUserById(Convert.ToInt32(identity.Id));
}
}
@@ -72,7 +72,7 @@ namespace Umbraco.Core.Auditing
foreach (var id in args.MemberIds)
{
members.TryGetValue(id, out var member);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/member", $"modified roles for member id:{id} \"{member?.Name ?? "(unknown)"}\" <{member?.Email ?? ""}>, removed {roles}");
@@ -87,7 +87,7 @@ namespace Umbraco.Core.Auditing
foreach (var id in args.MemberIds)
{
members.TryGetValue(id, out var member);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/member", $"modified roles for member id:{id} \"{member?.Name ?? "(unknown)"}\" <{member?.Email ?? ""}>, assigned {roles}");
@@ -105,7 +105,7 @@ namespace Umbraco.Core.Auditing
var sections = string.Join(", ", group.AllowedSections);
var perms = string.Join(", ", group.Permissions);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/user", $"save group id:{group.Id}:{group.Alias} \"{group.Name}\", updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}, sections: {sections}, perms: {perms}");
@@ -122,7 +122,7 @@ namespace Umbraco.Core.Auditing
var assigned = string.Join(", ", perm.AssignedPermissions);
var entity = ApplicationContext.Current.Services.EntityService.Get(perm.EntityId);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/user", $"assign group {(perm.IsDefaultPermissions ? "default " : "")}perms id:{group.Id}:{group.Alias} \"{group.Name}\", assigning {(string.IsNullOrWhiteSpace(assigned) ? "(nothing)" : assigned)} on id:{perm.EntityId} \"{entity.Name}\"");
@@ -138,7 +138,7 @@ namespace Umbraco.Core.Auditing
//var dp = string.Join(", ", member.Properties.Where(x => x.WasDirty()).Select(x => x.Alias));
var dp = string.Join(", ", ((Member) member).GetWereDirtyProperties());
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/member", $"save member id:{member.Id} \"{member.Name}\" <{member.Email}>, updating {(string.IsNullOrWhiteSpace(dp) ? "(nothing)" : dp)}");
@@ -151,7 +151,7 @@ namespace Umbraco.Core.Auditing
var members = deleteEventArgs.DeletedEntities;
foreach (var member in members)
{
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
0, null,
"umbraco/member", $"delete member id:{member.Id} \"{member.Name}\" <{member.Email}>");
@@ -171,7 +171,7 @@ namespace Umbraco.Core.Auditing
? string.Join(", ", affectedUser.Groups.Select(x => x.Alias))
: null;
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", $"save user{(sections == null ? "" : (", sections: " + sections))}{(groups == null ? "" : (", groups: " + groups))}");
@@ -183,7 +183,7 @@ namespace Umbraco.Core.Auditing
var performingUser = PerformingUser;
var affectedUsers = deleteEventArgs.DeletedEntities;
foreach (var affectedUser in affectedUsers)
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", PerformingIp,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", "delete user");
@@ -194,7 +194,7 @@ namespace Umbraco.Core.Auditing
if (args is IdentityAuditEventArgs identityArgs)
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
0, null,
"umbraco/user", "login success");
@@ -206,7 +206,7 @@ namespace Umbraco.Core.Auditing
if (args is IdentityAuditEventArgs identityArgs)
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
0, null,
"umbraco/user", "logout success");
@@ -219,7 +219,7 @@ namespace Umbraco.Core.Auditing
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
var affectedUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.AffectedUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", "password reset");
@@ -232,7 +232,7 @@ namespace Umbraco.Core.Auditing
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
var affectedUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.AffectedUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", "password change");
@@ -244,7 +244,7 @@ namespace Umbraco.Core.Auditing
if (args is IdentityAuditEventArgs identityArgs)
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
0, null,
"umbraco/user", "login failed");
@@ -257,7 +257,7 @@ namespace Umbraco.Core.Auditing
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
var affectedUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.AffectedUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", "password forgot/change");
@@ -270,7 +270,7 @@ namespace Umbraco.Core.Auditing
{
var performingUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.PerformingUser);
var affectedUser = ApplicationContext.Current.Services.UserService.GetUserById(identityArgs.AffectedUser);
- AuditService.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
+ AuditServiceInstance.Write(performingUser.Id, $"User \"{performingUser.Name}\" <{performingUser.Email}>", identityArgs.IpAddress,
DateTime.Now,
affectedUser.Id, $"User \"{affectedUser.Name}\" <{affectedUser.Email}>",
"umbraco/user", "password forgot/request");
diff --git a/src/Umbraco.Core/Persistence/Repositories/AuditEntryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/AuditEntryRepository.cs
index e48156a26d..d0dff66780 100644
--- a/src/Umbraco.Core/Persistence/Repositories/AuditEntryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/AuditEntryRepository.cs
@@ -120,5 +120,12 @@ namespace Umbraco.Core.Persistence.Repositories
records = page.TotalItems;
return page.Items.Select(AuditEntryFactory.BuildEntity);
}
+
+ ///
+ public bool IsAvailable()
+ {
+ var tables = SqlSyntax.GetTablesInSchema(Database).ToArray();
+ return tables.InvariantContains(AuditEntryDto.TableName);
+ }
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/IAuditEntryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IAuditEntryRepository.cs
index 7bf42a348e..04cb88bf43 100644
--- a/src/Umbraco.Core/Persistence/Repositories/IAuditEntryRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/IAuditEntryRepository.cs
@@ -12,5 +12,11 @@ namespace Umbraco.Core.Persistence.Repositories
/// Gets a page of entries.
///
IEnumerable GetPage(long pageIndex, int pageCount, out long records);
+
+ ///
+ /// Determines whether the repository is available.
+ ///
+ /// During an upgrade, the repository may not be available, until the table has been created.
+ bool IsAvailable();
}
}
diff --git a/src/Umbraco.Core/Services/AuditService.cs b/src/Umbraco.Core/Services/AuditService.cs
index 9b7e4928c5..240060cbae 100644
--- a/src/Umbraco.Core/Services/AuditService.cs
+++ b/src/Umbraco.Core/Services/AuditService.cs
@@ -13,9 +13,13 @@ namespace Umbraco.Core.Services
{
public sealed class AuditService : ScopeRepositoryService, IAuditService
{
+ private readonly Lazy _isAvailable;
+
public AuditService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
- { }
+ {
+ _isAvailable = new Lazy(DetermineIsAvailable);
+ }
public void Add(AuditType type, string comment, int userId, int objectId)
{
@@ -123,6 +127,8 @@ namespace Umbraco.Core.Services
EventDetails = eventDetails
};
+ if (_isAvailable.Value == false) return entry;
+
using (var uow = UowProvider.GetUnitOfWork())
{
var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
@@ -136,6 +142,8 @@ namespace Umbraco.Core.Services
///
public IEnumerable Get()
{
+ if (_isAvailable.Value == false) return Enumerable.Empty();
+
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
@@ -146,11 +154,29 @@ namespace Umbraco.Core.Services
///
public IEnumerable GetPage(long pageIndex, int pageCount, out long records)
{
+ if (_isAvailable.Value == false)
+ {
+ records = 0;
+ return Enumerable.Empty();
+ }
+
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
return repository.GetPage(pageIndex, pageCount, out records);
}
}
+
+ ///
+ /// Determines whether the repository is available.
+ ///
+ private bool DetermineIsAvailable()
+ {
+ using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
+ {
+ var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
+ return repository.IsAvailable();
+ }
+ }
}
}