mirror of https://github.com/abpframework/abp.git
47 changed files with 772 additions and 202 deletions
@ -0,0 +1,46 @@ |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Security.Claims; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Security.Claims |
|||
{ |
|||
public class AbpClaimsMapMiddleware : IMiddleware, ITransientDependency |
|||
{ |
|||
public async Task InvokeAsync(HttpContext context, RequestDelegate next) |
|||
{ |
|||
var currentPrincipalAccessor = context.RequestServices |
|||
.GetRequiredService<ICurrentPrincipalAccessor>(); |
|||
|
|||
var mapOptions = context.RequestServices |
|||
.GetRequiredService<IOptions<AbpClaimsMapOptions>>().Value; |
|||
|
|||
var mapClaims = currentPrincipalAccessor |
|||
.Principal |
|||
.Claims |
|||
.Where(claim => mapOptions.Maps.Keys.Contains(claim.Type)); |
|||
|
|||
currentPrincipalAccessor |
|||
.Principal |
|||
.AddIdentity( |
|||
new ClaimsIdentity( |
|||
mapClaims |
|||
.Select( |
|||
claim => new Claim( |
|||
mapOptions.Maps[claim.Type](), |
|||
claim.Value, |
|||
claim.ValueType, |
|||
claim.Issuer |
|||
) |
|||
) |
|||
) |
|||
); |
|||
|
|||
await next(context); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Security.Claims; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Security.Claims |
|||
{ |
|||
public class AbpClaimsMapOptions |
|||
{ |
|||
public Dictionary<string, Func<string>> Maps { get; } |
|||
|
|||
public AbpClaimsMapOptions() |
|||
{ |
|||
Maps = new Dictionary<string, Func<string>>() |
|||
{ |
|||
{ "sub", () => AbpClaimTypes.UserId }, |
|||
{ "role", () => AbpClaimTypes.Role }, |
|||
{ "email", () => AbpClaimTypes.Email }, |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Quartz; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.Quartz |
|||
{ |
|||
public class AbpBackgroundJobQuartzOptions |
|||
{ |
|||
public int RetryCount { get; set; } |
|||
|
|||
public int RetryIntervalMillisecond { get; set; } |
|||
|
|||
|
|||
[NotNull] |
|||
public Func<int, IJobExecutionContext, JobExecutionException,Task> RetryStrategy |
|||
{ |
|||
get => _retryStrategy; |
|||
set => _retryStrategy = Check.NotNull(value, nameof(value)); |
|||
} |
|||
private Func<int, IJobExecutionContext, JobExecutionException,Task> _retryStrategy; |
|||
|
|||
public AbpBackgroundJobQuartzOptions() |
|||
{ |
|||
RetryCount = 3; |
|||
RetryIntervalMillisecond = 3000; |
|||
_retryStrategy = DefaultRetryStrategy; |
|||
} |
|||
|
|||
private async Task DefaultRetryStrategy(int retryIndex, IJobExecutionContext executionContext, JobExecutionException exception) |
|||
{ |
|||
exception.RefireImmediately = true; |
|||
|
|||
var retryCount = executionContext.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ nameof(RetryCount)); |
|||
if (retryIndex > retryCount) |
|||
{ |
|||
exception.RefireImmediately = false; |
|||
exception.UnscheduleAllTriggers = true; |
|||
return; |
|||
} |
|||
|
|||
var retryInterval = executionContext.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ nameof(RetryIntervalMillisecond)); |
|||
await Task.Delay(retryInterval); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Quartz; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.Quartz |
|||
{ |
|||
public static class QuartzBackgroundJobManageExtensions |
|||
{ |
|||
public static async Task<string> EnqueueAsync<TArgs>(this IBackgroundJobManager backgroundJobManager, |
|||
TArgs args, int retryCount, int retryIntervalMillisecond, |
|||
BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) |
|||
{ |
|||
if (backgroundJobManager is QuartzBackgroundJobManager quartzBackgroundJobManager) |
|||
{ |
|||
return await quartzBackgroundJobManager.ReEnqueueAsync(args, retryCount, retryIntervalMillisecond, |
|||
priority, delay); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace Volo.Abp.BackgroundWorkers.Quartz |
|||
{ |
|||
public class AbpBackgroundWorkerQuartzOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Default : true.
|
|||
/// </summary>
|
|||
public bool IsAutoRegisterEnabled { get; set; } = true; |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
using System; |
|||
using System.Collections.Specialized; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Quartz; |
|||
|
|||
namespace Volo.Abp.Quartz |
|||
{ |
|||
public class AbpQuartzOptions |
|||
{ |
|||
/// <summary>
|
|||
/// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory.
|
|||
/// </summary>
|
|||
public NameValueCollection Properties { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// How long Quartz should wait before starting. Default: 0.
|
|||
/// </summary>
|
|||
public TimeSpan StartDelay { get; set; } |
|||
|
|||
[NotNull] |
|||
public Func<IScheduler, Task> StartSchedulerFactory |
|||
{ |
|||
get => _startSchedulerFactory; |
|||
set => _startSchedulerFactory = Check.NotNull(value, nameof(value)); |
|||
} |
|||
private Func<IScheduler, Task> _startSchedulerFactory; |
|||
|
|||
public AbpQuartzOptions() |
|||
{ |
|||
Properties = new NameValueCollection(); |
|||
StartDelay = new TimeSpan(0); |
|||
_startSchedulerFactory = StartSchedulerAsync; |
|||
} |
|||
|
|||
private async Task StartSchedulerAsync(IScheduler scheduler) |
|||
{ |
|||
if (StartDelay.Ticks > 0) |
|||
{ |
|||
await scheduler.StartDelayed(StartDelay); |
|||
} |
|||
else |
|||
{ |
|||
await scheduler.Start(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,23 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Specialized; |
|||
|
|||
namespace Volo.Abp.Quartz |
|||
{ |
|||
public class AbpQuartzPreOptions |
|||
{ |
|||
/// <summary>
|
|||
/// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory.
|
|||
/// </summary>
|
|||
public NameValueCollection Properties { get; set; } |
|||
/// <summary>
|
|||
/// How long Quartz should wait before starting. Default: 0.
|
|||
/// </summary>
|
|||
public TimeSpan StartDelay { get; set; } |
|||
|
|||
public AbpQuartzPreOptions() |
|||
{ |
|||
Properties = new NameValueCollection(); |
|||
StartDelay = new TimeSpan(0); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Security.Claims; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Shouldly; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Security.Claims |
|||
{ |
|||
public class ClaimsMapTestController : AbpController |
|||
{ |
|||
public ActionResult ClaimsMapTest() |
|||
{ |
|||
var serialNumber = CurrentUser.FindClaim(ClaimTypes.SerialNumber); |
|||
serialNumber.ShouldNotBeNull(); |
|||
serialNumber.Value.ShouldBe("123456"); |
|||
|
|||
var dateOfBirth = CurrentUser.FindClaim(ClaimTypes.DateOfBirth); |
|||
dateOfBirth.ShouldNotBeNull(); |
|||
dateOfBirth.Value.ShouldBe("2020"); |
|||
|
|||
return Content("OK"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using System.Security.Claims; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.AspNetCore.Mvc.Authorization; |
|||
using Volo.Abp.AspNetCore.TestBase; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.MemoryDb; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.Security.Claims |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreTestBaseModule), |
|||
typeof(AbpMemoryDbTestModule), |
|||
typeof(AbpAspNetCoreMvcModule), |
|||
typeof(AbpAutofacModule) |
|||
)] |
|||
public class ClaimsMapTestController_Tests : AspNetCoreMvcTestBase |
|||
{ |
|||
private readonly FakeUserClaims _fakeRequiredService; |
|||
|
|||
public ClaimsMapTestController_Tests() |
|||
{ |
|||
_fakeRequiredService = GetRequiredService<FakeUserClaims>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Claims_Should_Be_Mapped() |
|||
{ |
|||
_fakeRequiredService.Claims.AddRange(new[] |
|||
{ |
|||
new Claim("SerialNumber", "123456"), |
|||
new Claim("DateOfBirth", "2020") |
|||
}); |
|||
|
|||
var result = await GetResponseAsStringAsync("/ClaimsMapTest/ClaimsMapTest"); |
|||
result.ShouldBe("OK"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main(string[] args) |
|||
{ |
|||
CreateHostBuilder(args).Build().Run(); |
|||
} |
|||
|
|||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:56574", |
|||
"sslPort": 44374 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:5001;http://localhost:5000", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.AspNetCore.TestBase\Volo.Abp.AspNetCore.TestBase.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Core\Volo.Abp.Core.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Tests\Volo.Abp.AspNetCore.Tests.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,6 @@ |
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared |
|||
{ |
|||
public class AbpAspNetCoreMvcUiThemeSharedTestBase : AbpAspNetCoreTestBase<Startup> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using Volo.Abp.AspNetCore.TestBase; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpAspNetCoreTestBaseModule), |
|||
typeof(AbpAspNetCoreMvcUiThemeSharedModule) |
|||
)] |
|||
public class AbpAspNetCoreMvcUiThemeSharedTestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Options; |
|||
using Shouldly; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar.Button; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.PageToolbars; |
|||
using Volo.Abp.Localization; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.PageToolbars |
|||
{ |
|||
public class PageToolbar_Tests : AbpAspNetCoreMvcUiThemeSharedTestBase |
|||
{ |
|||
protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) |
|||
{ |
|||
services.Configure<AbpPageToolbarOptions>(options => |
|||
{ |
|||
options.Configure("TestPage1", toolbar => |
|||
{ |
|||
toolbar.Contributors.Add(new MyToolbarContributor()); |
|||
toolbar.Contributors.Add(new MyToolbarContributor2()); |
|||
toolbar.AddComponent<MyPageComponent5>(); |
|||
toolbar.AddButton(new FixedLocalizableString("My button"), order: -1); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AbpPageToolbarOptions_Should_Contain_Contributors() |
|||
{ |
|||
var options = GetRequiredService<IOptions<AbpPageToolbarOptions>>().Value; |
|||
options.Toolbars.Count.ShouldBe(1); |
|||
options.Toolbars.ShouldContainKey("TestPage1"); |
|||
options.Toolbars["TestPage1"].Contributors.Count.ShouldBe(4); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task PageToolbarManager_Should_Return_ToolbarItems() |
|||
{ |
|||
var pageToolbarManager = GetRequiredService<IPageToolbarManager>(); |
|||
var items = await pageToolbarManager.GetItemsAsync("TestPage1"); |
|||
items.Length.ShouldBe(5); |
|||
items[0].ComponentType.ShouldBe(typeof(AbpPageToolbarButtonViewComponent)); |
|||
items[1].ComponentType.ShouldBe(typeof(MyPageComponent2)); |
|||
items[2].ComponentType.ShouldBe(typeof(MyPageComponent3)); |
|||
items[3].ComponentType.ShouldBe(typeof(MyPageComponent4)); |
|||
items[4].ComponentType.ShouldBe(typeof(MyPageComponent5)); |
|||
} |
|||
|
|||
public class MyToolbarContributor : IPageToolbarContributor |
|||
{ |
|||
public Task ContributeAsync(PageToolbarContributionContext context) |
|||
{ |
|||
context.Items.Add(new PageToolbarItem(typeof(MyPageComponent1))); |
|||
context.Items.Add(new PageToolbarItem(typeof(MyPageComponent2))); |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
|
|||
public class MyToolbarContributor2 : IPageToolbarContributor |
|||
{ |
|||
public Task ContributeAsync(PageToolbarContributionContext context) |
|||
{ |
|||
context.Items.RemoveAll(i => i.ComponentType == typeof(MyPageComponent1)); |
|||
context.Items.Add(new PageToolbarItem(typeof(MyPageComponent3))); |
|||
context.Items.Add(new PageToolbarItem(typeof(MyPageComponent4))); |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
|
|||
public class MyPageComponent1 : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult InvokeAsync() |
|||
{ |
|||
return Content("MyPageComponent1"); |
|||
} |
|||
} |
|||
|
|||
public class MyPageComponent2 : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult InvokeAsync() |
|||
{ |
|||
return Content("MyPageComponent2"); |
|||
} |
|||
} |
|||
|
|||
public class MyPageComponent3 : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult InvokeAsync() |
|||
{ |
|||
return Content("MyPageComponent3"); |
|||
} |
|||
} |
|||
|
|||
public class MyPageComponent4 : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult InvokeAsync() |
|||
{ |
|||
return Content("MyPageComponent4"); |
|||
} |
|||
} |
|||
|
|||
public class MyPageComponent5 : AbpViewComponent |
|||
{ |
|||
public IViewComponentResult InvokeAsync() |
|||
{ |
|||
return Content("MyPageComponent4"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddApplication<AbpAspNetCoreMvcUiThemeSharedTestModule>(); |
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) |
|||
{ |
|||
app.InitializeApplication(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.IO; |
|||
using System.Linq; |
|||
|
|||
namespace Volo.Blogging.Pages.Blogs.Shared.Helpers |
|||
{ |
|||
public static class BlogNameControlHelper |
|||
{ |
|||
public static readonly string[] ProhibitedFileExtensions = new string[] {"ico", "txt", "php"}; |
|||
|
|||
public static bool IsProhibitedFileFormatName(string blogShortName) |
|||
{ |
|||
if (string.IsNullOrWhiteSpace(blogShortName)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return ProhibitedFileExtensions.Any(x => blogShortName.ToLowerInvariant().EndsWith(x)); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue