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>
{
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>
where TState : IHasSimpleStateCheckers<TState>
{
private readonly string[] _globalFeatureNames;
private readonly bool _requiresAll;
public string[] GlobalFeatureNames { get; }
public bool RequiresAll { get; }
public RequireGlobalFeaturesSimpleStateChecker(params string[] globalFeatureNames)
: this(true, globalFeatureNames)
@ -20,23 +20,23 @@ public class RequireGlobalFeaturesSimpleStateChecker<TState> : ISimpleStateCheck
{
Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames));
_requiresAll = requiresAll;
_globalFeatureNames = globalFeatureNames;
RequiresAll = requiresAll;
GlobalFeatureNames = globalFeatureNames;
}
public RequireGlobalFeaturesSimpleStateChecker(bool requiresAll, params Type[] globalFeatureNames)
{
Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames));
_requiresAll = requiresAll;
_globalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray();
RequiresAll = requiresAll;
GlobalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray();
}
public Task<bool> IsEnabledAsync(SimpleStateCheckerContext<TState> context)
{
var isEnabled = _requiresAll
? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x))
: _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x));
var isEnabled = RequiresAll
? GlobalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x))
: GlobalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x));
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.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using Volo.Abp.Authorization.Permissions;
@ -14,13 +15,16 @@ namespace Volo.Abp.PermissionManagement;
public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, ITransientDependency
{
protected ISimpleStateCheckerSerializer StateCheckerSerializer { get; }
protected IGuidGenerator GuidGenerator { get; }
protected IStringLocalizerFactory StringLocalizerFactory { get; }
public PermissionDefinitionSerializer(
IGuidGenerator guidGenerator,
IStringLocalizerFactory stringLocalizerFactory)
IStringLocalizerFactory stringLocalizerFactory,
ISimpleStateCheckerSerializer stateCheckerSerializer)
{
StateCheckerSerializer = stateCheckerSerializer;
GuidGenerator = guidGenerator;
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();
}
@ -67,16 +72,9 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
throw new System.NotImplementedException();
}
protected virtual string SerializeStateCheckers(IEnumerable<ISimpleStateChecker<PermissionDefinition>> stateCheckers)
protected virtual string SerializeStateCheckers(List<ISimpleStateChecker<PermissionDefinition>> stateCheckers)
{
//TODO: Serialize state checker
if(!stateCheckers.Any())
{
return null;
}
return null;
return StateCheckerSerializer.Serialize(stateCheckers);
}
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>
<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="..\Volo.Abp.PermissionManagement.TestBase\Volo.Abp.PermissionManagement.TestBase.csproj" />
</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.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.Uow;
@ -10,7 +12,10 @@ namespace Volo.Abp.PermissionManagement;
[DependsOn(
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementTestBaseModule))]
typeof(AbpPermissionManagementTestBaseModule),
typeof(AbpFeaturesModule),
typeof(AbpGlobalFeaturesModule)
)]
public class AbpPermissionManagementTestModule : AbpModule
{
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 Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.Features;
using Volo.Abp.GlobalFeatures;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Xunit;
@ -30,7 +32,8 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase
MultiTenancySides.Tenant
)
.WithProviders("ProviderA", "ProviderB")
.WithProperty("CustomProperty2", "CustomValue2");
.WithProperty("CustomProperty2", "CustomValue2")
.RequireGlobalFeatures("GlobalFeature1", "GlobalFeature2");
// Act
@ -47,6 +50,7 @@ public class PermissionDefinitionSerializer_Tests : PermissionTestBase
permissionRecord.GetProperty("CustomProperty2").ShouldBe("CustomValue2");
permissionRecord.Providers.ShouldBe("ProviderA,ProviderB");
permissionRecord.MultiTenancySide.ShouldBe(MultiTenancySides.Tenant);
permissionRecord.StateCheckers.ShouldBe("[{\"T\":\"GF\",\"A\":true,\"N\":[\"GlobalFeature1\",\"GlobalFeature2\"]}]");
}
private static PermissionGroupDefinition CreatePermissionGroup1(

Loading…
Cancel
Save