Browse Source

Introduce ISimpleStateCheckerSerializer and implement serialization of global feature requirements.

pull/13644/head
Halil İbrahim Kalkan 4 years ago
parent
commit
6359d013bd
  1. 2
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs
  2. 10
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializer.cs
  3. 15
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializerContributor.cs
  4. 56
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializer.cs
  5. 38
      framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializerExtensions.cs
  6. 54
      framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeaturesSimpleStateCheckerSerializerContributor.cs
  7. 18
      framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs
  8. 46
      framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/GlobalFeaturesSimpleStateCheckerSerializerContributor_Tests.cs
  9. 20
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs
  10. 2
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.csproj
  11. 7
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementTestModule.cs
  12. 6
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs

2
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateChecker.cs

@ -6,4 +6,4 @@ public interface ISimpleStateChecker<TState>
where TState : IHasSimpleStateCheckers<TState> where TState : IHasSimpleStateCheckers<TState>
{ {
Task<bool> IsEnabledAsync(SimpleStateCheckerContext<TState> context); Task<bool> IsEnabledAsync(SimpleStateCheckerContext<TState> context);
} }

10
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializer.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.SimpleStateChecking;
public interface ISimpleStateCheckerSerializer
{
public string Serialize<TState>(ISimpleStateChecker<TState> checker)
where TState : IHasSimpleStateCheckers<TState>;
public ISimpleStateChecker<TState> Deserialize<TState>(string value)
where TState : IHasSimpleStateCheckers<TState>;
}

15
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/ISimpleStateCheckerSerializerContributor.cs

@ -0,0 +1,15 @@
using System.Text.Json.Nodes;
using JetBrains.Annotations;
namespace Volo.Abp.SimpleStateChecking;
public interface ISimpleStateCheckerSerializerContributor
{
[CanBeNull]
public string SerializeToJson<TState>(ISimpleStateChecker<TState> checker)
where TState : IHasSimpleStateCheckers<TState>;
[CanBeNull]
public ISimpleStateChecker<TState> Deserialize<TState>(JsonObject jsonObject)
where TState : IHasSimpleStateCheckers<TState>;
}

56
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializer.cs

@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.Text.Json.Nodes;
using JetBrains.Annotations;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.SimpleStateChecking;
public class SimpleStateCheckerSerializer :
ISimpleStateCheckerSerializer,
ITransientDependency
{
private readonly IEnumerable<ISimpleStateCheckerSerializerContributor> _contributors;
public SimpleStateCheckerSerializer(IEnumerable<ISimpleStateCheckerSerializerContributor> contributors)
{
_contributors = contributors;
}
[CanBeNull]
public string Serialize<TState>(ISimpleStateChecker<TState> checker)
where TState : IHasSimpleStateCheckers<TState>
{
foreach (var contributor in _contributors)
{
var result = contributor.SerializeToJson(checker);
if (result != null)
{
return result;
}
}
return null;
}
[CanBeNull]
public ISimpleStateChecker<TState> Deserialize<TState>(string value)
where TState : IHasSimpleStateCheckers<TState>
{
var jsonObject = JsonNode.Parse(value) as JsonObject;
if (jsonObject == null)
{
throw new AbpException("The value is not a JSON object: " + value);
}
foreach (var contributor in _contributors)
{
var result = contributor.Deserialize<TState>(jsonObject);
if (result != null)
{
return result;
}
}
return null;
}
}

38
framework/src/Volo.Abp.Core/Volo/Abp/SimpleStateChecking/SimpleStateCheckerSerializerExtensions.cs

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Volo.Abp.SimpleStateChecking;
public static class SimpleStateCheckerSerializerExtensions
{
public static string Serialize<TState>(
this ISimpleStateCheckerSerializer serializer,
IList<ISimpleStateChecker<TState>> stateCheckers)
where TState : IHasSimpleStateCheckers<TState>
{
switch (stateCheckers.Count)
{
case 0:
return null;
case 1:
return $"[{serializer.Serialize(stateCheckers.Single())}]";
default:
var stringBuilder = new StringBuilder("[");
for (var i = 0; i < stateCheckers.Count; i++)
{
if (i > 0)
{
stringBuilder.Append(",");
}
stringBuilder.Append(serializer.Serialize(stateCheckers[i]));
}
stringBuilder.Append("]");
return stringBuilder.ToString();
}
}
}

54
framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeaturesSimpleStateCheckerSerializerContributor.cs

@ -0,0 +1,54 @@
using System.Linq;
using System.Text.Json.Nodes;
using Volo.Abp.DependencyInjection;
using Volo.Abp.SimpleStateChecking;
namespace Volo.Abp.GlobalFeatures;
public class GlobalFeaturesSimpleStateCheckerSerializerContributor :
ISimpleStateCheckerSerializerContributor,
ITransientDependency
{
public string SerializeToJson<TState>(ISimpleStateChecker<TState> checker)
where TState : IHasSimpleStateCheckers<TState>
{
if (checker is not RequireGlobalFeaturesSimpleStateChecker<TState> globalFeaturesSimpleStateChecker)
{
return null;
}
var jsonObject = new JsonObject {
["T"] = "GF",
["A"] = globalFeaturesSimpleStateChecker.RequiresAll
};
var nameArray = new JsonArray();
foreach (var globalFeatureName in globalFeaturesSimpleStateChecker.GlobalFeatureNames)
{
nameArray.Add(globalFeatureName);
}
jsonObject["N"] = nameArray;
return jsonObject.ToJsonString();
}
public ISimpleStateChecker<TState> Deserialize<TState>(JsonObject jsonObject)
where TState : IHasSimpleStateCheckers<TState>
{
if (jsonObject["T"]?.ToString() != "GF")
{
return null;
}
var nameArray = jsonObject["N"] as JsonArray;
if (nameArray == null)
{
throw new AbpException("'N' is not an array in the serialized state checker! JsonObject: " + jsonObject.ToJsonString());
}
return new RequireGlobalFeaturesSimpleStateChecker<TState>(
(bool?)jsonObject["A"] ?? false,
nameArray.Select(x => x.ToString()).ToArray()
);
}
}

18
framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesSimpleStateChecker.cs

@ -8,8 +8,8 @@ namespace Volo.Abp.GlobalFeatures;
public class RequireGlobalFeaturesSimpleStateChecker<TState> : ISimpleStateChecker<TState> public class RequireGlobalFeaturesSimpleStateChecker<TState> : ISimpleStateChecker<TState>
where TState : IHasSimpleStateCheckers<TState> where TState : IHasSimpleStateCheckers<TState>
{ {
private readonly string[] _globalFeatureNames; public string[] GlobalFeatureNames { get; }
private readonly bool _requiresAll; public bool RequiresAll { get; }
public RequireGlobalFeaturesSimpleStateChecker(params string[] globalFeatureNames) public RequireGlobalFeaturesSimpleStateChecker(params string[] globalFeatureNames)
: this(true, globalFeatureNames) : this(true, globalFeatureNames)
@ -20,23 +20,23 @@ public class RequireGlobalFeaturesSimpleStateChecker<TState> : ISimpleStateCheck
{ {
Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames));
_requiresAll = requiresAll; RequiresAll = requiresAll;
_globalFeatureNames = globalFeatureNames; GlobalFeatureNames = globalFeatureNames;
} }
public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params Type[] globalFeatureNames) public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params Type[] globalFeatureNames)
{ {
Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames));
_requiresAll = requiresAll; RequiresAll = requiresAll;
_globalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray(); GlobalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray();
} }
public Task<bool> IsEnabledAsync(SimpleStateCheckerContext<TState> context) public Task<bool> IsEnabledAsync(SimpleStateCheckerContext<TState> context)
{ {
var isEnabled = _requiresAll var isEnabled = RequiresAll
? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x)) ? GlobalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x))
: _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x)); : GlobalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x));
return Task.FromResult(isEnabled); return Task.FromResult(isEnabled);
} }

46
framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/GlobalFeaturesSimpleStateCheckerSerializerContributor_Tests.cs

@ -0,0 +1,46 @@
using System.Collections.Generic;
using System.Text.Json.Nodes;
using Shouldly;
using Volo.Abp.SimpleStateChecking;
using Xunit;
namespace Volo.Abp.GlobalFeatures;
public class GlobalFeaturesSimpleStateCheckerSerializerContributor_Tests
{
[Fact]
public void Should_Serialize_RequireGlobalFeaturesSimpleStateChecker()
{
var serializer = new GlobalFeaturesSimpleStateCheckerSerializerContributor();
var result = serializer.SerializeToJson(
new RequireGlobalFeaturesSimpleStateChecker<MyState>(
"FeatureA",
"FeatureB"
)
);
result.ShouldBe("{\"T\":\"GF\",\"A\":true,\"N\":[\"FeatureA\",\"FeatureB\"]}");
}
[Fact]
public void Should_Deserialize_RequireGlobalFeaturesSimpleStateChecker()
{
var serializer = new GlobalFeaturesSimpleStateCheckerSerializerContributor();
var jsonObject = (JsonObject)JsonNode.Parse("{\"T\":\"GF\",\"A\":true,\"N\":[\"FeatureA\",\"FeatureB\"]}");
var checker = serializer.Deserialize<MyState>(jsonObject);
checker.ShouldBeOfType<RequireGlobalFeaturesSimpleStateChecker<MyState>>();
var globalFeaturesSimpleStateChecker = checker as RequireGlobalFeaturesSimpleStateChecker<MyState>;
globalFeaturesSimpleStateChecker.ShouldNotBeNull();
globalFeaturesSimpleStateChecker.RequiresAll.ShouldBeTrue();
globalFeaturesSimpleStateChecker.GlobalFeatureNames[0].ShouldBe("FeatureA");
globalFeaturesSimpleStateChecker.GlobalFeatureNames[1].ShouldBe("FeatureB");
}
private class MyState : IHasSimpleStateCheckers<MyState>
{
public List<ISimpleStateChecker<MyState>> StateCheckers { get; } = new();
}
}

