Browse Source

Merge pull request #26048 from abpframework/maliming/tenant-connection-string-audit

Keep tenant connection string out of the audit logs
pull/26063/head
Engincan VESKE 3 days ago
committed by GitHub
parent
commit
8d68019fc9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 16
      docs/en/framework/infrastructure/audit-logging.md
  2. 2
      framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/DisableAuditingAttribute.cs
  3. 20
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs
  4. 21
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditingHelper_Tests.cs
  5. 3
      modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/ITenantAppService.cs
  6. 3
      modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs
  7. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConnectionString.cs
  8. 3
      modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs

16
docs/en/framework/infrastructure/audit-logging.md

@ -165,6 +165,22 @@ public class HomeController : AbpController
}
````
### Hiding Parameter Values
An audited action writes its parameter values into the audit log. Use `[DisableAuditing]` on a parameter when its value is sensitive:
````csharp
public class HomeController : AbpController
{
public async Task<ActionResult> SetConnectionString([DisableAuditing] string connectionString)
{
//...
}
}
````
The action is still audit logged and the parameter name is still written, but its value is replaced with `null`.
### Enable/Disable for Application Services & Methods
[Application service](../architecture/domain-driven-design/application-services.md) method calls also included into the audit log by default. You can use the `[DisableAuditing]` in service or method level.

2
framework/src/Volo.Abp.Auditing.Contracts/Volo/Abp/Auditing/DisableAuditingAttribute.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.Auditing;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter)]
public class DisableAuditingAttribute : Attribute
{
/// <summary>

20
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs

@ -178,7 +178,7 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
? type.FullName!
: "",
MethodName = method.Name,
Parameters = SerializeConvertArguments(arguments),
Parameters = SerializeConvertArguments(method, arguments),
ExecutionTime = Clock.Now
};
@ -220,6 +220,24 @@ public class AuditingHelper : IAuditingHelper, ITransientDependency
}
}
protected virtual string SerializeConvertArguments(MethodInfo method, IDictionary<string, object?> arguments)
{
var disabledParameters = method.GetParameters()
.Where(x => x.IsDefined(typeof(DisableAuditingAttribute), true))
.Select(x => x.Name)
.ToArray();
if (disabledParameters.Any())
{
arguments = arguments.ToDictionary(
x => x.Key,
x => disabledParameters.Contains(x.Key) ? null : x.Value
);
}
return SerializeConvertArguments(arguments);
}
protected virtual string SerializeConvertArguments(IDictionary<string, object?> arguments)
{
try

21
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditingHelper_Tests.cs

@ -1,7 +1,9 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NSubstitute;
using Shouldly;
using Volo.Abp.DependencyInjection;
using Xunit;
@ -125,6 +127,20 @@ public class AuditingHelper_Tests : AbpAuditingTestBase
}
}
[Fact]
public async Task Should_Not_Write_Parameter_Value_With_DisableAuditing()
{
var myAuditedObject = GetRequiredService<MyAuditedObject>();
await myAuditedObject.DoItWithSecretAsync("MyTenant", "Server=localhost;Password=1q2w3E*");
var auditLog = (AuditLogInfo)AuditingStore.ReceivedCalls().Last().GetArguments()[0]!;
var action = auditLog.Actions.Single(x => x.MethodName == nameof(MyAuditedObject.DoItWithSecretAsync));
action.Parameters.ShouldContain("MyTenant");
action.Parameters.ShouldNotContain("1q2w3E*");
}
public interface IMyAuditedObject : ITransientDependency, IAuditingEnabled
{
}
@ -135,5 +151,10 @@ public class AuditingHelper_Tests : AbpAuditingTestBase
{
return Task.CompletedTask;
}
public virtual Task DoItWithSecretAsync(string name, [DisableAuditing] string connectionString)
{
return Task.CompletedTask;
}
}
}

3
modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/ITenantAppService.cs

@ -1,6 +1,7 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Auditing;
namespace Volo.Abp.TenantManagement;
@ -8,7 +9,7 @@ public interface ITenantAppService : ICrudAppService<TenantDto, Guid, GetTenants
{
Task<string> GetDefaultConnectionStringAsync(Guid id);
Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString);
Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString);
Task DeleteDefaultConnectionStringAsync(Guid id);
}

3
modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
@ -133,7 +134,7 @@ public class TenantAppService : TenantManagementAppServiceBase, ITenantAppServic
}
[Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)]
public virtual async Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
public virtual async Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString)
{
var tenant = await TenantRepository.GetAsync(id);
if (tenant.FindDefaultConnectionString() != defaultConnectionString)

2
modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConnectionString.cs

@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.TenantManagement;
@ -10,6 +11,7 @@ public class TenantConnectionString : Entity
public virtual string Name { get; protected set; }
[DisableAuditing]
public virtual string Value { get; protected set; }
protected TenantConnectionString()

3
modules/tenant-management/src/Volo.Abp.TenantManagement.HttpApi/Volo/Abp/TenantManagement/TenantController.cs

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Auditing;
namespace Volo.Abp.TenantManagement;
@ -62,7 +63,7 @@ public class TenantController : AbpControllerBase, ITenantAppService //TODO: Thr
[HttpPut]
[Route("{id}/default-connection-string")]
public virtual Task UpdateDefaultConnectionStringAsync(Guid id, string defaultConnectionString)
public virtual Task UpdateDefaultConnectionStringAsync(Guid id, [DisableAuditing] string defaultConnectionString)
{
return TenantAppService.UpdateDefaultConnectionStringAsync(id, defaultConnectionString);
}

Loading…
Cancel
Save