mirror of https://github.com/abpframework/abp.git
9 changed files with 172 additions and 26 deletions
@ -0,0 +1,42 @@ |
|||
using Microsoft.AspNetCore.Mvc.Filters; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc.Abstractions; |
|||
using Volo.Abp.Aspects; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Features |
|||
{ |
|||
public class AbpFeatureActionFilter : IAsyncActionFilter, ITransientDependency |
|||
{ |
|||
private readonly IMethodInvocationFeatureCheckerService _methodInvocationAuthorizationService; |
|||
|
|||
public AbpFeatureActionFilter(IMethodInvocationFeatureCheckerService methodInvocationAuthorizationService) |
|||
{ |
|||
_methodInvocationAuthorizationService = methodInvocationAuthorizationService; |
|||
} |
|||
|
|||
public async Task OnActionExecutionAsync( |
|||
ActionExecutingContext context, |
|||
ActionExecutionDelegate next) |
|||
{ |
|||
if (!context.ActionDescriptor.IsControllerAction()) |
|||
{ |
|||
await next(); |
|||
return; |
|||
} |
|||
|
|||
var methodInfo = context.ActionDescriptor.GetMethodInfo(); |
|||
|
|||
using (AbpCrossCuttingConcerns.Applying(context.Controller, AbpCrossCuttingConcerns.FeatureChecking)) |
|||
{ |
|||
await _methodInvocationAuthorizationService.CheckAsync( |
|||
new MethodInvocationFeatureCheckerContext(methodInfo) |
|||
); |
|||
|
|||
await next(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Features |
|||
{ |
|||
public abstract class FeatureCheckerBase : IFeatureChecker, ITransientDependency |
|||
{ |
|||
public abstract Task<string> GetOrNullAsync(string name); |
|||
|
|||
public virtual async Task<bool> IsEnabledAsync(string name) |
|||
{ |
|||
var value = await GetOrNullAsync(name); |
|||
if (value == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
return bool.Parse(value); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
throw new AbpException( |
|||
$"The value '{value}' for the feature '{name}' should be a boolean, but was not!", |
|||
ex |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Features |
|||
{ |
|||
public class FakeFeatureChecker : FeatureCheckerBase |
|||
{ |
|||
public override Task<string> GetOrNullAsync(string name) |
|||
{ |
|||
return Task.FromResult(GetOrNull(name)); |
|||
} |
|||
|
|||
private static string GetOrNull(string name) |
|||
{ |
|||
switch (name) |
|||
{ |
|||
case "AllowedFeature": |
|||
return true.ToString(); |
|||
case "NotAllowedFeature": |
|||
return null; //or false, doesn't matter
|
|||
} |
|||
|
|||
throw new ApplicationException($"Unknown feature: '{name}'"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Features |
|||
{ |
|||
[Route("api/feature-test")] |
|||
public class FeatureTestController : AbpController |
|||
{ |
|||
[HttpGet] |
|||
[Route("allowed-feature")] |
|||
[RequiresFeature("AllowedFeature")] |
|||
public Task AllowedFeatureAsync() |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("not-allowed-feature")] |
|||
[RequiresFeature("NotAllowedFeature")] |
|||
public void NotAllowedFeature() |
|||
{ |
|||
|
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("no-feature")] |
|||
public int NoFeature() |
|||
{ |
|||
return 42; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System.Net; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Features |
|||
{ |
|||
public class FeatureTestController_Tests : AspNetCoreMvcTestBase |
|||
{ |
|||
[Fact] |
|||
public async Task Should_Allow_Enabled_Features() |
|||
{ |
|||
await GetResponseAsStringAsync( |
|||
"/api/feature-test/allowed-feature" |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Not_Allow_Not_Enabled_Features() |
|||
{ |
|||
await GetResponseAsStringAsync( |
|||
"/api/feature-test/not-allowed-feature", |
|||
HttpStatusCode.Unauthorized |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Allow_Actions_With_No_Feature() |
|||
{ |
|||
await GetResponseAsStringAsync( |
|||
"/api/feature-test/no-feature" |
|||
); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue