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