Browse Source

FeatureValueProvider and PermissionValueProvider with duplicate names is not allowed

pull/18823/head
liangshiwei 2 years ago
parent
commit
45e9a0da2d
  1. 15
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs
  2. 20
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs
  3. 44
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs
  4. 8
      framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs
  5. 59
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs
  6. 54
      framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs
  7. 10
      framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs

15
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionValueProviderManager.cs

@ -9,7 +9,7 @@ namespace Volo.Abp.Authorization.Permissions;
public class PermissionValueProviderManager : IPermissionValueProviderManager, ISingletonDependency
{
public IReadOnlyList<IPermissionValueProvider> ValueProviders => _lazyProviders.Value;
public IReadOnlyList<IPermissionValueProvider> ValueProviders => GetProviders();
private readonly Lazy<List<IPermissionValueProvider>> _lazyProviders;
protected AbpPermissionOptions Options { get; }
@ -28,4 +28,17 @@ public class PermissionValueProviderManager : IPermissionValueProviderManager, I
true
);
}
protected virtual List<IPermissionValueProvider> GetProviders()
{
var providers = _lazyProviders.Value;
var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1);
if(multipleProviders != null)
{
throw new AbpException($"Duplicate permission value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}");
}
return providers;
}
}

20
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureChecker.cs

@ -12,34 +12,26 @@ public class FeatureChecker : FeatureCheckerBase
protected AbpFeatureOptions Options { get; }
protected IServiceProvider ServiceProvider { get; }
protected IFeatureDefinitionManager FeatureDefinitionManager { get; }
protected List<IFeatureValueProvider> Providers => _providers.Value;
private readonly Lazy<List<IFeatureValueProvider>> _providers;
protected IFeatureValueProviderManager FeatureValueProviderManager { get; }
public FeatureChecker(
IOptions<AbpFeatureOptions> options,
IServiceProvider serviceProvider,
IFeatureDefinitionManager featureDefinitionManager)
IFeatureDefinitionManager featureDefinitionManager,
IFeatureValueProviderManager featureValueProviderManager)
{
ServiceProvider = serviceProvider;
FeatureDefinitionManager = featureDefinitionManager;
FeatureValueProviderManager = featureValueProviderManager;
Options = options.Value;
_providers = new Lazy<List<IFeatureValueProvider>>(
() => Options
.ValueProviders
.Select(type => (ServiceProvider.GetRequiredService(type) as IFeatureValueProvider)!)
.ToList(),
true
);
}
public override async Task<string?> GetOrNullAsync(string name)
{
var featureDefinition = await FeatureDefinitionManager.GetAsync(name);
var providers = Enumerable
.Reverse(Providers);
var providers = FeatureValueProviderManager.ValueProviders
.Reverse();
if (featureDefinition.AllowedProviders.Any())
{

44
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureValueProviderManager.cs

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Features;
public class FeatureValueProviderManager : IFeatureValueProviderManager, ISingletonDependency
{
public IReadOnlyList<IFeatureValueProvider> ValueProviders => GetProviders();
private readonly Lazy<List<IFeatureValueProvider>> _lazyProviders;
protected AbpFeatureOptions Options { get; }
public FeatureValueProviderManager(
IServiceProvider serviceProvider,
IOptions<AbpFeatureOptions> options)
{
Options = options.Value;
_lazyProviders = new Lazy<List<IFeatureValueProvider>>(
() => Options
.ValueProviders
.Select(c => serviceProvider.GetRequiredService(c) as IFeatureValueProvider)
.ToList()!,
true
);
}
protected virtual List<IFeatureValueProvider> GetProviders()
{
var providers = _lazyProviders.Value;
var multipleProviders = providers.GroupBy(p => p.Name).FirstOrDefault(x => x.Count() > 1);
if(multipleProviders != null)
{
throw new AbpException($"Duplicate feature value provider name detected: {multipleProviders.Key}. Providers:{Environment.NewLine}{multipleProviders.Select(p => p.GetType().FullName!).JoinAsString(Environment.NewLine)}");
}
return providers;
}
}

8
framework/src/Volo.Abp.Features/Volo/Abp/Features/IFeatureValueProviderManager.cs

@ -0,0 +1,8 @@
using System.Collections.Generic;
namespace Volo.Abp.Features;
public interface IFeatureValueProviderManager
{
IReadOnlyList<IFeatureValueProvider> ValueProviders { get; }
}

59
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/PermissionValueProviderManager_Tests.cs

@ -0,0 +1,59 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Authorization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Authorization.TestServices;
using Xunit;
namespace Volo.Abp;
public class PermissionValueProviderManager_Tests: AuthorizationTestBase
{
private readonly IPermissionValueProviderManager _permissionValueProviderManager;
public PermissionValueProviderManager_Tests()
{
_permissionValueProviderManager = GetRequiredService<IPermissionValueProviderManager>();
}
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.Services.Configure<AbpPermissionOptions>(permissionOptions =>
{
permissionOptions.ValueProviders.Add<TestDuplicatePermissionValueProvider>();
});
}
[Fact]
public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected()
{
var exception = Assert.Throws<AbpException>(() =>
{
var providers = _permissionValueProviderManager.ValueProviders;
});
exception.Message.ShouldBe($"Duplicate permission value provider name detected: TestPermissionValueProvider1. Providers:{Environment.NewLine}{typeof(TestDuplicatePermissionValueProvider).FullName}{Environment.NewLine}{typeof(TestPermissionValueProvider1).FullName}");
}
}
public class TestDuplicatePermissionValueProvider : PermissionValueProvider
{
public TestDuplicatePermissionValueProvider(IPermissionStore permissionStore) : base(permissionStore)
{
}
public override string Name => "TestPermissionValueProvider1";
public override Task<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context)
{
throw new NotImplementedException();
}
public override Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
{
throw new NotImplementedException();
}
}

