Browse Source

Merge branch 'dev' into pr/2563

pull/3732/head
Alper Ebicoglu 6 years ago
parent
commit
29afdb8db9
  1. 9
      framework/Volo.Abp.sln
  2. 10
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
  3. 46
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs
  4. 21
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapOptions.cs
  5. 3
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobOptions.cs
  6. 24
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs
  7. 2
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs
  8. 17
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs
  9. 46
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobQuartzOptions.cs
  10. 18
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs
  11. 22
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManageExtensions.cs
  12. 37
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs
  13. 29
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs
  14. 10
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkerQuartzOptions.cs
  15. 31
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs
  16. 8
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorker.cs
  17. 7
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerBase.cs
  18. 36
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs
  19. 31
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs
  20. 48
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs
  21. 23
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs
  22. 13
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  23. 22
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Claims/ClaimsMapTestController.cs
  24. 41
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Claims/ClaimsMapTestController_Tests.cs
  25. 26
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Program.cs
  26. 27
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Properties/launchSettings.json
  27. 15
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.csproj
  28. 6
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/AbpAspNetCoreMvcUiThemeSharedTestBase.cs
  29. 19
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/AbpAspNetCoreMvcUiThemeSharedTestModule.cs
  30. 113
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/PageToolbars/PageToolbar_Tests.cs
  31. 19
      framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Startup.cs
  32. 4
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Blogs/BlogAppService.cs
  33. 6
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml.cs
  34. 5
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs
  35. 6
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml.cs
  36. 5
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs
  37. 20
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Shared/Helpers/BlogNameControlHelper.cs
  38. 1
      modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj
  39. 20
      modules/blogging/test/Volo.Blogging.Application.Tests/Volo/Blogging/BlogAppService_Tests.cs
  40. 15
      samples/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/BackendAdminAppGatewayHostModule.cs
  41. 16
      samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGatewayHostModule.cs
  42. 16
      samples/MicroserviceDemo/gateways/PublicWebSiteGateway.Host/PublicWebSiteGatewayHostModule.cs
  43. 16
      samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs
  44. 17
      samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityServiceHostModule.cs
  45. 16
      samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceHostModule.cs
  46. 16
      samples/MicroserviceDemo/microservices/TenantManagementService.Host/TenantManagementServiceHostModule.cs
  47. 16
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

9
framework/Volo.Abp.sln

@ -287,7 +287,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Validation.Abstrac
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.SignalR", "src\Volo.Abp.AspNetCore.SignalR\Volo.Abp.AspNetCore.SignalR.csproj", "{B64FCE08-E9D2-4984-BF12-FE199F257416}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.SignalR.Tests", "test\Volo.Abp.AspNetCore.SignalR.Tests\Volo.Abp.AspNetCore.SignalR.Tests.csproj", "{8B758716-DCC9-4223-8421-5588D1597487}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.SignalR.Tests", "test\Volo.Abp.AspNetCore.SignalR.Tests\Volo.Abp.AspNetCore.SignalR.Tests.csproj", "{8B758716-DCC9-4223-8421-5588D1597487}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests", "test\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.csproj", "{79323211-E658-493E-9863-035AA4C3F913}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -859,6 +861,10 @@ Global
{8B758716-DCC9-4223-8421-5588D1597487}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B758716-DCC9-4223-8421-5588D1597487}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B758716-DCC9-4223-8421-5588D1597487}.Release|Any CPU.Build.0 = Release|Any CPU
{79323211-E658-493E-9863-035AA4C3F913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79323211-E658-493E-9863-035AA4C3F913}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79323211-E658-493E-9863-035AA4C3F913}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79323211-E658-493E-9863-035AA4C3F913}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1005,6 +1011,7 @@ Global
{FA5D1D6A-2A05-4A3D-99C1-2B6C1D1F99A3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{B64FCE08-E9D2-4984-BF12-FE199F257416} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{8B758716-DCC9-4223-8421-5588D1597487} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{79323211-E658-493E-9863-035AA4C3F913} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

10
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs

@ -1,4 +1,4 @@
using System;
using System;
using JetBrains.Annotations;
using Microsoft.AspNetCore.RequestLocalization;
using Microsoft.Extensions.DependencyInjection;
@ -6,6 +6,7 @@ using Microsoft.Extensions.Hosting;
using Volo.Abp;
using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.AspNetCore.Security.Claims;
using Volo.Abp.AspNetCore.Tracing;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection;
@ -76,5 +77,10 @@ namespace Microsoft.AspNetCore.Builder
app.Properties[ExceptionHandlingMiddlewareMarker] = true;
return app.UseMiddleware<AbpExceptionHandlingMiddleware>();
}
public static IApplicationBuilder UseAbpClaimsMap(this IApplicationBuilder app)
{
return app.UseMiddleware<AbpClaimsMapMiddleware>();
}
}
}
}

46
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapMiddleware.cs

@ -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);
}
}
}

21
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpClaimsMapOptions.cs

@ -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 },
};
}
}
}

3
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobOptions.cs

@ -8,8 +8,7 @@ namespace Volo.Abp.BackgroundJobs
{
private readonly Dictionary<Type, BackgroundJobConfiguration> _jobConfigurationsByArgsType;
private readonly Dictionary<string, BackgroundJobConfiguration> _jobConfigurationsByName;
//TODO: Implement for all providers! (Hangfire does not implement yet)
/// <summary>
/// Default: true.
/// </summary>

24
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs

@ -1,4 +1,8 @@
using Volo.Abp.Hangfire;
using System;
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Hangfire;
using Volo.Abp.Modularity;
namespace Volo.Abp.BackgroundJobs.Hangfire
@ -6,9 +10,23 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
[DependsOn(
typeof(AbpBackgroundJobsAbstractionsModule),
typeof(AbpHangfireModule)
)]
)]
public class AbpBackgroundJobsHangfireModule : AbpModule
{
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundJobOptions>>().Value;
if (!options.IsJobExecutionEnabled)
{
var hangfireOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpHangfireOptions>>().Value;
hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer;
}
}
private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider)
{
serviceProvider.GetRequiredService<JobStorage>();
return null;
}
}
}
}

2
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs

@ -8,7 +8,7 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
[Dependency(ReplaceServices = true)]
public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDependency
{
public Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
public virtual Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
TimeSpan? delay = null)
{
if (!delay.HasValue)

17
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.Threading;
@ -6,22 +8,31 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
{
public class HangfireJobExecutionAdapter<TArgs>
{
public ILogger<HangfireJobExecutionAdapter<TArgs>> Logger { get; set; }
protected AbpBackgroundJobOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; }
public HangfireJobExecutionAdapter(
IOptions<AbpBackgroundJobOptions> options,
IBackgroundJobExecuter jobExecuter,
IOptions<AbpBackgroundJobOptions> options,
IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{
JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
Logger = NullLogger<HangfireJobExecutionAdapter<TArgs>>.Instance;
}
public void Execute(TArgs args)
{
if (!Options.IsJobExecutionEnabled)
{
Logger.LogWarning("Background jobs system is disabled");
return;
}
using (var scope = ServiceScopeFactory.CreateScope())
{
var jobType = Options.GetJob(typeof(TArgs)).JobType;
@ -30,4 +41,4 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
}
}
}
}
}

46
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobQuartzOptions.cs

@ -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);
}
}
}

18
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
using Volo.Abp.Quartz;
@ -8,11 +10,21 @@ namespace Volo.Abp.BackgroundJobs.Quartz
typeof(AbpBackgroundJobsAbstractionsModule),
typeof(AbpQuartzModule)
)]
public class AbpBackgroundJobsQuartzModule :AbpModule
public class AbpBackgroundJobsQuartzModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient(typeof(QuartzJobExecutionAdapter<>));
}
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundJobOptions>>().Value;
if (!options.IsJobExecutionEnabled)
{
var quartzOptions = context.ServiceProvider.GetService<IOptions<AbpQuartzOptions>>().Value;
quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask;
}
}
}
}
}

22
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManageExtensions.cs

@ -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;
}
}
}

37
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs

@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Quartz;
using Volo.Abp.DependencyInjection;
@ -7,20 +8,40 @@ namespace Volo.Abp.BackgroundJobs.Quartz
{
[Dependency(ReplaceServices = true)]
public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDependency
{
private readonly IScheduler _scheduler;
public QuartzBackgroundJobManager(IScheduler scheduler)
{
public const string JobDataPrefix = "Abp";
public const string RetryIndex = "RetryIndex";
protected IScheduler Scheduler { get; }
protected AbpBackgroundJobQuartzOptions Options { get; }
public QuartzBackgroundJobManager(IScheduler scheduler,IOptions<AbpBackgroundJobQuartzOptions> options)
{
_scheduler = scheduler;
Scheduler = scheduler;
Options = options.Value;
}
public async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
TimeSpan? delay = null)
{
var jobDetail = JobBuilder.Create<QuartzJobExecutionAdapter<TArgs>>().SetJobData(new JobDataMap { { nameof(TArgs), args } }).Build();
return await ReEnqueueAsync(args, Options.RetryCount, Options.RetryIntervalMillisecond, priority, delay);
}
public virtual async Task<string> ReEnqueueAsync<TArgs>(TArgs args, int retryCount, int retryIntervalMillisecond,
BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
{
var jobDataMap = new JobDataMap
{
{nameof(TArgs), args},
{JobDataPrefix+ nameof(Options.RetryCount), retryCount},
{JobDataPrefix+ nameof(Options.RetryIntervalMillisecond), retryIntervalMillisecond},
{JobDataPrefix+ RetryIndex, 0}
};
var jobDetail = JobBuilder.Create<QuartzJobExecutionAdapter<TArgs>>().RequestRecovery().SetJobData(jobDataMap).Build();
var trigger = !delay.HasValue ? TriggerBuilder.Create().StartNow().Build() : TriggerBuilder.Create().StartAt(new DateTimeOffset(DateTime.Now.Add(delay.Value))).Build();
await _scheduler.ScheduleJob(jobDetail, trigger);
await Scheduler.ScheduleJob(jobDetail, trigger);
return jobDetail.Key.ToString();
}
}

29
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs

@ -1,6 +1,8 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Quartz;
@ -8,29 +10,50 @@ namespace Volo.Abp.BackgroundJobs.Quartz
{
public class QuartzJobExecutionAdapter<TArgs> : IJob
{
public ILogger<QuartzJobExecutionAdapter<TArgs>> Logger { get; set; }
protected AbpBackgroundJobOptions Options { get; }
protected AbpBackgroundJobQuartzOptions BackgroundJobQuartzOptions { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; }
public QuartzJobExecutionAdapter(
IOptions<AbpBackgroundJobOptions> options,
IOptions<AbpBackgroundJobQuartzOptions> backgroundJobQuartzOptions,
IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory)
{
JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
BackgroundJobQuartzOptions = backgroundJobQuartzOptions.Value;
Logger = NullLogger<QuartzJobExecutionAdapter<TArgs>>.Instance;
}
public async Task Execute(IJobExecutionContext context)
{
using (var scope = ServiceScopeFactory.CreateScope())
{
var args = (TArgs)context.JobDetail.JobDataMap.Get(nameof(TArgs));
var args = (TArgs) context.JobDetail.JobDataMap.Get(nameof(TArgs));
var jobType = Options.GetJob(typeof(TArgs)).JobType;
var jobContext = new JobExecutionContext(scope.ServiceProvider, jobType, args);
await JobExecuter.ExecuteAsync(jobContext);
try
{
await JobExecuter.ExecuteAsync(jobContext);
}
catch (Exception exception)
{
var jobExecutionException = new JobExecutionException(exception);
var retryIndex = context.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ QuartzBackgroundJobManager.RetryIndex);
retryIndex++;
context.JobDetail.JobDataMap.Put(QuartzBackgroundJobManager.JobDataPrefix+ QuartzBackgroundJobManager.RetryIndex, retryIndex);
await BackgroundJobQuartzOptions.RetryStrategy.Invoke(retryIndex, context, jobExecutionException);
throw jobExecutionException;
}
}
}
}
}
}

10
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkerQuartzOptions.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.BackgroundWorkers.Quartz
{
public class AbpBackgroundWorkerQuartzOptions
{
/// <summary>
/// Default : true.
/// </summary>
public bool IsAutoRegisterEnabled { get; set; } = true;
}
}

31
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs

@ -1,5 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
using Volo.Abp.Quartz;
@ -15,15 +17,30 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
{
context.Services.AddConventionalRegistrar(new AbpQuartzConventionalRegistrar());
}
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerOptions>>().Value;
if (!options.IsEnabled)
{
var quartzOptions = context.ServiceProvider.GetService<IOptions<AbpQuartzOptions>>().Value;
quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask;
}
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var backgroundWorkerManager = context.ServiceProvider.GetService<IBackgroundWorkerManager>();
var works = context.ServiceProvider.GetServices<IQuartzBackgroundWorker>();
foreach (var work in works)
var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerOptions>>().Value;
var quartzBackgroundWorkerOptions = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerQuartzOptions>>().Value;
if (options.IsEnabled && quartzBackgroundWorkerOptions.IsAutoRegisterEnabled)
{
backgroundWorkerManager.Add(work);
var backgroundWorkerManager = context.ServiceProvider.GetService<IBackgroundWorkerManager>();
var works = context.ServiceProvider.GetServices<IQuartzBackgroundWorker>().Where(x=>x.AutoRegister);
foreach (var work in works)
{
backgroundWorkerManager.Add(work);
}
}
}
}

8
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorker.cs

@ -1,4 +1,6 @@
using Quartz;
using System;
using System.Threading.Tasks;
using Quartz;
namespace Volo.Abp.BackgroundWorkers.Quartz
{
@ -7,5 +9,9 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
ITrigger Trigger { get; set; }
IJobDetail JobDetail { get; set; }
bool AutoRegister { get; set; }
Func<IScheduler,Task> ScheduleJob { get; set; }
}
}

7
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerBase.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Quartz;
namespace Volo.Abp.BackgroundWorkers.Quartz
@ -8,6 +9,10 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
public ITrigger Trigger { get; set; }
public IJobDetail JobDetail { get; set; }
public bool AutoRegister { get; set; } = true;
public Func<IScheduler, Task> ScheduleJob { get; set; } = null;
public abstract Task Execute(IJobExecutionContext context);
}

36
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs

@ -16,12 +16,12 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
_scheduler = scheduler;
}
public async Task StartAsync(CancellationToken cancellationToken = default)
public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{
await _scheduler.ResumeAll(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken = default)
public virtual async Task StopAsync(CancellationToken cancellationToken = default)
{
if (!_scheduler.IsShutdown)
{
@ -29,15 +29,41 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
}
}
public void Add(IBackgroundWorker worker)
public virtual void Add(IBackgroundWorker worker)
{
AsyncHelper.RunSync(() => ReScheduleJobAsync(worker));
}
protected virtual async Task ReScheduleJobAsync(IBackgroundWorker worker)
{
if (worker is IQuartzBackgroundWorker quartzWork)
{
Check.NotNull(quartzWork.Trigger, nameof(quartzWork.Trigger));
Check.NotNull(quartzWork.JobDetail, nameof(quartzWork.JobDetail));
AsyncHelper.RunSync(() => _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger));
if (quartzWork.ScheduleJob != null)
{
await quartzWork.ScheduleJob.Invoke(_scheduler);
}
else
{
await DefaultScheduleJobAsync(quartzWork);
}
}
}
protected virtual async Task DefaultScheduleJobAsync(IQuartzBackgroundWorker quartzWork)
{
if (await _scheduler.CheckExists(quartzWork.JobDetail.Key))
{
await _scheduler.AddJob(quartzWork.JobDetail, true, true);
await _scheduler.ResumeJob(quartzWork.JobDetail.Key);
await _scheduler.RescheduleJob(quartzWork.Trigger.Key, quartzWork.Trigger);
}
else
{
await _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger);
}
}
}
}
}

