Browse Source

Created AuditPropertySetter and initial tests. Added TenantId to current user.

pull/272/head
Halil İbrahim Kalkan 8 years ago
parent
commit
3b84fc3392
  1. 7
      Volo.Abp.sln
  2. 4
      src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj
  3. 2
      src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj.DotSettings
  4. 11
      src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingModule.cs
  5. 111
      src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditPropertySetter.cs
  6. 9
      src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditPropertySetter.cs
  7. 17
      src/Volo.Abp.Users/Volo/Abp/Users/CurrentUser.cs
  8. 4
      src/Volo.Abp.Users/Volo/Abp/Users/ICurrentUser.cs
  9. 24
      test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj
  10. 2
      test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj.DotSettings
  11. 57
      test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditPropertySetterTestBase.cs
  12. 28
      test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditPropertySetter_CreationAudit_Tests.cs

7
Volo.Abp.sln

@ -308,6 +308,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Users", "src\Volo.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Auditing", "src\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj", "{03F51721-DA51-4BAE-9909-3FC88FAB7774}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Auditing.Tests", "test\Volo.Abp.Auditing.Tests\Volo.Abp.Auditing.Tests.csproj", "{D5733D90-8C3D-4026-85E2-41DED26C4938}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -814,6 +816,10 @@ Global
{03F51721-DA51-4BAE-9909-3FC88FAB7774}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03F51721-DA51-4BAE-9909-3FC88FAB7774}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03F51721-DA51-4BAE-9909-3FC88FAB7774}.Release|Any CPU.Build.0 = Release|Any CPU
{D5733D90-8C3D-4026-85E2-41DED26C4938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5733D90-8C3D-4026-85E2-41DED26C4938}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5733D90-8C3D-4026-85E2-41DED26C4938}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5733D90-8C3D-4026-85E2-41DED26C4938}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -964,6 +970,7 @@ Global
{F33F751F-1260-40C0-8F76-E3D680605662} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{DAE9088E-6E30-4D5D-9DF8-2188E8D386FE} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8}
{03F51721-DA51-4BAE-9909-3FC88FAB7774} = {4C753F64-0C93-4D65-96C2-A40893AFC1E8}
{D5733D90-8C3D-4026-85E2-41DED26C4938} = {37087D1B-3693-4E96-983D-A69F210BDE53}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

4
src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj

@ -14,8 +14,10 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<ProjectReference Include="..\Volo.Abp.Users\Volo.Abp.Users.csproj" />
</ItemGroup>
</Project>

2
src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj.DotSettings

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary>

11
src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingModule.cs

@ -1,10 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Data;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing;
using Volo.Abp.Users;
namespace Volo.Abp.Auditing
{
[DependsOn(typeof(AbpDataModule))] //TODO: Can we remove data module dependency since it only contains ISoftDelete related to auditing module!
//TODO: Can we remove AbpDataModule dependency since it only contains ISoftDelete related to auditing module!
[DependsOn(
typeof(AbpDataModule),
typeof(AbpTimingModule),
typeof(AbpUsersModule),
typeof(AbpMultiTenancyAbstractionsModule)
)]
public class AbpAuditingModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)

111
src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditPropertySetter.cs