54
framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureValueProviderManager_Tests.cs

@ -0,0 +1,54 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;
namespace Volo.Abp.Features;
public class FeatureValueProviderManager_Tests : FeatureTestBase
{
private readonly IFeatureValueProviderManager _featureValueProviderManager;
public FeatureValueProviderManager_Tests()
{
_featureValueProviderManager = GetRequiredService<IFeatureValueProviderManager>();
}
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.Services.Configure<AbpFeatureOptions>(permissionOptions =>
{
permissionOptions.ValueProviders.Add<TestDuplicateFeatureValueProvider>();
});
}
[Fact]
public void Should_Throw_Exception_If_Duplicate_Provider_Name_Detected()
{
var exception = Assert.Throws<AbpException>(() =>
{
var providers = _featureValueProviderManager.ValueProviders;
});
exception.Message.ShouldBe($"Duplicate feature value provider name detected: {TestDuplicateFeatureValueProvider.ProviderName}. Providers:{Environment.NewLine}{typeof(TestDuplicateFeatureValueProvider).FullName}{Environment.NewLine}{typeof(DefaultValueFeatureValueProvider).FullName}");
}
}
public class TestDuplicateFeatureValueProvider : FeatureValueProvider
{
public const string ProviderName = "D";
public override string Name => ProviderName;
public TestDuplicateFeatureValueProvider(IFeatureStore settingStore)
: base(settingStore)
{
}
public override Task<string> GetOrNullAsync(FeatureDefinition setting)
{
throw new NotImplementedException();
}
}

10
framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingValueProviderManager_Tests.cs

@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute.Extensions;
using Shouldly;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Testing;
@ -25,7 +23,7 @@ public class SettingValueProviderManager_Tests: AbpIntegratedTest<AbpSettingsTes
options.UseAutofac();
options.Services.Configure<AbpSettingOptions>(settingOptions =>
{
settingOptions.ValueProviders.Add<Test2SettingValueProvider>();
settingOptions.ValueProviders.Add<TestDuplicateSettingValueProvider>();
});
}
@ -37,18 +35,18 @@ public class SettingValueProviderManager_Tests: AbpIntegratedTest<AbpSettingsTes
var providers = _settingValueProviderManager.Providers;
});
exception.Message.ShouldBe($"Duplicate setting value provider name detected: Test. Providers:{Environment.NewLine}Volo.Abp.Settings.Test2SettingValueProvider{Environment.NewLine}Volo.Abp.Settings.TestSettingValueProvider");
exception.Message.ShouldBe($"Duplicate setting value provider name detected: {TestDuplicateSettingValueProvider.ProviderName}. Providers:{Environment.NewLine}{typeof(TestDuplicateSettingValueProvider).FullName}{Environment.NewLine}{typeof(TestSettingValueProvider).FullName}");
}
}
public class Test2SettingValueProvider : ISettingValueProvider, ITransientDependency
public class TestDuplicateSettingValueProvider : ISettingValueProvider, ITransientDependency
{
public const string ProviderName = "Test";
public string Name => ProviderName;
public Test2SettingValueProvider()
public TestDuplicateSettingValueProvider()
{
}

Loading…
Cancel
Save