20
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
@ -14,13 +15,16 @@ namespace Volo.Abp.PermissionManagement;
public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, ITransientDependency public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, ITransientDependency
{ {
protected ISimpleStateCheckerSerializer StateCheckerSerializer { get; }
protected IGuidGenerator GuidGenerator { get; } protected IGuidGenerator GuidGenerator { get; }
protected IStringLocalizerFactory StringLocalizerFactory { get; } protected IStringLocalizerFactory StringLocalizerFactory { get; }
public PermissionDefinitionSerializer( public PermissionDefinitionSerializer(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
IStringLocalizerFactory stringLocalizerFactory) IStringLocalizerFactory stringLocalizerFactory,
ISimpleStateCheckerSerializer stateCheckerSerializer)
{ {
StateCheckerSerializer = stateCheckerSerializer;
GuidGenerator = guidGenerator; GuidGenerator = guidGenerator;
StringLocalizerFactory = stringLocalizerFactory; StringLocalizerFactory = stringLocalizerFactory;
} }
@ -52,7 +56,8 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
} }
} }
public Task<PermissionDefinition> DeserializeAsync(PermissionDefinitionRecord permissionRecord) public Task<PermissionDefinition> DeserializeAsync(
PermissionDefinitionRecord permissionRecord)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
@ -67,16 +72,9 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
protected virtual string SerializeStateCheckers(IEnumerable<ISimpleStateChecker<PermissionDefinition>> stateCheckers) protected virtual string SerializeStateCheckers(List<ISimpleStateChecker<PermissionDefinition>> stateCheckers)
{ {
//TODO: Serialize state checker return StateCheckerSerializer.Serialize(stateCheckers);
if(!stateCheckers.Any())
{
return null;
}
return null;
} }
protected virtual string SerializeProviders(ICollection<string> providers) protected virtual string SerializeProviders(ICollection<string> providers)

2
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo.Abp.PermissionManagement.Domain.Tests.csproj

@ -12,6 +12,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Features\Volo.Abp.Features.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.GlobalFeatures\Volo.Abp.GlobalFeatures.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\Volo.Abp.PermissionManagement.TestBase\Volo.Abp.PermissionManagement.TestBase.csproj" /> <ProjectReference Include="..\Volo.Abp.PermissionManagement.TestBase\Volo.Abp.PermissionManagement.TestBase.csproj" />
</ItemGroup> </ItemGroup>

7
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementTestModule.cs

@ -2,6 +2,8 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.Uow; using Volo.Abp.Uow;
@ -10,7 +12,10 @@ namespace Volo.Abp.PermissionManagement;
[DependsOn( [DependsOn(
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementTestBaseModule))] typeof(AbpPermissionManagementTestBaseModule),
typeof(AbpFeaturesModule),
typeof(AbpGlobalFeaturesModule)
)]
public class AbpPermissionManagementTestModule : AbpModule public class AbpPermissionManagementTestModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)

6
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer_Tests.cs

@ -2,6 +2,8 @@
using Shouldly; using Shouldly;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
using Xunit; using Xunit;
@ -30,7 +32,8 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase
MultiTenancySides.Tenant MultiTenancySides.Tenant
) )
.WithProviders("ProviderA", "ProviderB") .WithProviders("ProviderA", "ProviderB")
.WithProperty("CustomProperty2", "CustomValue2"); .WithProperty("CustomProperty2", "CustomValue2")
.RequireGlobalFeatures("GlobalFeature1", "GlobalFeature2");
// Act // Act
@ -47,6 +50,7 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase
permissionRecord.GetProperty("CustomProperty2").ShouldBe("CustomValue2"); permissionRecord.GetProperty("CustomProperty2").ShouldBe("CustomValue2");
permissionRecord.Providers.ShouldBe("ProviderA,ProviderB"); permissionRecord.Providers.ShouldBe("ProviderA,ProviderB");
permissionRecord.MultiTenancySide.ShouldBe(MultiTenancySides.Tenant); permissionRecord.MultiTenancySide.ShouldBe(MultiTenancySides.Tenant);
permissionRecord.StateCheckers.ShouldBe("[{\"T\":\"GF\",\"A\":true,\"N\":[\"GlobalFeature1\",\"GlobalFeature2\"]}]");
} }
private static PermissionGroupDefinition CreatePermissionGroup1( private static PermissionGroupDefinition CreatePermissionGroup1(

Loading…
Cancel
Save