mirror of https://github.com/abpframework/abp.git
committed by
GitHub
9 changed files with 249 additions and 3 deletions
@ -0,0 +1,26 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class AbpHubContext |
||||
|
{ |
||||
|
public IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
public Hub Hub { get; } |
||||
|
|
||||
|
public MethodInfo HubMethod { get; } |
||||
|
|
||||
|
public IReadOnlyList<object> HubMethodArguments { get; } |
||||
|
|
||||
|
public AbpHubContext(IServiceProvider serviceProvider, Hub hub, MethodInfo hubMethod, IReadOnlyList<object> hubMethodArguments) |
||||
|
{ |
||||
|
ServiceProvider = serviceProvider; |
||||
|
Hub = hub; |
||||
|
HubMethod = hubMethod; |
||||
|
HubMethodArguments = hubMethodArguments; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class AbpHubContextAccessorHubFilter : IHubFilter |
||||
|
{ |
||||
|
public virtual async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next) |
||||
|
{ |
||||
|
var hubContextAccessor = invocationContext.ServiceProvider.GetRequiredService<IAbpHubContextAccessor>(); |
||||
|
using (hubContextAccessor.Change(new AbpHubContext( |
||||
|
invocationContext.ServiceProvider, |
||||
|
invocationContext.Hub, |
||||
|
invocationContext.HubMethod, |
||||
|
invocationContext.HubMethodArguments))) |
||||
|
{ |
||||
|
return await next(invocationContext); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.SignalR; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.Auditing; |
||||
|
using Volo.Abp.Uow; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR.Auditing |
||||
|
{ |
||||
|
public class AbpAuditHubFilter : IHubFilter |
||||
|
{ |
||||
|
public virtual async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next) |
||||
|
{ |
||||
|
var options = invocationContext.ServiceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value; |
||||
|
if (!options.IsEnabled) |
||||
|
{ |
||||
|
return await next(invocationContext); |
||||
|
} |
||||
|
|
||||
|
var hasError = false; |
||||
|
var auditingManager = invocationContext.ServiceProvider.GetRequiredService<IAuditingManager>(); |
||||
|
using (var saveHandle = auditingManager.BeginScope()) |
||||
|
{ |
||||
|
Debug.Assert(auditingManager.Current != null); |
||||
|
object result; |
||||
|
try |
||||
|
{ |
||||
|
result = await next(invocationContext); |
||||
|
|
||||
|
if (auditingManager.Current.Log.Exceptions.Any()) |
||||
|
{ |
||||
|
hasError = true; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
hasError = true; |
||||
|
|
||||
|
if (!auditingManager.Current.Log.Exceptions.Contains(ex)) |
||||
|
{ |
||||
|
auditingManager.Current.Log.Exceptions.Add(ex); |
||||
|
} |
||||
|
|
||||
|
throw; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
if (ShouldWriteAuditLog(invocationContext.ServiceProvider, hasError)) |
||||
|
{ |
||||
|
var unitOfWorkManager = invocationContext.ServiceProvider.GetRequiredService<IUnitOfWorkManager>(); |
||||
|
if (unitOfWorkManager.Current != null) |
||||
|
{ |
||||
|
await unitOfWorkManager.Current.SaveChangesAsync(); |
||||
|
} |
||||
|
|
||||
|
await saveHandle.SaveAsync(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private bool ShouldWriteAuditLog(IServiceProvider serviceProvider, bool hasError) |
||||
|
{ |
||||
|
var options = serviceProvider.GetRequiredService<IOptions<AbpAuditingOptions>>().Value; |
||||
|
if (options.AlwaysLogOnException && hasError) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
if (!options.IsEnabledForAnonymousUsers && !serviceProvider.GetRequiredService<ICurrentUser>().IsAuthenticated) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var auditingManager = serviceProvider.GetRequiredService<IAuditingManager>(); |
||||
|
if (auditingManager.Current == null || |
||||
|
auditingManager.Current.Log.Actions.IsNullOrEmpty()) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System.Linq; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.AspNetCore.WebClientInfo; |
||||
|
using Volo.Abp.Auditing; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR.Auditing |
||||
|
{ |
||||
|
public class AspNetCoreSignalRAuditLogContributor : AuditLogContributor, ITransientDependency |
||||
|
{ |
||||
|
public ILogger<AspNetCoreSignalRAuditLogContributor> Logger { get; set; } |
||||
|
|
||||
|
public AspNetCoreSignalRAuditLogContributor() |
||||
|
{ |
||||
|
Logger = NullLogger<AspNetCoreSignalRAuditLogContributor>.Instance; |
||||
|
} |
||||
|
|
||||
|
public override void PreContribute(AuditLogContributionContext context) |
||||
|
{ |
||||
|
var hubContext = context.ServiceProvider.GetRequiredService<IAbpHubContextAccessor>().Context; |
||||
|
if (hubContext == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var clientInfoProvider = context.ServiceProvider.GetRequiredService<IWebClientInfoProvider>(); |
||||
|
if (context.AuditInfo.ClientIpAddress == null) |
||||
|
{ |
||||
|
context.AuditInfo.ClientIpAddress = clientInfoProvider.ClientIpAddress; |
||||
|
} |
||||
|
|
||||
|
if (context.AuditInfo.BrowserInfo == null) |
||||
|
{ |
||||
|
context.AuditInfo.BrowserInfo = clientInfoProvider.BrowserInfo; |
||||
|
} |
||||
|
|
||||
|
//TODO: context.AuditInfo.ClientName
|
||||
|
} |
||||
|
|
||||
|
public override void PostContribute(AuditLogContributionContext context) |
||||
|
{ |
||||
|
var hubContext = context.ServiceProvider.GetRequiredService<IAbpHubContextAccessor>().Context; |
||||
|
if (hubContext == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var firstAction = context.AuditInfo.Actions.FirstOrDefault(); |
||||
|
context.AuditInfo.Url = firstAction?.ServiceName + "." + firstAction?.MethodName; |
||||
|
context.AuditInfo.HttpStatusCode = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public class DefaultAbpHubContextAccessor : IAbpHubContextAccessor, ISingletonDependency |
||||
|
{ |
||||
|
public AbpHubContext Context => _currentHubContext.Value; |
||||
|
|
||||
|
private readonly AsyncLocal<AbpHubContext> _currentHubContext = new AsyncLocal<AbpHubContext>(); |
||||
|
|
||||
|
public virtual IDisposable Change(AbpHubContext context) |
||||
|
{ |
||||
|
var parent = Context; |
||||
|
_currentHubContext.Value = context; |
||||
|
return new DisposeAction(() => |
||||
|
{ |
||||
|
_currentHubContext.Value = parent; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.SignalR |
||||
|
{ |
||||
|
public interface IAbpHubContextAccessor |
||||
|
{ |
||||
|
AbpHubContext Context { get; } |
||||
|
|
||||
|
IDisposable Change(AbpHubContext context); |
||||
|
} |
||||
|
} |
||||
|
|
||||
Loading…
Reference in new issue