AuditingHelper.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Threading.Tasks;
  6. using System.Transactions;
  7. using Abp.Collections.Extensions;
  8. using Abp.Dependency;
  9. using Abp.Domain.Uow;
  10. using Abp.Runtime.Session;
  11. using Abp.Timing;
  12. using Castle.Core.Logging;
  13. namespace Abp.Auditing
  14. {
  15. public class AuditingHelper : IAuditingHelper, ITransientDependency
  16. {
  17. public ILogger Logger { get; set; }
  18. public IAbpSession AbpSession { get; set; }
  19. public IAuditingStore AuditingStore { get; set; }
  20. private readonly IAuditInfoProvider _auditInfoProvider;
  21. private readonly IAuditingConfiguration _configuration;
  22. private readonly IUnitOfWorkManager _unitOfWorkManager;
  23. private readonly IAuditSerializer _auditSerializer;
  24. public AuditingHelper(
  25. IAuditInfoProvider auditInfoProvider,
  26. IAuditingConfiguration configuration,
  27. IUnitOfWorkManager unitOfWorkManager,
  28. IAuditSerializer auditSerializer)
  29. {
  30. _auditInfoProvider = auditInfoProvider;
  31. _configuration = configuration;
  32. _unitOfWorkManager = unitOfWorkManager;
  33. _auditSerializer = auditSerializer;
  34. AbpSession = NullAbpSession.Instance;
  35. Logger = NullLogger.Instance;
  36. AuditingStore = SimpleLogAuditingStore.Instance;
  37. }
  38. public bool ShouldSaveAudit(MethodInfo methodInfo, bool defaultValue = false)
  39. {
  40. if (!_configuration.IsEnabled)
  41. {
  42. return false;
  43. }
  44. if (!_configuration.IsEnabledForAnonymousUsers && (AbpSession?.UserId == null))
  45. {
  46. return false;
  47. }
  48. if (methodInfo == null)
  49. {
  50. return false;
  51. }
  52. if (!methodInfo.IsPublic)
  53. {
  54. return false;
  55. }
  56. if (methodInfo.IsDefined(typeof(AuditedAttribute), true))
  57. {
  58. return true;
  59. }
  60. if (methodInfo.IsDefined(typeof(DisableAuditingAttribute), true))
  61. {
  62. return false;
  63. }
  64. var classType = methodInfo.DeclaringType;
  65. if (classType != null)
  66. {
  67. if (classType.GetTypeInfo().IsDefined(typeof(AuditedAttribute), true))
  68. {
  69. return true;
  70. }
  71. if (classType.GetTypeInfo().IsDefined(typeof(DisableAuditingAttribute), true))
  72. {
  73. return false;
  74. }
  75. if (_configuration.Selectors.Any(selector => selector.Predicate(classType)))
  76. {
  77. return true;
  78. }
  79. }
  80. return defaultValue;
  81. }
  82. public AuditInfo CreateAuditInfo(Type type, MethodInfo method, object[] arguments)
  83. {
  84. return CreateAuditInfo(type, method, CreateArgumentsDictionary(method, arguments));
  85. }
  86. public AuditInfo CreateAuditInfo(Type type, MethodInfo method, IDictionary<string, object> arguments)
  87. {
  88. var auditInfo = new AuditInfo
  89. {
  90. TenantId = AbpSession.TenantId,
  91. UserId = AbpSession.UserId,
  92. ImpersonatorUserId = AbpSession.ImpersonatorUserId,
  93. ImpersonatorTenantId = AbpSession.ImpersonatorTenantId,
  94. ServiceName = type != null
  95. ? type.FullName
  96. : "",
  97. MethodName = method.Name,
  98. Parameters = ConvertArgumentsToJson(arguments),
  99. ExecutionTime = Clock.Now
  100. };
  101. try
  102. {
  103. _auditInfoProvider.Fill(auditInfo);
  104. }
  105. catch (Exception ex)
  106. {
  107. Logger.Warn(ex.ToString(), ex);
  108. }
  109. return auditInfo;
  110. }
  111. public void Save(AuditInfo auditInfo)
  112. {
  113. using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.Suppress))
  114. {
  115. AuditingStore.Save(auditInfo);
  116. uow.Complete();
  117. }
  118. }
  119. public async Task SaveAsync(AuditInfo auditInfo)
  120. {
  121. using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.Suppress))
  122. {
  123. await AuditingStore.SaveAsync(auditInfo);
  124. await uow.CompleteAsync();
  125. }
  126. }
  127. private string ConvertArgumentsToJson(IDictionary<string, object> arguments)
  128. {
  129. try
  130. {
  131. if (arguments.IsNullOrEmpty())
  132. {
  133. return "{}";
  134. }
  135. var dictionary = new Dictionary<string, object>();
  136. foreach (var argument in arguments)
  137. {
  138. if (argument.Value != null && _configuration.IgnoredTypes.Any(t => t.IsInstanceOfType(argument.Value)))
  139. {
  140. dictionary[argument.Key] = null;
  141. }
  142. else
  143. {
  144. dictionary[argument.Key] = argument.Value;
  145. }
  146. }
  147. return _auditSerializer.Serialize(dictionary);
  148. }
  149. catch (Exception ex)
  150. {
  151. Logger.Warn(ex.ToString(), ex);
  152. return "{}";
  153. }
  154. }
  155. private static Dictionary<string, object> CreateArgumentsDictionary(MethodInfo method, object[] arguments)
  156. {
  157. var parameters = method.GetParameters();
  158. var dictionary = new Dictionary<string, object>();
  159. for (var i = 0; i < parameters.Length; i++)
  160. {
  161. dictionary[parameters[i].Name] = arguments[i];
  162. }
  163. return dictionary;
  164. }
  165. }
  166. }