@ -0,0 +1,111 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing;
using Volo.Abp.Users;
namespace Volo.Abp.Auditing
{
public class AuditPropertySetter : IAuditPropertySetter, ITransientDependency
{
protected ICurrentUser CurrentUser { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IClock Clock { get; }
public AuditPropertySetter(
ICurrentUser currentUser,
ICurrentTenant currentTenant,
IClock clock)
{
CurrentUser = currentUser;
CurrentTenant = currentTenant;
Clock = clock;
}
public void SetCreationAuditProperties(object targetObject)
{
if (!(targetObject is IHasCreationTime objectWithCreationTime))
{
return;
}
if (objectWithCreationTime.CreationTime == default)
{
objectWithCreationTime.CreationTime = Clock.Now;
}
if (!(targetObject is ICreationAudited creationAuditedObject))
{
return;
}
if (creationAuditedObject.CreatorId != null)
{
return;
}
if (!CurrentUser.Id.HasValue)
{
return;
}
if (targetObject is IMultiTenant multiTenantEntity)
{
if (multiTenantEntity.TenantId != CurrentUser.TenantId)
{
return;
}
}
/* TODO: The code below is from old ABP, not implemented yet
if (tenantId.HasValue && MultiTenancyHelper.IsHostEntity(entity))
{
//Tenant user created a host entity
return;
}
*/
creationAuditedObject.CreatorId = CurrentUser.Id;
}
public void SetModificationAuditProperties(object auditedObject)
{
if (auditedObject is IHasModificationTime objectWithModificationTime)
{
objectWithModificationTime.LastModificationTime = Clock.Now;
}
if (!(auditedObject is IModificationAudited modificationAuditedObject))
{
return;
}
if (!CurrentUser.Id.HasValue)
{
modificationAuditedObject.LastModifierId = null;
return;
}
if (modificationAuditedObject is IMultiTenant multiTenantEntity)
{
if (multiTenantEntity.TenantId != CurrentUser.TenantId)
{
modificationAuditedObject.LastModifierId = null;
return;
}
}
/* TODO: The code below is from old ABP, not implemented yet
if (tenantId.HasValue && MultiTenancyHelper.IsHostEntity(entity))
{
//Tenant user modified a host entity
modificationAuditedObject.LastModifierId = null;
return;
}
*/
modificationAuditedObject.LastModifierId = CurrentUser.Id;
}
}
}

9
src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditPropertySetter.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.Auditing
{
public interface IAuditPropertySetter
{
void SetCreationAuditProperties(object targetObject);
void SetModificationAuditProperties(object auditedObject);
}
}

17
src/Volo.Abp.Users/Volo/Abp/Users/CurrentUser.cs

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
@ -12,19 +13,7 @@ namespace Volo.Abp.Users
public virtual bool IsAuthenticated => Id.HasValue;
public virtual Guid? Id
{
get
{
var value = this.FindClaimValue(AbpClaimTypes.UserId);
if (value == null)
{
return null;
}
return Guid.Parse(value);
}
}
public virtual Guid? Id => _principalAccessor.Principal?.FindUserId();
public virtual string UserName => this.FindClaimValue(AbpClaimTypes.UserName);
@ -36,6 +25,8 @@ namespace Volo.Abp.Users
public virtual bool EmailVerified => string.Equals(this.FindClaimValue(AbpClaimTypes.EmailVerified), "true", StringComparison.InvariantCultureIgnoreCase);
public virtual Guid? TenantId => _principalAccessor.Principal?.FindTenantId();
public virtual string[] Roles => FindClaims(AbpClaimTypes.Role).Select(c => c.Value).ToArray();
private readonly ICurrentPrincipalAccessor _principalAccessor;

4
src/Volo.Abp.Users/Volo/Abp/Users/ICurrentUser.cs

@ -16,7 +16,7 @@ namespace Volo.Abp.Users
[CanBeNull]
string PhoneNumber { get; }
bool PhoneNumberVerified { get; }
[CanBeNull]
@ -24,6 +24,8 @@ namespace Volo.Abp.Users
bool EmailVerified { get; }
Guid? TenantId { get; }
[NotNull]
string[] Roles { get; }

24
test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<AssemblyName>Volo.Abp.Auditing.Tests</AssemblyName>
<PackageId>Volo.Abp.Auditing.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
</ItemGroup>
</Project>

2
test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj.DotSettings

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp71</s:String></wpf:ResourceDictionary>

57
test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditPropertySetterTestBase.cs

@ -0,0 +1,57 @@
using System;
using NSubstitute;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Timing;
using Volo.Abp.Users;
namespace Volo.Abp.Auditing
{
public class AuditPropertySetterTestBase
{
protected Guid? CurrentUserId = null;
protected Guid? CurrentUserTenantId = null;
protected Guid? CurrentTenantId = null;
protected DateTime Now = DateTime.Now;
protected MyAuditedObject TargetObject;
protected readonly AuditPropertySetter AuditPropertySetter;
public AuditPropertySetterTestBase()
{
AuditPropertySetter = CreateAuditPropertySetter();
TargetObject = new MyAuditedObject();
}
private AuditPropertySetter CreateAuditPropertySetter()
{
var currentUser = Substitute.For<ICurrentUser>();
currentUser.Id.Returns(ci => CurrentUserId);
currentUser.TenantId.Returns(ci => CurrentUserTenantId);
var currentTenant = Substitute.For<ICurrentTenant>();
currentTenant.Id.Returns(ci => CurrentTenantId);
var clock = Substitute.For<IClock>();
clock.Now.Returns(Now);
return new AuditPropertySetter(
currentUser,
currentTenant,
clock
);
}
public class MyAuditedObject : IFullAudited
{
public DateTime CreationTime { get; set; }
public Guid? CreatorId { get; set; }
public DateTime? LastModificationTime { get; set; }
public Guid? LastModifierId { get; set; }
public bool IsDeleted { get; set; }
public DateTime? DeletionTime { get; set; }
public Guid? DeleterId { get; set; }
}
}
}

28
test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/AuditPropertySetter_CreationAudit_Tests.cs

@ -0,0 +1,28 @@
using System;
using Shouldly;
using Xunit;
namespace Volo.Abp.Auditing
{
public class AuditPropertySetter_CreationAudit_Tests : AuditPropertySetterTestBase
{
[Fact]
public void Should_Set_CreationTime()
{
AuditPropertySetter.SetCreationAuditProperties(TargetObject);
TargetObject.CreationTime.ShouldNotBe(default);
}
[Fact]
public void Should_Set_CreatorId()
{
CurrentUserId = Guid.NewGuid();
AuditPropertySetter.SetCreationAuditProperties(TargetObject);
TargetObject.CreationTime.ShouldNotBe(default);
TargetObject.CreatorId.ShouldBe(CurrentUserId);
}
}
}
Loading…
Cancel
Save