31
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs

@ -14,32 +14,33 @@ namespace Volo.Abp.Quartz
public override void ConfigureServices(ServiceConfigurationContext context)
{
var options = context.Services.ExecutePreConfiguredActions<AbpQuartzPreOptions>();
var options = context.Services.ExecutePreConfiguredActions<AbpQuartzOptions>();
context.Services.AddSingleton(AsyncHelper.RunSync(() => new StdSchedulerFactory(options.Properties).GetScheduler()));
context.Services.AddSingleton(typeof(IJobFactory), typeof(AbpQuartzJobFactory));
Configure<AbpQuartzOptions>(quartzOptions =>
{
quartzOptions.Properties = options.Properties;
quartzOptions.StartDelay = options.StartDelay;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpQuartzPreOptions>>().Value;
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpQuartzOptions>>().Value;
_scheduler = context.ServiceProvider.GetService<IScheduler>();
_scheduler.JobFactory = context.ServiceProvider.GetService<IJobFactory>();
if (options.StartDelay.Ticks > 0)
{
AsyncHelper.RunSync(() => _scheduler.StartDelayed(options.StartDelay));
}
else
{
AsyncHelper.RunSync(() => _scheduler.Start());
}
AsyncHelper.RunSync(() => options.StartSchedulerFactory.Invoke(_scheduler));
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
//TODO: ABP may provide two methods for application shutdown: OnPreApplicationShutdown & OnApplicationShutdown
AsyncHelper.RunSync(() => _scheduler.Shutdown());
if (_scheduler.IsStarted)
{
AsyncHelper.RunSync(() => _scheduler.Shutdown());
}
}
}
}
}

48
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs

@ -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();
}
}
}
}

23
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs

@ -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);
}
}
}

13
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs

@ -1,13 +1,13 @@
using System;
using System.Linq;
using System.Security.Claims;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Authorization;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.Localization.Resource;
using Volo.Abp.AspNetCore.Security.Claims;
using Volo.Abp.AspNetCore.TestBase;
using Volo.Abp.Autofac;
using Volo.Abp.Localization;
@ -76,11 +76,17 @@ namespace Volo.Abp.AspNetCore.Mvc
options.Languages.Add(new LanguageInfo("en", "en", "English"));
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
});
Configure<RazorPagesOptions>(options =>
{
options.RootDirectory = "/Volo/Abp/AspNetCore/Mvc";
});
Configure<AbpClaimsMapOptions>(options =>
{
options.Maps.Add("SerialNumber", () => ClaimTypes.SerialNumber);
options.Maps.Add("DateOfBirth", () => ClaimTypes.DateOfBirth);
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -92,6 +98,7 @@ namespace Volo.Abp.AspNetCore.Mvc
app.UseAbpRequestLocalization();
app.UseRouting();
app.UseMiddleware<FakeAuthenticationMiddleware>();
app.UseAbpClaimsMap();
app.UseAuthorization();
app.UseAuditing();
app.UseUnitOfWork();

22
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Claims/ClaimsMapTestController.cs

@ -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");
}
}
}

41
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Security/Claims/ClaimsMapTestController_Tests.cs

@ -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");
}
}
}

26
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Program.cs

@ -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>();
});
}
}

27
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Properties/launchSettings.json

@ -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"
}
}
}
}

15
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests.csproj

@ -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>

6
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/AbpAspNetCoreMvcUiThemeSharedTestBase.cs

@ -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>
{
}
}

19
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/AbpAspNetCoreMvcUiThemeSharedTestModule.cs

@ -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)
{
}
}
}

113
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/PageToolbars/PageToolbar_Tests.cs

@ -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");
}
}
}
}

19
framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Tests/Volo/Abp/AspNetCore/Mvc/UI/Theme/Shared/Startup.cs

@ -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();
}
}
}

4
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Blogs/BlogAppService.cs

@ -1,7 +1,7 @@
using System;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using Volo.Blogging.Blogs.Dtos;

6
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml.cs

@ -8,6 +8,7 @@ using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Comments;
using Volo.Blogging.Comments.Dtos;
using Volo.Blogging.Pages.Blogs.Shared.Helpers;
using Volo.Blogging.Posts;
namespace Volo.Blogging.Pages.Blog.Posts
@ -48,6 +49,11 @@ namespace Volo.Blogging.Pages.Blog.Posts
public virtual async Task<IActionResult> OnGetAsync()
{
if (BlogNameControlHelper.IsProhibitedFileFormatName(BlogShortName))
{
return NotFound();
}
await GetData();
return Page();

5
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Edit.cshtml.cs

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Pages.Blogs.Shared.Helpers;
using Volo.Blogging.Posts;
namespace Volo.Blogging.Pages.Blog.Posts
@ -39,6 +40,10 @@ namespace Volo.Blogging.Pages.Blog.Posts
{
return Redirect("/");
}
if (BlogNameControlHelper.IsProhibitedFileFormatName(BlogShortName))
{
return NotFound();
}
var postDto = await _postAppService.GetAsync(new Guid(PostId));
Post = ObjectMapper.Map<PostWithDetailsDto, EditPostViewModel>(postDto);

6
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Index.cshtml.cs

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Pages.Blogs.Shared.Helpers;
using Volo.Blogging.Posts;
using Volo.Blogging.Tagging;
using Volo.Blogging.Tagging.Dtos;
@ -37,6 +38,11 @@ namespace Volo.Blogging.Pages.Blog.Posts
public virtual async Task<ActionResult> OnGetAsync()
{
if (BlogNameControlHelper.IsProhibitedFileFormatName(BlogShortName))
{
return NotFound();
}
Blog = await _blogAppService.GetByShortNameAsync(BlogShortName);
Posts = (await _postAppService.GetListByBlogIdAndTagName(Blog.Id, TagName)).Items;
PopularTags = (await _tagAppService.GetPopularTags(Blog.Id, new GetPopularTagsInput {ResultCount = 10, MinimumPostCount = 2}));

5
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/New.cshtml.cs

@ -8,6 +8,7 @@ using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Pages.Blogs.Shared.Helpers;
using Volo.Blogging.Posts;
namespace Volo.Blogging.Pages.Blog.Posts
@ -41,6 +42,10 @@ namespace Volo.Blogging.Pages.Blog.Posts
{
return Redirect("/");
}
if (BlogNameControlHelper.IsProhibitedFileFormatName(BlogShortName))
{
return NotFound();
}
Blog = await _blogAppService.GetByShortNameAsync(BlogShortName);
Post = new CreatePostViewModel

20
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Shared/Helpers/BlogNameControlHelper.cs

@ -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));
}
}
}

1
modules/blogging/test/Volo.Blogging.Application.Tests/Volo.Blogging.Application.Tests.csproj

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Blogging.Application\Volo.Blogging.Application.csproj" />
<ProjectReference Include="..\..\src\Volo.Blogging.Web\Volo.Blogging.Web.csproj" />
<ProjectReference Include="..\Volo.Blogging.Domain.Tests\Volo.Blogging.Domain.Tests.csproj" />
</ItemGroup>

20
modules/blogging/test/Volo.Blogging.Application.Tests/Volo/Blogging/BlogAppService_Tests.cs

@ -6,6 +6,7 @@ using Volo.Blogging.Blogs;
using Volo.Blogging.Blogs.Dtos;
using Volo.Blogging.Comments;
using Volo.Blogging.Comments.Dtos;
using Volo.Blogging.Pages.Blogs.Shared.Helpers;
using Volo.Blogging.Posts;
using Xunit;
@ -41,6 +42,25 @@ namespace Volo.Blogging
blog.Name.ShouldBe(targetBlog.Name);
}
[Theory]
[InlineData("favicon.ICO")]
[InlineData("favicon.ico")]
[InlineData("wp-login.php")]
[InlineData("wp-login.PHP")]
[InlineData("robots.txt")]
public void Should_Return_True_For_FileExtension_Shortname(string blogShortName)
{
BlogNameControlHelper.IsProhibitedFileFormatName(blogShortName).ShouldBe(true);
}
[Theory]
[InlineData("test-post")]
[InlineData("Test.Module")]
public void Should_Return_False_For_Normal_Shortname(string blogShortName)
{
BlogNameControlHelper.IsProhibitedFileFormatName(blogShortName).ShouldBe(false);
}
[Fact]
public async Task Should_Create_A_Blog()
{

15
samples/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/BackendAdminAppGatewayHostModule.cs

@ -110,21 +110,8 @@ namespace BackendAdminAppGateway.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAbpClaimsMap();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
if (MsDemoConsts.IsMultiTenancyEnabled)
{
app.UseMultiTenancy();

16
samples/MicroserviceDemo/gateways/InternalGateway.Host/InternalGatewayHostModule.cs

@ -89,21 +89,7 @@ namespace InternalGateway.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{
app.UseMultiTenancy();

16
samples/MicroserviceDemo/gateways/PublicWebSiteGateway.Host/PublicWebSiteGatewayHostModule.cs

@ -85,21 +85,7 @@ namespace PublicWebSiteGateway.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{
app.UseMultiTenancy();

16
samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs

@ -121,21 +121,7 @@ namespace BloggingService.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{

17
samples/MicroserviceDemo/microservices/IdentityService.Host/IdentityServiceHostModule.cs

@ -102,26 +102,13 @@ namespace IdentityService.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{
app.UseMultiTenancy();
}
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpRequestLocalization(); //TODO: localization?
app.UseSwagger();
app.UseSwaggerUI(options =>

16
samples/MicroserviceDemo/microservices/ProductService.Host/ProductServiceHostModule.cs

@ -105,21 +105,7 @@ namespace ProductService.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{

16
samples/MicroserviceDemo/microservices/TenantManagementService.Host/TenantManagementServiceHostModule.cs

@ -106,21 +106,7 @@ namespace TenantManagementService.Host
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpClaimsMap();
if (MsDemoConsts.IsMultiTenancyEnabled)
{

16
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyProjectNameHttpApiHostModule.cs

@ -168,25 +168,11 @@ namespace MyCompanyName.MyProjectName
app.UseRouting();
app.UseCors(DefaultCorsPolicyName);
app.UseAuthentication();
app.UseAbpClaimsMap();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.Use(async (ctx, next) =>
{
var currentPrincipalAccessor = ctx.RequestServices.GetRequiredService<ICurrentPrincipalAccessor>();
var map = new Dictionary<string, string>()
{
{ "sub", AbpClaimTypes.UserId },
{ "role", AbpClaimTypes.Role },
{ "email", AbpClaimTypes.Email },
//any other map
};
var mapClaims = currentPrincipalAccessor.Principal.Claims.Where(p => map.Keys.Contains(p.Type)).ToList();
currentPrincipalAccessor.Principal.AddIdentity(new ClaimsIdentity(mapClaims.Select(p => new Claim(map[p.Type], p.Value, p.ValueType, p.Issuer))));
await next();
});
app.UseAbpRequestLocalization();
app.UseAuthorization();
app.UseSwagger();

Loading…
Cancel
Save