mirror of https://github.com/abpframework/abp.git
14 changed files with 303 additions and 1 deletions
@ -0,0 +1,47 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Abstractions; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
using Volo.Abp.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
public class GlobalFeatureActionFilter : IAsyncActionFilter, ITransientDependency |
||||
|
{ |
||||
|
public ILogger<GlobalFeatureActionFilter> Logger { get; set; } |
||||
|
|
||||
|
public GlobalFeatureActionFilter() |
||||
|
{ |
||||
|
Logger = NullLogger<GlobalFeatureActionFilter>.Instance; |
||||
|
} |
||||
|
|
||||
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
||||
|
{ |
||||
|
if (!context.ActionDescriptor.IsControllerAction()) |
||||
|
{ |
||||
|
await next(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!IsGlobalFeatureEnabled(context.Controller.GetType(), out var attribute)) |
||||
|
{ |
||||
|
Logger.LogWarning($"The '{context.Controller.GetType().FullName}' controller needs to enable '{attribute.Name}' feature."); |
||||
|
context.Result = new NotFoundResult(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await next(); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsGlobalFeatureEnabled(Type controllerType, out RequiresGlobalFeatureAttribute attribute) |
||||
|
{ |
||||
|
attribute = ReflectionHelper.GetSingleAttributeOrDefault<RequiresGlobalFeatureAttribute>(controllerType); |
||||
|
return attribute == null || GlobalFeatureManager.Instance.IsEnabled(attribute.GetFeatureName()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.AspNetCore.Mvc.Abstractions; |
||||
|
using Microsoft.AspNetCore.Mvc.Filters; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
using Volo.Abp.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
public class GlobalFeaturePageFilter: IAsyncPageFilter, ITransientDependency |
||||
|
{ |
||||
|
public ILogger<GlobalFeaturePageFilter> Logger { get; set; } |
||||
|
|
||||
|
public GlobalFeaturePageFilter() |
||||
|
{ |
||||
|
Logger = NullLogger<GlobalFeaturePageFilter>.Instance; |
||||
|
} |
||||
|
|
||||
|
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) |
||||
|
{ |
||||
|
if (context.HandlerInstance == null || !context.ActionDescriptor.IsPageAction()) |
||||
|
{ |
||||
|
await next(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!IsGlobalFeatureEnabled(context.HandlerInstance.GetType(), out var attribute)) |
||||
|
{ |
||||
|
Logger.LogWarning($"The '{context.HandlerInstance.GetType().FullName}' page needs to enable '{attribute.Name}' feature."); |
||||
|
context.Result = new NotFoundResult(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
await next(); |
||||
|
} |
||||
|
|
||||
|
protected virtual bool IsGlobalFeatureEnabled(Type controllerType, out RequiresGlobalFeatureAttribute attribute) |
||||
|
{ |
||||
|
attribute = ReflectionHelper.GetSingleAttributeOrDefault<RequiresGlobalFeatureAttribute>(controllerType); |
||||
|
return attribute == null || GlobalFeatureManager.Instance.IsEnabled(attribute.GetFeatureName()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
[GlobalFeatureName(Name)] |
||||
|
public class AbpAspNetCoreMvcTestFeature1 : Abp.GlobalFeatures.GlobalFeature |
||||
|
{ |
||||
|
public const string Name = "AbpAspNetCoreMvcTest.Feature1"; |
||||
|
|
||||
|
internal AbpAspNetCoreMvcTestFeature1([NotNull] AbpAspNetCoreMvcTestFeatures abpAspNetCoreMvcTestFeatures) |
||||
|
: base(abpAspNetCoreMvcTestFeatures) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AbpAspNetCoreMvcTestFeatures : GlobalModuleFeatures |
||||
|
{ |
||||
|
public const string ModuleName = "AbpAspNetCoreMvcTest"; |
||||
|
|
||||
|
public AbpAspNetCoreMvcTestFeature1 Reactions => GetFeature<AbpAspNetCoreMvcTestFeature1>(); |
||||
|
|
||||
|
public AbpAspNetCoreMvcTestFeatures([NotNull] GlobalFeatureManager featureManager) |
||||
|
: base(featureManager) |
||||
|
{ |
||||
|
AddFeature(new AbpAspNetCoreMvcTestFeature1(this)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
[RequiresGlobalFeature("Not-Enabled-Feature")] |
||||
|
[Route("api/DisabledGlobalFeatureTestController-Test")] |
||||
|
public class DisabledGlobalFeatureTestController : AbpController |
||||
|
{ |
||||
|
[HttpGet] |
||||
|
[Route("TestMethod")] |
||||
|
public string TestMethod() |
||||
|
{ |
||||
|
return "TestMethod"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
@page |
||||
|
@model Volo.Abp.AspNetCore.Mvc.GlobalFeatures.DisabledGlobalFeatureTestPage |
||||
|
|
||||
|
@{ |
||||
|
Layout = null; |
||||
|
} |
||||
|
|
||||
|
<!DOCTYPE html> |
||||
|
|
||||
|
<html> |
||||
|
<head> |
||||
|
<title></title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div> |
||||
|
|
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.RazorPages; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
[RequiresGlobalFeature("Not-Enabled-Feature")] |
||||
|
public class DisabledGlobalFeatureTestPage : PageModel |
||||
|
{ |
||||
|
public void OnGet() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
[RequiresGlobalFeature(AbpAspNetCoreMvcTestFeature1.Name)] |
||||
|
[Route("api/EnabledGlobalFeatureTestController-Test")] |
||||
|
public class EnabledGlobalFeatureTestController : AbpController |
||||
|
{ |
||||
|
[HttpGet] |
||||
|
[Route("TestMethod")] |
||||
|
public string TestMethod() |
||||
|
{ |
||||
|
return "TestMethod"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
@page |
||||
|
@model Volo.Abp.AspNetCore.Mvc.GlobalFeatures.EnabledGlobalFeatureTestPage |
||||
|
|
||||
|
@{ |
||||
|
Layout = null; |
||||
|
} |
||||
|
|
||||
|
<!DOCTYPE html> |
||||
|
|
||||
|
<html> |
||||
|
<head> |
||||
|
<title></title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div> |
||||
|
|
||||
|
</div> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc.RazorPages; |
||||
|
using Volo.Abp.GlobalFeatures; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
[RequiresGlobalFeature(AbpAspNetCoreMvcTestFeature1.Name)] |
||||
|
public class EnabledGlobalFeatureTestPage : PageModel |
||||
|
{ |
||||
|
public void OnGet() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System.Net; |
||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
public class RequiresGlobalFeatureTestController_Tests: AspNetCoreMvcTestBase |
||||
|
{ |
||||
|
[Fact] |
||||
|
public async Task Should_404_If_Feature_Disabled() |
||||
|
{ |
||||
|
var result = await GetResponseAsync("/api/DisabledGlobalFeatureTestController-Test/TestMethod", HttpStatusCode.NotFound); |
||||
|
result.StatusCode.ShouldBe(HttpStatusCode.NotFound); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Pass_Check_If_Feature_Enabled() |
||||
|
{ |
||||
|
var result = await GetResponseAsync("/api/EnabledGlobalFeatureTestController-Test/TestMethod", HttpStatusCode.OK); |
||||
|
result.StatusCode.ShouldBe(HttpStatusCode.OK); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System.Net; |
||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.GlobalFeatures |
||||
|
{ |
||||
|
public class RequiresGlobalFeatureTestPage_Tests : AspNetCoreMvcTestBase |
||||
|
{ |
||||
|
[Fact] |
||||
|
public async Task Should_404_If_Feature_Disabled() |
||||
|
{ |
||||
|
var result = await GetResponseAsync("/GlobalFeatures/DisabledGlobalFeatureTestPage", HttpStatusCode.NotFound); |
||||
|
result.StatusCode.ShouldBe(HttpStatusCode.NotFound); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Pass_Check_If_Feature_Enabled() |
||||
|
{ |
||||
|
var result = await GetResponseAsync("/GlobalFeatures/EnabledGlobalFeatureTestPage", HttpStatusCode.OK); |
||||
|
result.StatusCode.ShouldBe(HttpStatusCode.OK); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue