Browse Source

Merge pull request #6333 from abpframework/issue-6318

Remove AsyncHelper usage for the IdentityOptions
pull/6356/head
maliming 6 years ago
committed by GitHub
parent
commit
e2dbae1c03
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicOptionsManagerExtensions.cs
  2. 32
      framework/src/Volo.Abp.Core/Microsoft/Extensions/Options/OptionsAbpDynamicOptionsManagerExtensions.cs
  3. 24
      framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs
  4. 11
      modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs
  5. 15
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs
  6. 7
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
  7. 2
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs
  8. 11
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  9. 3
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs
  10. 7
      modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AccountAppService_Tests.cs
  11. 12
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
  12. 11
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/ProfileAppService.cs
  13. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs
  14. 29
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs
  15. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs
  16. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs
  17. 8
      modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs
  18. 44
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityOptions_Tests.cs
  19. 7
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs
  20. 6
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs

19
framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceCollectionDynamicOptionsManagerExtensions.cs

@ -0,0 +1,19 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Volo.Abp.Options;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionDynamicOptionsManagerExtensions
{
public static IServiceCollection AddAbpDynamicOptions<TOptions, TManager>(this IServiceCollection services)
where TOptions : class
where TManager : AbpDynamicOptionsManager<TOptions>
{
services.Replace(ServiceDescriptor.Scoped(typeof(IOptions<TOptions>), typeof(TManager)));
services.Replace(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<TOptions>), typeof(TManager)));
return services;
}
}
}

32
framework/src/Volo.Abp.Core/Microsoft/Extensions/Options/OptionsAbpDynamicOptionsManagerExtensions.cs

@ -0,0 +1,32 @@
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Options;
namespace Microsoft.Extensions.Options
{
public static class OptionsAbpDynamicOptionsManagerExtensions
{
public static Task SetAsync<T>(this IOptions<T> options)
where T : class
{
return options.ToDynamicOptions().SetAsync();
}
public static Task SetAsync<T>(this IOptions<T> options, string name)
where T : class
{
return options.ToDynamicOptions().SetAsync(name);
}
private static AbpDynamicOptionsManager<T> ToDynamicOptions<T>(this IOptions<T> options)
where T : class
{
if (options is AbpDynamicOptionsManager<T> dynamicOptionsManager)
{
return dynamicOptionsManager;
}
throw new AbpException($"Options must be derived from the {typeof(AbpDynamicOptionsManager<>).FullName}!");
}
}
}

24
framework/src/Volo.Abp.Core/Volo/Abp/Options/AbpDynamicOptionsManager.cs

@ -0,0 +1,24 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Volo.Abp.Options
{
public abstract class AbpDynamicOptionsManager<T> : OptionsManager<T>
where T : class
{
protected AbpDynamicOptionsManager(IOptionsFactory<T> factory)
: base(factory)
{
}
public Task SetAsync() => SetAsync(Microsoft.Extensions.Options.Options.DefaultName);
public virtual Task SetAsync(string name)
{
return OverrideOptionsAsync(base.Get(name));
}
protected abstract Task OverrideOptionsAsync(T options);
}
}

11
modules/account/src/Volo.Abp.Account.Application/Volo/Abp/Account/AccountAppService.cs

@ -1,5 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Emailing; using Volo.Abp.Account.Emailing;
using Volo.Abp.Account.Localization; using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Settings; using Volo.Abp.Account.Settings;
@ -15,17 +16,21 @@ namespace Volo.Abp.Account
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected IAccountEmailer AccountEmailer { get; } protected IAccountEmailer AccountEmailer { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; } protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountAppService( public AccountAppService(
IdentityUserManager userManager, IdentityUserManager userManager,
IIdentityRoleRepository roleRepository, IIdentityRoleRepository roleRepository,
IAccountEmailer accountEmailer, IAccountEmailer accountEmailer,
IdentitySecurityLogManager identitySecurityLogManager) IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
{ {
RoleRepository = roleRepository; RoleRepository = roleRepository;
AccountEmailer = accountEmailer; AccountEmailer = accountEmailer;
IdentitySecurityLogManager = identitySecurityLogManager; IdentitySecurityLogManager = identitySecurityLogManager;
UserManager = userManager; UserManager = userManager;
IdentityOptions = identityOptions;
LocalizationResource = typeof(AccountResource); LocalizationResource = typeof(AccountResource);
} }
@ -33,6 +38,8 @@ namespace Volo.Abp.Account
{ {
await CheckSelfRegistrationAsync(); await CheckSelfRegistrationAsync();
await IdentityOptions.SetAsync();
var user = new IdentityUser(GuidGenerator.Create(), input.UserName, input.EmailAddress, CurrentTenant.Id); var user = new IdentityUser(GuidGenerator.Create(), input.UserName, input.EmailAddress, CurrentTenant.Id);
(await UserManager.CreateAsync(user, input.Password)).CheckErrors(); (await UserManager.CreateAsync(user, input.Password)).CheckErrors();
@ -52,6 +59,8 @@ namespace Volo.Abp.Account
public virtual async Task ResetPasswordAsync(ResetPasswordDto input) public virtual async Task ResetPasswordAsync(ResetPasswordDto input)
{ {
await IdentityOptions.SetAsync();
var user = await UserManager.GetByIdAsync(input.UserId); var user = await UserManager.GetByIdAsync(input.UserId);
(await UserManager.ResetPasswordAsync(user, input.ResetToken, input.Password)).CheckErrors(); (await UserManager.ResetPasswordAsync(user, input.ResetToken, input.Password)).CheckErrors();

15
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs

@ -12,6 +12,7 @@ using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Principal; using System.Security.Principal;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.Account.Settings; using Volo.Abp.Account.Settings;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity; using Volo.Abp.Identity;
@ -33,17 +34,19 @@ namespace Volo.Abp.Account.Web.Pages.Account
IOptions<AbpAccountOptions> accountOptions, IOptions<AbpAccountOptions> accountOptions,
IIdentityServerInteractionService interaction, IIdentityServerInteractionService interaction,
IClientStore clientStore, IClientStore clientStore,
IEventService identityServerEvents) IEventService identityServerEvents,
IOptions<IdentityOptions> identityOptions)
:base( :base(
schemeProvider, schemeProvider,
accountOptions) accountOptions,
identityOptions)
{ {
Interaction = interaction; Interaction = interaction;
ClientStore = clientStore; ClientStore = clientStore;
IdentityServerEvents = identityServerEvents; IdentityServerEvents = identityServerEvents;
} }
public async override Task<IActionResult> OnGetAsync() public override async Task<IActionResult> OnGetAsync()
{ {
LoginInput = new LoginInputModel(); LoginInput = new LoginInputModel();
@ -98,7 +101,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
return Page(); return Page();
} }
public async override Task<IActionResult> OnPostAsync(string action) public override async Task<IActionResult> OnPostAsync(string action)
{ {
if (action == "Cancel") if (action == "Cancel")
{ {
@ -120,6 +123,8 @@ namespace Volo.Abp.Account.Web.Pages.Account
ValidateModel(); ValidateModel();
await IdentityOptions.SetAsync();
ExternalProviders = await GetExternalProviders(); ExternalProviders = await GetExternalProviders();
EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin); EnableLocalLogin = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin);
@ -173,7 +178,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
return RedirectSafely(ReturnUrl, ReturnUrlHash); return RedirectSafely(ReturnUrl, ReturnUrlHash);
} }
public async override Task<IActionResult> OnPostExternalLogin(string provider) public override async Task<IActionResult> OnPostExternalLogin(string provider)
{ {
if (AccountOptions.WindowsAuthenticationSchemeName == provider) if (AccountOptions.WindowsAuthenticationSchemeName == provider)
{ {

7
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs

@ -2,6 +2,7 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Localization; using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Settings; using Volo.Abp.Account.Settings;
using Volo.Abp.Account.Web.Areas.Account.Controllers.Models; using Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
@ -27,12 +28,14 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; } protected ISettingProvider SettingProvider { get; }
protected IdentitySecurityLogManager IdentitySecurityLogManager { get; } protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AccountController( public AccountController(
SignInManager<IdentityUser> signInManager, SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager, IdentityUserManager userManager,
ISettingProvider settingProvider, ISettingProvider settingProvider,
IdentitySecurityLogManager identitySecurityLogManager) IdentitySecurityLogManager identitySecurityLogManager,
IOptions<IdentityOptions> identityOptions)
{ {
LocalizationResource = typeof(AccountResource); LocalizationResource = typeof(AccountResource);
@ -40,6 +43,7 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
UserManager = userManager; UserManager = userManager;
SettingProvider = settingProvider; SettingProvider = settingProvider;
IdentitySecurityLogManager = identitySecurityLogManager; IdentitySecurityLogManager = identitySecurityLogManager;
IdentityOptions = identityOptions;
} }
[HttpPost] [HttpPost]
@ -104,6 +108,7 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword); return new AbpLoginResult(LoginResultType.InvalidUserNameOrPassword);
} }
await IdentityOptions.SetAsync();
return GetAbpLoginResult(await SignInManager.CheckPasswordSignInAsync(identityUser, login.Password, true)); return GetAbpLoginResult(await SignInManager.CheckPasswordSignInAsync(identityUser, login.Password, true));
} }

2
modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Localization; using Volo.Abp.Account.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.Identity; using Volo.Abp.Identity;
@ -16,6 +17,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
public SignInManager<IdentityUser> SignInManager { get; set; } public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; } public IdentityUserManager UserManager { get; set; }
public IdentitySecurityLogManager IdentitySecurityLogManager { get; set; } public IdentitySecurityLogManager IdentitySecurityLogManager { get; set; }
public IOptions<IdentityOptions> IdentityOptions { get; set; }
protected AccountPageModel() protected AccountPageModel()
{ {

11
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs

@ -51,14 +51,17 @@ namespace Volo.Abp.Account.Web.Pages.Account
protected IAuthenticationSchemeProvider SchemeProvider { get; } protected IAuthenticationSchemeProvider SchemeProvider { get; }
protected AbpAccountOptions AccountOptions { get; } protected AbpAccountOptions AccountOptions { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public bool ShowCancelButton { get; set; } public bool ShowCancelButton { get; set; }
public LoginModel( public LoginModel(
IAuthenticationSchemeProvider schemeProvider, IAuthenticationSchemeProvider schemeProvider,
IOptions<AbpAccountOptions> accountOptions) IOptions<AbpAccountOptions> accountOptions,
IOptions<IdentityOptions> identityOptions)
{ {
SchemeProvider = schemeProvider; SchemeProvider = schemeProvider;
IdentityOptions = identityOptions;
AccountOptions = accountOptions.Value; AccountOptions = accountOptions.Value;
} }
@ -91,6 +94,8 @@ namespace Volo.Abp.Account.Web.Pages.Account
await ReplaceEmailToUsernameOfInputIfNeeds(); await ReplaceEmailToUsernameOfInputIfNeeds();
await IdentityOptions.SetAsync();
var result = await SignInManager.PasswordSignInAsync( var result = await SignInManager.PasswordSignInAsync(
LoginInput.UserNameOrEmailAddress, LoginInput.UserNameOrEmailAddress,
LoginInput.Password, LoginInput.Password,
@ -181,6 +186,8 @@ namespace Volo.Abp.Account.Web.Pages.Account
return RedirectToPage("./Login"); return RedirectToPage("./Login");
} }
await IdentityOptions.SetAsync();
var loginInfo = await SignInManager.GetExternalLoginInfoAsync(); var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (loginInfo == null) if (loginInfo == null)
{ {
@ -254,6 +261,8 @@ namespace Volo.Abp.Account.Web.Pages.Account
protected virtual async Task<IdentityUser> CreateExternalUserAsync(ExternalLoginInfo info) protected virtual async Task<IdentityUser> CreateExternalUserAsync(ExternalLoginInfo info)
{ {
await IdentityOptions.SetAsync();
var emailAddress = info.Principal.FindFirstValue(AbpClaimTypes.Email); var emailAddress = info.Principal.FindFirstValue(AbpClaimTypes.Email);
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id); var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);

3
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Account.Settings; using Volo.Abp.Account.Settings;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Identity; using Volo.Abp.Identity;
@ -124,6 +125,8 @@ namespace Volo.Abp.Account.Web.Pages.Account
protected virtual async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress) protected virtual async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress)
{ {
await IdentityOptions.SetAsync();
var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id); var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
(await UserManager.CreateAsync(user)).CheckErrors(); (await UserManager.CreateAsync(user)).CheckErrors();

7
modules/account/test/Volo.Abp.Account.Application.Tests/Volo/Abp/Account/AccountAppService_Tests.cs

@ -1,5 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Shouldly; using Shouldly;
using Volo.Abp.Identity; using Volo.Abp.Identity;
using Xunit; using Xunit;
@ -12,18 +13,22 @@ namespace Volo.Abp.Account
private readonly IIdentityUserRepository _identityUserRepository; private readonly IIdentityUserRepository _identityUserRepository;
private readonly ILookupNormalizer _lookupNormalizer; private readonly ILookupNormalizer _lookupNormalizer;
private readonly IdentityUserManager _userManager; private readonly IdentityUserManager _userManager;
private readonly IOptions<IdentityOptions> _identityOptions;
public AccountAppService_Tests() public AccountAppService_Tests()
{ {
_accountAppService = GetRequiredService<IAccountAppService>(); _accountAppService = GetRequiredService<IAccountAppService>();
_identityUserRepository = GetRequiredService<IIdentityUserRepository>(); _identityUserRepository = GetRequiredService<IIdentityUserRepository>();
_lookupNormalizer = GetRequiredService<ILookupNormalizer>(); _lookupNormalizer = GetRequiredService<ILookupNormalizer>();
_userManager = GetRequiredService<IdentityUserManager>(); _userManager = GetRequiredService<IdentityUserManager>();
_identityOptions = GetRequiredService<IOptions<IdentityOptions>>();
} }
[Fact] [Fact]
public async Task RegisterAsync() public async Task RegisterAsync()
{ {
await _identityOptions.SetAsync();
var registerDto = new RegisterDto var registerDto = new RegisterDto
{ {
UserName = "bob.lee", UserName = "bob.lee",

12
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
@ -12,16 +13,19 @@ namespace Volo.Abp.Identity
{ {
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected IIdentityUserRepository UserRepository { get; } protected IIdentityUserRepository UserRepository { get; }
public IIdentityRoleRepository RoleRepository { get; } protected IIdentityRoleRepository RoleRepository { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public IdentityUserAppService( public IdentityUserAppService(
IdentityUserManager userManager, IdentityUserManager userManager,
IIdentityUserRepository userRepository, IIdentityUserRepository userRepository,
IIdentityRoleRepository roleRepository) IIdentityRoleRepository roleRepository,
IOptions<IdentityOptions> identityOptions)
{ {
UserManager = userManager; UserManager = userManager;
UserRepository = userRepository; UserRepository = userRepository;
RoleRepository = roleRepository; RoleRepository = roleRepository;
IdentityOptions = identityOptions;
} }
//TODO: [Authorize(IdentityPermissions.Users.Default)] should go the IdentityUserAppService class. //TODO: [Authorize(IdentityPermissions.Users.Default)] should go the IdentityUserAppService class.
@ -68,6 +72,8 @@ namespace Volo.Abp.Identity
[Authorize(IdentityPermissions.Users.Create)] [Authorize(IdentityPermissions.Users.Create)]
public virtual async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input) public virtual async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{ {
await IdentityOptions.SetAsync();
var user = new IdentityUser( var user = new IdentityUser(
GuidGenerator.Create(), GuidGenerator.Create(),
input.UserName, input.UserName,
@ -88,6 +94,8 @@ namespace Volo.Abp.Identity
[Authorize(IdentityPermissions.Users.Update)] [Authorize(IdentityPermissions.Users.Update)]
public virtual async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input) public virtual async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserUpdateDto input)
{ {
await IdentityOptions.SetAsync();
var user = await UserManager.GetByIdAsync(id); var user = await UserManager.GetByIdAsync(id);
user.ConcurrencyStamp = input.ConcurrencyStamp; user.ConcurrencyStamp = input.ConcurrencyStamp;

11
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/ProfileAppService.cs

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.Identity.Settings; using Volo.Abp.Identity.Settings;
using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectExtending;
using Volo.Abp.Settings; using Volo.Abp.Settings;
@ -13,10 +14,14 @@ namespace Volo.Abp.Identity
public class ProfileAppService : IdentityAppServiceBase, IProfileAppService public class ProfileAppService : IdentityAppServiceBase, IProfileAppService
{ {
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public ProfileAppService(IdentityUserManager userManager) public ProfileAppService(
IdentityUserManager userManager,
IOptions<IdentityOptions> identityOptions)
{ {
UserManager = userManager; UserManager = userManager;
IdentityOptions = identityOptions;
} }
public virtual async Task<ProfileDto> GetAsync() public virtual async Task<ProfileDto> GetAsync()
@ -28,6 +33,8 @@ namespace Volo.Abp.Identity
public virtual async Task<ProfileDto> UpdateAsync(UpdateProfileDto input) public virtual async Task<ProfileDto> UpdateAsync(UpdateProfileDto input)
{ {
await IdentityOptions.SetAsync();
var user = await UserManager.GetByIdAsync(CurrentUser.GetId()); var user = await UserManager.GetByIdAsync(CurrentUser.GetId());
if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled)) if (await SettingProvider.IsTrueAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled))
@ -56,6 +63,8 @@ namespace Volo.Abp.Identity
public virtual async Task ChangePasswordAsync(ChangePasswordInput input) public virtual async Task ChangePasswordAsync(ChangePasswordInput input)
{ {
await IdentityOptions.SetAsync();
var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId()); var currentUser = await UserManager.GetByIdAsync(CurrentUser.GetId());
if (currentUser.IsExternal) if (currentUser.IsExternal)

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityDomainModule.cs

@ -56,7 +56,7 @@ namespace Volo.Abp.Identity
options.ClaimsIdentity.RoleClaimType = AbpClaimTypes.Role; options.ClaimsIdentity.RoleClaimType = AbpClaimTypes.Role;
}); });
AddAbpIdentityOptionsFactory(context.Services); context.Services.AddAbpDynamicOptions<IdentityOptions, AbpIdentityOptionsManager>();
} }
public override void PostConfigureServices(ServiceConfigurationContext context) public override void PostConfigureServices(ServiceConfigurationContext context)
@ -88,11 +88,5 @@ namespace Volo.Abp.Identity
); );
}); });
} }
private static void AddAbpIdentityOptionsFactory(IServiceCollection services)
{
services.Replace(ServiceDescriptor.Transient<IOptionsFactory<IdentityOptions>, AbpIdentityOptionsFactory>());
services.Replace(ServiceDescriptor.Scoped<IOptions<IdentityOptions>, OptionsManager<IdentityOptions>>());
}
} }
} }

29
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsFactory.cs → modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityOptionsManager.cs

@ -1,43 +1,25 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Identity.Settings; using Volo.Abp.Identity.Settings;
using Volo.Abp.Options; using Volo.Abp.Options;
using Volo.Abp.Settings; using Volo.Abp.Settings;
using Volo.Abp.Threading;
namespace Volo.Abp.Identity namespace Volo.Abp.Identity
{ {
public class AbpIdentityOptionsFactory : AbpOptionsFactory<IdentityOptions> public class AbpIdentityOptionsManager : AbpDynamicOptionsManager<IdentityOptions>
{ {
protected ISettingProvider SettingProvider { get; } protected ISettingProvider SettingProvider { get; }
public AbpIdentityOptionsFactory( public AbpIdentityOptionsManager(IOptionsFactory<IdentityOptions> factory,
IEnumerable<IConfigureOptions<IdentityOptions>> setups,
IEnumerable<IPostConfigureOptions<IdentityOptions>> postConfigures,
ISettingProvider settingProvider) ISettingProvider settingProvider)
: base(setups, postConfigures) : base(factory)
{ {
SettingProvider = settingProvider; SettingProvider = settingProvider;
} }
public override IdentityOptions Create(string name) protected override async Task OverrideOptionsAsync(IdentityOptions options)
{
var options = base.Create(name);
OverrideOptions(options);
return options;
}
protected virtual void OverrideOptions(IdentityOptions options)
{
AsyncHelper.RunSync(()=>OverrideOptionsAsync(options));
}
protected virtual async Task OverrideOptionsAsync(IdentityOptions options)
{ {
options.Password.RequiredLength = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredLength, options.Password.RequiredLength); options.Password.RequiredLength = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredLength, options.Password.RequiredLength);
options.Password.RequiredUniqueChars = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredUniqueChars, options.Password.RequiredUniqueChars); options.Password.RequiredUniqueChars = await SettingProvider.GetAsync(IdentitySettingNames.Password.RequiredUniqueChars, options.Password.RequiredUniqueChars);
@ -52,7 +34,6 @@ namespace Volo.Abp.Identity
options.SignIn.RequireConfirmedEmail = await SettingProvider.GetAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail, options.SignIn.RequireConfirmedEmail); options.SignIn.RequireConfirmedEmail = await SettingProvider.GetAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail, options.SignIn.RequireConfirmedEmail);
options.SignIn.RequireConfirmedPhoneNumber = await SettingProvider.GetAsync(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, options.SignIn.RequireConfirmedPhoneNumber); options.SignIn.RequireConfirmedPhoneNumber = await SettingProvider.GetAsync(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, options.SignIn.RequireConfirmedPhoneNumber);
} }
} }
} }

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs

@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -14,23 +15,28 @@ namespace Volo.Abp.Identity
protected ICurrentTenant CurrentTenant { get; } protected ICurrentTenant CurrentTenant { get; }
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected IIdentityUserRepository IdentityUserRepository { get; } protected IIdentityUserRepository IdentityUserRepository { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
protected ExternalLoginProviderBase( protected ExternalLoginProviderBase(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IdentityUserManager userManager, IdentityUserManager userManager,
IIdentityUserRepository identityUserRepository) IIdentityUserRepository identityUserRepository,
IOptions<IdentityOptions> identityOptions)
{ {
GuidGenerator = guidGenerator; GuidGenerator = guidGenerator;
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
UserManager = userManager; UserManager = userManager;
IdentityUserRepository = identityUserRepository; IdentityUserRepository = identityUserRepository;
IdentityOptions = identityOptions;
} }
public abstract Task<bool> TryAuthenticateAsync(string userName, string plainPassword); public abstract Task<bool> TryAuthenticateAsync(string userName, string plainPassword);
public virtual async Task<IdentityUser> CreateUserAsync(string userName, string providerName) public virtual async Task<IdentityUser> CreateUserAsync(string userName, string providerName)
{ {
await IdentityOptions.SetAsync();
var externalUser = await GetUserInfoAsync(userName); var externalUser = await GetUserInfoAsync(userName);
NormalizeExternalLoginUserInfo(externalUser, userName); NormalizeExternalLoginUserInfo(externalUser, userName);

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityDataSeeder.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -17,6 +18,7 @@ namespace Volo.Abp.Identity
protected IdentityUserManager UserManager { get; } protected IdentityUserManager UserManager { get; }
protected IdentityRoleManager RoleManager { get; } protected IdentityRoleManager RoleManager { get; }
protected ICurrentTenant CurrentTenant { get; } protected ICurrentTenant CurrentTenant { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public IdentityDataSeeder( public IdentityDataSeeder(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
@ -25,7 +27,8 @@ namespace Volo.Abp.Identity
ILookupNormalizer lookupNormalizer, ILookupNormalizer lookupNormalizer,
IdentityUserManager userManager, IdentityUserManager userManager,
IdentityRoleManager roleManager, IdentityRoleManager roleManager,
ICurrentTenant currentTenant) ICurrentTenant currentTenant,
IOptions<IdentityOptions> identityOptions)
{ {
GuidGenerator = guidGenerator; GuidGenerator = guidGenerator;
RoleRepository = roleRepository; RoleRepository = roleRepository;
@ -34,6 +37,7 @@ namespace Volo.Abp.Identity
UserManager = userManager; UserManager = userManager;
RoleManager = roleManager; RoleManager = roleManager;
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
IdentityOptions = identityOptions;
} }
[UnitOfWork] [UnitOfWork]
@ -45,6 +49,8 @@ namespace Volo.Abp.Identity
Check.NotNullOrWhiteSpace(adminEmail, nameof(adminEmail)); Check.NotNullOrWhiteSpace(adminEmail, nameof(adminEmail));
Check.NotNullOrWhiteSpace(adminPassword, nameof(adminPassword)); Check.NotNullOrWhiteSpace(adminPassword, nameof(adminPassword));
await IdentityOptions.SetAsync();
var result = new IdentityDataSeedResult(); var result = new IdentityDataSeedResult();
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))

8
modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -14,12 +16,14 @@ namespace Volo.Abp.Identity.AspNetCore
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IdentityUserManager userManager, IdentityUserManager userManager,
IIdentityUserRepository identityUserRepository) IIdentityUserRepository identityUserRepository,
IOptions<IdentityOptions> identityOptions)
: base( : base(
guidGenerator, guidGenerator,
currentTenant, currentTenant,
userManager, userManager,
identityUserRepository) identityUserRepository,
identityOptions)
{ {
} }

44
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityOptions_Tests.cs

@ -23,28 +23,52 @@ namespace Volo.Abp.Identity
} }
[Fact] [Fact]
public void Should_Resolve_AbpIdentityOptionsFactory() public void Should_Resolve_AbpIdentityOptionsManager()
{ {
GetRequiredService<IOptionsFactory<IdentityOptions>>().ShouldBeOfType(typeof(AbpIdentityOptionsFactory)); GetRequiredService<IOptions<IdentityOptions>>().ShouldBeOfType(typeof(AbpIdentityOptionsManager));
} }
[Fact] [Fact]
public void Should_Get_Options_From_Custom_Settings_If_Available() public async Task Should_Get_Options_From_Custom_Settings_If_Available()
{ {
using (var scope1 = ServiceProvider.CreateScope()) using (var scope1 = ServiceProvider.CreateScope())
{ {
var options = scope1.ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>().Value; var options = scope1.ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>();
options.Password.RequiredLength.ShouldBe(6); //Default value
options.Password.RequiredUniqueChars.ShouldBe(1); //Default value //Can not get the values from the SettingProvider without options.SetAsync();
options.Value.Password.RequiredLength.ShouldBe(6); //Default value
options.Value.Password.RequiredUniqueChars.ShouldBe(1); //Default value
}
using (var scope2 = ServiceProvider.CreateScope())
{
var options = scope2.ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>();
var optionsValue = options.Value;
await options.SetAsync();
//Still the default values because SettingProvider has not been configured yet
optionsValue.Password.RequiredLength.ShouldBe(6); //Default value
optionsValue.Password.RequiredUniqueChars.ShouldBe(1); //Default value
} }
_settingProvider.GetOrNullAsync(IdentitySettingNames.Password.RequiredLength).Returns(Task.FromResult("42")); _settingProvider
.GetOrNullAsync(IdentitySettingNames.Password.RequiredLength)
.Returns(Task.FromResult("42"));
using (var scope2 = ServiceProvider.CreateScope()) using (var scope2 = ServiceProvider.CreateScope())
{ {
var options = scope2.ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>().Value; var options = scope2.ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>();
options.Password.RequiredLength.ShouldBe(42); //Setting value var optionsValue = options.Value;
options.Password.RequiredUniqueChars.ShouldBe(1); //Default value
await options.SetAsync();
//Get the value from SettingProvider
optionsValue.Password.RequiredLength.ShouldBe(42); //Setting value
optionsValue.Password.RequiredUniqueChars.ShouldBe(1); //Default value
} }
} }
} }

7
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Shouldly; using Shouldly;
using Volo.Abp.Uow; using Volo.Abp.Uow;
using Xunit; using Xunit;
@ -18,6 +19,7 @@ namespace Volo.Abp.Identity
private readonly ILookupNormalizer _lookupNormalizer; private readonly ILookupNormalizer _lookupNormalizer;
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IdentityTestData _testData; private readonly IdentityTestData _testData;
protected IOptions<IdentityOptions> _identityOptions { get; }
public IdentityUserManager_Tests() public IdentityUserManager_Tests()
{ {
@ -28,6 +30,7 @@ namespace Volo.Abp.Identity
_lookupNormalizer = GetRequiredService<ILookupNormalizer>(); _lookupNormalizer = GetRequiredService<ILookupNormalizer>();
_testData = GetRequiredService<IdentityTestData>(); _testData = GetRequiredService<IdentityTestData>();
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>(); _unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>();
_identityOptions = GetRequiredService<IOptions<IdentityOptions>>();
} }
[Fact] [Fact]
@ -120,6 +123,8 @@ namespace Volo.Abp.Identity
[Fact] [Fact]
public async Task AddDefaultRolesAsync_In_Same_Uow() public async Task AddDefaultRolesAsync_In_Same_Uow()
{ {
await _identityOptions.SetAsync();
await CreateRandomDefaultRoleAsync(); await CreateRandomDefaultRoleAsync();
using (var uow = _unitOfWorkManager.Begin()) using (var uow = _unitOfWorkManager.Begin())
@ -176,6 +181,8 @@ namespace Volo.Abp.Identity
[Fact] [Fact]
public async Task AddDefaultRolesAsync_In_Different_Uow() public async Task AddDefaultRolesAsync_In_Different_Uow()
{ {
await _identityOptions.SetAsync();
await CreateRandomDefaultRoleAsync(); await CreateRandomDefaultRoleAsync();
Guid userId; Guid userId;

6
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs

@ -33,6 +33,7 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
protected IStringLocalizer<AbpIdentityServerResource> Localizer { get; } protected IStringLocalizer<AbpIdentityServerResource> Localizer { get; }
protected IHybridServiceScopeFactory ServiceScopeFactory { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
protected AbpIdentityOptions AbpIdentityOptions { get; } protected AbpIdentityOptions AbpIdentityOptions { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public AbpResourceOwnerPasswordValidator( public AbpResourceOwnerPasswordValidator(
UserManager<IdentityUser> userManager, UserManager<IdentityUser> userManager,
@ -41,7 +42,8 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
ILogger<ResourceOwnerPasswordValidator<IdentityUser>> logger, ILogger<ResourceOwnerPasswordValidator<IdentityUser>> logger,
IStringLocalizer<AbpIdentityServerResource> localizer, IStringLocalizer<AbpIdentityServerResource> localizer,
IOptions<AbpIdentityOptions> abpIdentityOptions, IOptions<AbpIdentityOptions> abpIdentityOptions,
IHybridServiceScopeFactory serviceScopeFactory) IHybridServiceScopeFactory serviceScopeFactory,
IOptions<IdentityOptions> identityOptions)
{ {
UserManager = userManager; UserManager = userManager;
SignInManager = signInManager; SignInManager = signInManager;
@ -50,6 +52,7 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
Localizer = localizer; Localizer = localizer;
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
AbpIdentityOptions = abpIdentityOptions.Value; AbpIdentityOptions = abpIdentityOptions.Value;
IdentityOptions = identityOptions;
} }
/// <summary> /// <summary>
@ -123,6 +126,7 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
string errorDescription; string errorDescription;
if (user != null) if (user != null)
{ {
await IdentityOptions.SetAsync();
var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true); var result = await SignInManager.CheckPasswordSignInAsync(user, context.Password, true);
if (result.Succeeded) if (result.Succeeded)
{ {

Loading…
Cancel
Save