From e151d16804a5b7c53e3ad9d7a442004dedb1b6cb Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Nov 2020 09:28:57 +0800 Subject: [PATCH 01/16] Use AbpDynamicOptionsManager to replace AbpOptionsFactory. --- .../AbpRequestLocalizationMiddleware.cs | 8 ++- .../AbpRequestLocalizationOptionsFactory.cs | 28 ----------- .../AbpRequestLocalizationOptionsManager.cs | 32 ++++++++++++ ...ltAbpRequestLocalizationOptionsProvider.cs | 11 ---- .../IAbpRequestLocalizationOptionsProvider.cs | 4 +- .../Abp/AspNetCore/AbpAspNetCoreModule.cs | 2 +- .../Abp/Options/AbpDynamicOptionsManager.cs | 4 +- .../Volo/Abp/Options/AbpOptionsFactory.cs | 50 +++++++++++++++++-- ...Factory.cs => AbpAbpLdapOptionsManager.cs} | 22 ++------ .../Volo/Abp/Ldap/AbpLdapModule.cs | 3 +- .../Volo/Abp/Ldap/LdapOptions_Tests.cs | 2 +- .../BloggingTestAppModule.cs | 2 +- .../Abp/Identity/AbpIdentityOptionsManager.cs | 2 +- 13 files changed, 94 insertions(+), 76 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs create mode 100644 framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs rename framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/{AbpAbpLdapOptionsFactory.cs => AbpAbpLdapOptionsManager.cs} (61%) diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs index 2a8c48b1c5..e83e240c85 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationMiddleware.cs @@ -23,15 +23,13 @@ namespace Microsoft.AspNetCore.RequestLocalization public async Task InvokeAsync(HttpContext context, RequestDelegate next) { + var middleware = new RequestLocalizationMiddleware( next, - new OptionsWrapper( - await _requestLocalizationOptionsProvider.GetLocalizationOptionsAsync() -), - _loggerFactory + new OptionsWrapper(await _requestLocalizationOptionsProvider.GetLocalizationOptionsAsync()), _loggerFactory ); await middleware.Invoke(context); } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs deleted file mode 100644 index 10cce6a776..0000000000 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Options; -using Volo.Abp.Options; - -namespace Microsoft.AspNetCore.RequestLocalization -{ - public class AbpRequestLocalizationOptionsFactory : AbpOptionsFactory - { - private readonly IAbpRequestLocalizationOptionsProvider _abpRequestLocalizationOptionsProvider; - - public AbpRequestLocalizationOptionsFactory( - IAbpRequestLocalizationOptionsProvider abpRequestLocalizationOptionsProvider, - IEnumerable> setups, - IEnumerable> postConfigures) - : base( - setups, - postConfigures) - { - _abpRequestLocalizationOptionsProvider = abpRequestLocalizationOptionsProvider; - } - - public override RequestLocalizationOptions Create(string name) - { - return _abpRequestLocalizationOptionsProvider.GetLocalizationOptions(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs new file mode 100644 index 0000000000..3748e6ff6c --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/AbpRequestLocalizationOptionsManager.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Options; +using Volo.Abp.Options; + +namespace Microsoft.AspNetCore.RequestLocalization +{ + public class AbpRequestLocalizationOptionsManager : AbpDynamicOptionsManager + { + private RequestLocalizationOptions _options; + + private readonly IAbpRequestLocalizationOptionsProvider _abpRequestLocalizationOptionsProvider; + + public AbpRequestLocalizationOptionsManager( + IOptionsFactory factory, + IAbpRequestLocalizationOptionsProvider abpRequestLocalizationOptionsProvider) + : base(factory) + { + _abpRequestLocalizationOptionsProvider = abpRequestLocalizationOptionsProvider; + } + + public override RequestLocalizationOptions Get(string name) + { + return _options ?? base.Get(name); + } + + protected override async Task OverrideOptionsAsync(string name, RequestLocalizationOptions options) + { + _options = await _abpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync(); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs index eca6990649..24713651f5 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/DefaultAbpRequestLocalizationOptionsProvider.cs @@ -11,7 +11,6 @@ using Nito.AsyncEx; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.Settings; -using Volo.Abp.Threading; namespace Microsoft.AspNetCore.RequestLocalization { @@ -33,16 +32,6 @@ namespace Microsoft.AspNetCore.RequestLocalization _optionsAction = optionsAction; } - public RequestLocalizationOptions GetLocalizationOptions() - { - if (_requestLocalizationOptions != null) - { - return _requestLocalizationOptions; - } - - return AsyncHelper.RunSync(GetLocalizationOptionsAsync); - } - public async Task GetLocalizationOptionsAsync() { if (_requestLocalizationOptions == null) diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs index cb4daec7f2..aea718b7cb 100644 --- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/RequestLocalization/IAbpRequestLocalizationOptionsProvider.cs @@ -8,8 +8,6 @@ namespace Microsoft.AspNetCore.RequestLocalization { void InitLocalizationOptions(Action optionsAction = null); - RequestLocalizationOptions GetLocalizationOptions(); - Task GetLocalizationOptionsAsync(); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index fad534949d..c97c3787e7 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -38,7 +38,7 @@ namespace Volo.Abp.AspNetCore AddAspNetServices(context.Services); context.Services.AddObjectAccessor(); - context.Services.Replace(ServiceDescriptor.Transient, AbpRequestLocalizationOptionsFactory>()); + context.Services.AddAbpDynamicOptions(); } private static void AddAspNetServices(IServiceCollection services) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs index af40ff1825..43d98aead4 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs @@ -16,9 +16,9 @@ namespace Volo.Abp.Options public virtual Task SetAsync(string name) { - return OverrideOptionsAsync(base.Get(name)); + return OverrideOptionsAsync(name, base.Get(name)); } - protected abstract Task OverrideOptionsAsync(T options); + protected abstract Task OverrideOptionsAsync(string name, T options); } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs index ecbe0d8271..e2a7a7bf53 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpOptionsFactory.cs @@ -4,21 +4,44 @@ using Microsoft.Extensions.Options; namespace Volo.Abp.Options { //TODO: Derive from OptionsFactory when this is released: https://github.com/aspnet/Options/pull/258 (or completely remove this!) + // https://github.com/dotnet/runtime/blob/master/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs public class AbpOptionsFactory : IOptionsFactory where TOptions : class, new() { private readonly IEnumerable> _setups; private readonly IEnumerable> _postConfigures; + private readonly IEnumerable> _validations; - public AbpOptionsFactory(IEnumerable> setups, IEnumerable> postConfigures) + public AbpOptionsFactory( + IEnumerable> setups, + IEnumerable> postConfigures) + : this(setups, postConfigures, validations: null) + { + + } + + public AbpOptionsFactory( + IEnumerable> setups, + IEnumerable> postConfigures, + IEnumerable> validations) { _setups = setups; _postConfigures = postConfigures; + _validations = validations; } public virtual TOptions Create(string name) { var options = new TOptions(); + ConfigureOptions(name, options); + PostConfigureOptions(name, options); + ValidateOptions(name, options); + + return options; + } + + protected virtual void ConfigureOptions(string name, TOptions options) + { foreach (var setup in _setups) { if (setup is IConfigureNamedOptions namedSetup) @@ -30,13 +53,34 @@ namespace Volo.Abp.Options setup.Configure(options); } } + } + protected virtual void PostConfigureOptions(string name, TOptions options) + { foreach (var post in _postConfigures) { post.PostConfigure(name, options); } + } - return options; + protected virtual void ValidateOptions(string name, TOptions options) + { + if (_validations != null) + { + var failures = new List(); + foreach (var validate in _validations) + { + var result = validate.Validate(name, options); + if (result.Failed) + { + failures.AddRange(result.Failures); + } + } + if (failures.Count > 0) + { + throw new OptionsValidationException(name, typeof(TOptions), failures); + } + } } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs similarity index 61% rename from framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs rename to framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs index 9579e169be..57d13693b4 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsFactory.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpAbpLdapOptionsManager.cs @@ -1,36 +1,22 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Options; using Volo.Abp.Options; using Volo.Abp.Settings; -using Volo.Abp.Threading; namespace Volo.Abp.Ldap { - public class AbpAbpLdapOptionsFactory : AbpOptionsFactory + public class AbpAbpLdapOptionsManager : AbpDynamicOptionsManager { protected ISettingProvider SettingProvider { get; } - public AbpAbpLdapOptionsFactory( - IEnumerable> setups, - IEnumerable> postConfigures, - ISettingProvider settingProvider) - : base(setups, postConfigures) + public AbpAbpLdapOptionsManager(IOptionsFactory factory, ISettingProvider settingProvider) + : base(factory) { SettingProvider = settingProvider; } - public override AbpLdapOptions Create(string name) - { - var options = base.Create(name); - - AsyncHelper.RunSync(() => OverrideOptionsAsync(options)); - - return options; - } - - protected virtual async Task OverrideOptionsAsync(AbpLdapOptions options) + protected override async Task OverrideOptionsAsync(string name, AbpLdapOptions options) { options.ServerHost = await GetSettingOrDefaultValue(LdapSettingNames.ServerHost, options.ServerHost); options.ServerPort = await SettingProvider.GetAsync(LdapSettingNames.ServerPort, options.ServerPort); diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs index c842d4d76b..3366f3d70f 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs @@ -18,8 +18,7 @@ namespace Volo.Abp.Ldap { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Replace(ServiceDescriptor.Transient, AbpAbpLdapOptionsFactory>()); - context.Services.Replace(ServiceDescriptor.Scoped, OptionsManager>()); + context.Services.AddAbpDynamicOptions(); var configuration = context.Services.GetConfiguration(); var ldapConfiguration = configuration["Ldap"]; diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs index 8ec7ef94c6..d6e6e1fc29 100644 --- a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapOptions_Tests.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Ldap [Fact] public void Should_Resolve_AbpAbpLdapOptionsFactory() { - GetRequiredService>().ShouldBeOfType(typeof(AbpAbpLdapOptionsFactory)); + GetRequiredService>().ShouldBeOfType(typeof(AbpAbpLdapOptionsManager)); } } } diff --git a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs index 600cc05f84..c41beef251 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs +++ b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs @@ -166,7 +166,7 @@ namespace Volo.BloggingTestApp app.UseAuthentication(); - app.UseRequestLocalization(app.ApplicationServices.GetRequiredService>().Value); + app.UseAbpRequestLocalization(); app.UseConfiguredEndpoints(); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs index 5735f36051..8ff4c141eb 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.Identity SettingProvider = settingProvider; } - protected override async Task OverrideOptionsAsync(IdentityOptions options) + protected override async Task OverrideOptionsAsync(string name, IdentityOptions options) { options.Password.RequiredLength = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredLength, options.Password.RequiredLength); options.Password.RequiredUniqueChars = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredUniqueChars, options.Password.RequiredUniqueChars); From 07d47ce314743df66770156d94491730094d2b31 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Nov 2020 17:27:36 +0800 Subject: [PATCH 02/16] Update Abp-4_0.md --- docs/en/Migration-Guides/Abp-4_0.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/Abp-4_0.md b/docs/en/Migration-Guides/Abp-4_0.md index 33ccc63513..6c5540df9e 100644 --- a/docs/en/Migration-Guides/Abp-4_0.md +++ b/docs/en/Migration-Guides/Abp-4_0.md @@ -251,6 +251,7 @@ public class MyService : ITransientDependency ```` Pre-built modules already handles this. However, if you have used `IdentityOptions` directly in your code, you also need to follow this new pattern. +Please make sure that the injected `IOptions` service and the service consuming it are in the same scope of dependency injection container. ## ASP.NET Core MVC / Razor Pages UI @@ -262,4 +263,4 @@ See the [Angular UI Migration Guide](Abp-4_0-Angular.md). ## Blazor UI -See the [Blazor UI Migration Guide](Abp-4_0-Blazor.md). \ No newline at end of file +See the [Blazor UI Migration Guide](Abp-4_0-Blazor.md). From e91dd06f3e86c307fe32dc61ad05e878d4c11dae Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 27 Nov 2020 21:32:42 +0800 Subject: [PATCH 03/16] Use LdapForNet instead of Novell. Make Ldap async! --- .../src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj | 2 +- .../Volo/Abp/Ldap/ILdapManager.cs | 6 ++-- .../Volo/Abp/Ldap/LdapManager.cs | 34 +++++++++++++------ .../Volo/Abp/Ldap/LdapManager_Tests.cs | 10 +++--- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj index 277ac1c24b..584c3e74c0 100644 --- a/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj +++ b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs index 6ad66b0cb3..2d41724c88 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs @@ -1,7 +1,9 @@ -namespace Volo.Abp.Ldap +using System.Threading.Tasks; + +namespace Volo.Abp.Ldap { public interface ILdapManager { - bool Authenticate(string username, string password); + Task AuthenticateAsync(string username, string password); } } diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs index 2d890c10f7..7a8d06746a 100644 --- a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs @@ -1,6 +1,8 @@ using System; +using System.Threading.Tasks; +using LdapForNet; +using LdapForNet.Native; using Microsoft.Extensions.Options; -using Novell.Directory.Ldap; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.DependencyInjection; @@ -15,17 +17,16 @@ namespace Volo.Abp.Ldap public LdapManager(IOptions ldapSettingsOptions) { LdapOptions = ldapSettingsOptions.Value; - Logger = NullLogger.Instance; } - public bool Authenticate(string username, string password) + public virtual async Task AuthenticateAsync(string username, string password) { try { - using (var conn = CreateLdapConnection()) + using (var conn = await CreateLdapConnectionAsync()) { - AuthenticateLdapConnection(conn, username, password); + await AuthenticateLdapConnectionAsync(conn, username, password); return true; } } @@ -36,22 +37,33 @@ namespace Volo.Abp.Ldap } } - protected virtual ILdapConnection CreateLdapConnection() + protected virtual async Task CreateLdapConnectionAsync() { var ldapConnection = new LdapConnection(); - ConfigureLdapConnection(ldapConnection); - ldapConnection.Connect(LdapOptions.ServerHost, LdapOptions.ServerPort); + await ConfigureLdapConnectionAsync(ldapConnection); + await ConnectAsync(ldapConnection); return ldapConnection; } - protected virtual void ConfigureLdapConnection(ILdapConnection connection) + protected virtual Task ConfigureLdapConnectionAsync(ILdapConnection ldapConnection) { + return Task.CompletedTask; + } + protected virtual Task ConnectAsync(ILdapConnection ldapConnection) + { + ldapConnection.Connect(LdapOptions.ServerHost, LdapOptions.ServerPort); + + return Task.CompletedTask; } - protected virtual void AuthenticateLdapConnection(ILdapConnection connection, string username, string password) + protected virtual async Task AuthenticateLdapConnectionAsync(ILdapConnection connection, string username, string password) { - connection.Bind(username, password); + await connection.BindAsync(Native.LdapAuthType.Simple, new LdapCredential() + { + UserName = username, + Password = password + }); } } } diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs index 8da9a9303d..6cc3a0acc7 100644 --- a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs @@ -1,4 +1,5 @@ -using Shouldly; +using System.Threading.Tasks; +using Shouldly; using Volo.Abp.Testing; using Xunit; @@ -19,10 +20,11 @@ namespace Volo.Abp.Ldap } [Fact(Skip = "Required Ldap environment")] - public void Authenticate() + public async Task AuthenticateAsync() { - _ldapManager.Authenticate("cn=abp,dc=abp,dc=io", "123qwe").ShouldBe(true); - _ldapManager.Authenticate("NoExists", "123qwe").ShouldBe(false); + (await _ldapManager.AuthenticateAsync("cn=abp,dc=abp,dc=io", "123qwe")).ShouldBe(true); + (await _ldapManager.AuthenticateAsync("cn=abp,dc=abp,dc=io", "123123")).ShouldBe(false); + (await _ldapManager.AuthenticateAsync("NoExists", "123qwe")).ShouldBe(false); } } } From 9c357f296b9810c72d8896c714957cc830f9edbe Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 30 Nov 2020 10:58:46 +0800 Subject: [PATCH 04/16] Add ldap changes to Abp-4_0.md --- docs/en/Migration-Guides/Abp-4_0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/Migration-Guides/Abp-4_0.md b/docs/en/Migration-Guides/Abp-4_0.md index 6c5540df9e..b48e441332 100644 --- a/docs/en/Migration-Guides/Abp-4_0.md +++ b/docs/en/Migration-Guides/Abp-4_0.md @@ -253,6 +253,10 @@ public class MyService : ITransientDependency Pre-built modules already handles this. However, if you have used `IdentityOptions` directly in your code, you also need to follow this new pattern. Please make sure that the injected `IOptions` service and the service consuming it are in the same scope of dependency injection container. +### LDAP module full async + +In order to solve the problem of async over sync, `ILdapManager` uses async method instead of sync. And use [`ldap4net`](https://github.com/flamencist/ldap4net) to replace [`Novell.Directory.Ldap.NETStandard`](https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard) package. + ## ASP.NET Core MVC / Razor Pages UI See the [ASP.NET Core MVC / Razor Pages UI Migration Guide](Abp-4_0-MVC-Razor-Pages.md). From 090cb6befcc7e920328674be138ab39f1c835c8d Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 27 Nov 2020 17:08:04 +0300 Subject: [PATCH 05/16] Update Docs.md --- docs/en/Modules/Docs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index e788a4c0f8..5780b4b827 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -446,7 +446,7 @@ As an example you can see ABP Framework documentation: #### Conditional sections feature (Using Scriban) -Docs module uses [Scriban]( ) for conditionally show or hide some parts of a document. In order to use that feature, you have to create a JSON file as **Parameter document** per every language. It will contain all the key-values, as well as their display names. +Docs module uses [Scriban](https://github.com/lunet-io/scriban/tree/master/doc) for conditionally show or hide some parts of a document. In order to use that feature, you have to create a JSON file as **Parameter document** per every language. It will contain all the key-values, as well as their display names. For example, [en/docs-params.json](https://github.com/abpio/abp-commercial-docs/blob/master/en/docs-params.json): @@ -537,7 +537,7 @@ Also, **Document_Language_Code** and **Document_Version** keys are pre-defined i ------ -**IMPORTANT NOTICE**: Scriban uses "{{" and "}}" for syntax. Therefore, you must use escape blocks if you are going to use those in your document (an Angular document, for example). See [Scriban docs]( ) for more information. +**IMPORTANT NOTICE**: Scriban uses "{{" and "}}" for syntax. Therefore, you must use escape blocks if you are going to use those in your document (an Angular document, for example). See [Scriban docs](https://github.com/lunet-io/scriban/blob/master/doc/language.md#13-escape-block) for more information. ### 8- Creating the Navigation Document From 097dee39076d7949bcc502971e9a3444109088d5 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 27 Nov 2020 17:34:51 +0300 Subject: [PATCH 06/16] Update Data-Tables.md --- docs/en/UI/AspNetCore/Data-Tables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/AspNetCore/Data-Tables.md b/docs/en/UI/AspNetCore/Data-Tables.md index 79fd6a3be1..a9dbf1eecf 100644 --- a/docs/en/UI/AspNetCore/Data-Tables.md +++ b/docs/en/UI/AspNetCore/Data-Tables.md @@ -101,7 +101,7 @@ Here, the all configuration options; DataTables.Net has its own expected data format while getting results of an AJAX call to the server to get the table data. They are especially related how paging and sorting parameters are sent and received. ABP Framework also offers its own conventions for the client-server [AJAX](JavaScript-API/Ajax.md) communication. -The `abp.libs.datatables.createAjax` method (used in the example above) adapts request and response data format and perfectly works with the [Dynamic JavaScript Client Proxy](Dynamic-JavaScript-Client-Proxies.md) system. +The `abp.libs.datatables.createAjax` method (used in the example above) adapts request and response data format and perfectly works with the [Dynamic JavaScript Client Proxy](Dynamic-JavaScript-Proxies.md) system. This works automatically, so most of the times you don't need to know how it works. See the [DTO document](../../Data-Transfer-Objects.md) if you want to learn more about `IPagedAndSortedResultRequest`, `IPagedResult` and other standard interfaces and base DTO classes those are used in client to server communication. From bd3149b0d2b1da337fe7bbe3554935626c4f86dd Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 27 Nov 2020 17:39:04 +0300 Subject: [PATCH 07/16] Update Navigation-Menu.md --- docs/en/UI/AspNetCore/Navigation-Menu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/AspNetCore/Navigation-Menu.md b/docs/en/UI/AspNetCore/Navigation-Menu.md index 762d6a4b0b..7a8fe31e3e 100644 --- a/docs/en/UI/AspNetCore/Navigation-Menu.md +++ b/docs/en/UI/AspNetCore/Navigation-Menu.md @@ -109,7 +109,7 @@ There are more options of a menu item (the constructor of the `ApplicationMenuIt As seen above, a menu contributor contributes to the menu dynamically. So, you can perform any custom logic or get menu items from any source. -One use case is the [authorization](Authorization.md). You typically want to add menu items by checking a permission. +One use case is the [authorization](../../Authorization.md). You typically want to add menu items by checking a permission. **Example: Check if the current user has a permission** From a6d15b16af687097eddc639a44f6d4abfa91df3b Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 27 Nov 2020 17:39:07 +0300 Subject: [PATCH 08/16] Update Application.md --- docs/en/Startup-Templates/Application.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Startup-Templates/Application.md b/docs/en/Startup-Templates/Application.md index 8cccf32382..81f0170e59 100644 --- a/docs/en/Startup-Templates/Application.md +++ b/docs/en/Startup-Templates/Application.md @@ -97,7 +97,7 @@ A `BookType` enum and a `BookConsts` class (which may have some constant fields #### .Domain Project -This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value types](../Value-Types.md), [repository interfaces](../Repositories.md) and other domain objects. +This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value objects](../Value-Objects.md), [repository interfaces](../Repositories.md) and other domain objects. A `Book` entity, a `BookManager` domain service and an `IBookRepository` interface are good candidates for this project. From 3a5c7b6030415124af8fb08be58f37896ab30597 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:29:56 +0300 Subject: [PATCH 09/16] Update Getting-Started-React-Native.md --- docs/en/Getting-Started-React-Native.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Getting-Started-React-Native.md b/docs/en/Getting-Started-React-Native.md index a06257fec9..08faac3608 100644 --- a/docs/en/Getting-Started-React-Native.md +++ b/docs/en/Getting-Started-React-Native.md @@ -27,13 +27,13 @@ You have multiple options to initiate a new React Native project that works with ### 1. Using ABP CLI -ABP CLI is probably the most convenient and flexible way to initiate an ABP solution with a React Native application. Simply [install the ABP CLI](../../CLI.md) and run the following command in your terminal: +ABP CLI is probably the most convenient and flexible way to initiate an ABP solution with a React Native application. Simply [install the ABP CLI](CLI.md) and run the following command in your terminal: ```shell abp new MyCompanyName.MyProjectName -csf -u -m react-native ``` -> To see further options in the CLI, please visit the [CLI manual](../../CLI.md). +> To see further options in the CLI, please visit the [CLI manual](CLI.md). This command will prepare a solution with an **Angular** or an **MVC** (depends on your choice), a **.NET Core**, and a **React Native** project in it. From d7270a51110d4414969dbc1b01cab0fc0d9b4adb Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:31:54 +0300 Subject: [PATCH 10/16] Update Authorization.md --- docs/en/Authorization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md index 158466d153..bceca3548f 100644 --- a/docs/en/Authorization.md +++ b/docs/en/Authorization.md @@ -406,5 +406,5 @@ This is already done for the startup template integration tests. ## See Also * [Permission Management Module](Modules/Permission-Management.md) -* [ASP.NET Core MVC / Razor Pages JavaScript Auth API](API/JavaScript-API/Auth.md) +* [ASP.NET Core MVC / Razor Pages JavaScript Auth API](UI/AspNetCore/JavaScript-API/Auth.md) * [Permission Management in Angular UI](UI/Angular/Permission-Management.md) From 83b41be6a981301ed445e70987eb0eeb4a609e02 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:33:38 +0300 Subject: [PATCH 11/16] Update AspNet-Boilerplate-Migration-Guide.md --- docs/en/AspNet-Boilerplate-Migration-Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/AspNet-Boilerplate-Migration-Guide.md b/docs/en/AspNet-Boilerplate-Migration-Guide.md index c7cc8a9e53..f4c2ec712b 100644 --- a/docs/en/AspNet-Boilerplate-Migration-Guide.md +++ b/docs/en/AspNet-Boilerplate-Migration-Guide.md @@ -438,7 +438,7 @@ ABP Framework uses and extends ASP.NET Core's [distributed caching abstraction]( ### Logging -ASP.NET Boilerplate uses Castle Windsor's [logging facility](http://docs.castleproject.org/Windsor.Logging-Facility.ashx) as an abstraction and supports multiple logging providers including Log4Net (the default one comes with the startup projects) and Serilog. You typically property-inject the logger: +ASP.NET Boilerplate uses Castle Windsor's [logging facility](https://github.com/castleproject/Windsor/blob/master/docs/logging-facility.md) as an abstraction and supports multiple logging providers including Log4Net (the default one comes with the startup projects) and Serilog. You typically property-inject the logger: ````csharp using Castle.Core.Logging; //1: Import Logging namespace From 6ce052b700268f356e16bdd5b5dda730e897e88a Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:36:37 +0300 Subject: [PATCH 12/16] Update CSRF-Anti-Forgery.md --- docs/en/CSRF-Anti-Forgery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/CSRF-Anti-Forgery.md b/docs/en/CSRF-Anti-Forgery.md index 33b856f563..720edc5924 100644 --- a/docs/en/CSRF-Anti-Forgery.md +++ b/docs/en/CSRF-Anti-Forgery.md @@ -25,7 +25,7 @@ ABP Framework provides `[AbpValidateAntiForgeryToken]` and `[AbpAutoValidateAnti ABP Framework also automates the following infrastructure; -* Server side sets a **special cookie**, named `XSRF-TOKEN` by default, that is used make the antiforgery token value available to the browser. This is **done automatically** (by the [application configuration](Application-Configuration.md) endpoint). Nothing to do in the client side. +* Server side sets a **special cookie**, named `XSRF-TOKEN` by default, that is used make the antiforgery token value available to the browser. This is **done automatically** (by the [application configuration](API/Application-Configuration.md) endpoint). Nothing to do in the client side. * In the client side, it reads the token from the cookie and sends it in the **HTTP header** (named `RequestVerificationToken` by default). This is implemented for all the supported UI types. * Server side validates the antiforgery token **only for same and cross site requests** made by the browser. It bypasses the validation for non-browser clients. From 9ae680db6e8785275b6552c4fbce9717da203669 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:39:54 +0300 Subject: [PATCH 13/16] Update Index.md --- docs/en/Contribution/Index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Contribution/Index.md b/docs/en/Contribution/Index.md index 83ec0bf05d..d245ccabcf 100644 --- a/docs/en/Contribution/Index.md +++ b/docs/en/Contribution/Index.md @@ -26,7 +26,7 @@ If you have a feature idea for the framework or modules, [create an issue](https ## Document Translation -You may want to translate the complete [documentation](https://abp.io/documents/) (including this one) to your mother language. If so, follow these steps: +You may want to translate the complete [documentation](https://docs.abp.io) (including this one) to your mother language. If so, follow these steps: * Clone the [ABP repository](https://github.com/abpframework/abp/) from Github. * To add a new language, create a new folder inside the [docs](https://github.com/abpframework/abp/tree/master/docs) folder. Folder names can be "en", "es", "fr", "tr" and so on based on the language (see [all culture codes](https://msdn.microsoft.com/en-us/library/hh441729.aspx)). From 6d78acf3461a41b32e561b9487e308700b0d3bb5 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Mon, 30 Nov 2020 09:39:56 +0300 Subject: [PATCH 14/16] Update Index.md --- docs/en/UI/AspNetCore/Tag-Helpers/Index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Index.md b/docs/en/UI/AspNetCore/Tag-Helpers/Index.md index f85edb5142..5b16d9ccdc 100644 --- a/docs/en/UI/AspNetCore/Tag-Helpers/Index.md +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Index.md @@ -16,7 +16,7 @@ Here, the list of components those are wrapped by the ABP Framework: * [Badges](Badges.md) * [Blockquote](Blockquote.md) * [Borders](Borders.md) -* [Breadcrumb](Breadcrumb.md) +* [Breadcrumb](Breadcrumbs.md) * [Buttons](Buttons.md) * [Cards](Cards.md) * [Carousel](Carousel.md) From 38af8956d1e32e90c10dd1efd27c0ade68725260 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 30 Nov 2020 15:40:28 +0800 Subject: [PATCH 15/16] Add Dynamic external login provider system. --- docs/en/Migration-Guides/Abp-4_0.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/Abp-4_0.md b/docs/en/Migration-Guides/Abp-4_0.md index b48e441332..5ec42f092d 100644 --- a/docs/en/Migration-Guides/Abp-4_0.md +++ b/docs/en/Migration-Guides/Abp-4_0.md @@ -244,7 +244,7 @@ public class MyService : ITransientDependency public async Task DoItAsync() { await _options.SetAsync(); - + var requiredLength = _options.Value.Password.RequiredLength; } } @@ -257,6 +257,16 @@ Please make sure that the injected `IOptions` service and the s In order to solve the problem of async over sync, `ILdapManager` uses async method instead of sync. And use [`ldap4net`](https://github.com/flamencist/ldap4net) to replace [`Novell.Directory.Ldap.NETStandard`](https://github.com/dsbenghe/Novell.Directory.Ldap.NETStandard) package. +### Dynamic external login provider system + +You need to change the `WithDynamicOptions` method and pass the `Handler` class of the external login provider. +Use the `goto definition` function in Visual Studio or Rider to check `Hanler` in the extension method like `AddGoogle`. + +```csharp +- WithDynamicOptions() ++ WithDynamicOptions() +```` + ## ASP.NET Core MVC / Razor Pages UI See the [ASP.NET Core MVC / Razor Pages UI Migration Guide](Abp-4_0-MVC-Razor-Pages.md). From 863203e89d305e6e8c93d2fd813c34631ce71a61 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 30 Nov 2020 15:41:50 +0800 Subject: [PATCH 16/16] Update Abp-4_0.md --- docs/en/Migration-Guides/Abp-4_0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Migration-Guides/Abp-4_0.md b/docs/en/Migration-Guides/Abp-4_0.md index 5ec42f092d..9e1bd4e816 100644 --- a/docs/en/Migration-Guides/Abp-4_0.md +++ b/docs/en/Migration-Guides/Abp-4_0.md @@ -260,7 +260,7 @@ In order to solve the problem of async over sync, `ILdapManager` uses async meth ### Dynamic external login provider system You need to change the `WithDynamicOptions` method and pass the `Handler` class of the external login provider. -Use the `goto definition` function in Visual Studio or Rider to check `Hanler` in the extension method like `AddGoogle`. +Use the `goto definition` function in Visual Studio or Rider to check `Handler` in the extension method like `AddGoogle`. ```csharp - WithDynamicOptions()