From 0ae62dcfe98dd73dcc476d18b30bdf2b19579853 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 14:55:58 +0800 Subject: [PATCH 01/10] Add CanObtainUserInfoWithoutPassword to IExternalLoginProvider --- .../Identity/AspNetCore/AbpSignInManager.cs | 14 +++++++-- .../Abp/Identity/ExternalLoginProviderBase.cs | 29 +++++++++++++++---- .../Abp/Identity/IExternalLoginProvider.cs | 8 +++-- .../AspNetCore/FakeExternalLoginProvider.cs | 5 ++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs index 313be4ae3f..946435e87c 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs @@ -49,11 +49,21 @@ public class AbpSignInManager : SignInManager var user = await UserManager.FindByNameAsync(userName); if (user == null) { - user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name); + user = externalLoginProvider.CanObtainUserInfoWithoutPassword + ? await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name) + : await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); } else { - await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + if (externalLoginProvider.CanObtainUserInfoWithoutPassword) + { + await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + } + else + { + await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); + } + } return await SignInOrTwoFactorAsync(user, isPersistent); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs index cfefad2a95..ba85576ace 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs @@ -16,6 +16,8 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider protected IdentityUserManager UserManager { get; } protected IIdentityUserRepository IdentityUserRepository { get; } protected IOptions IdentityOptions { get; } + + public bool CanObtainUserInfoWithoutPassword { get; set; } protected ExternalLoginProviderBase( IGuidGenerator guidGenerator, @@ -29,19 +31,21 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider UserManager = userManager; IdentityUserRepository = identityUserRepository; IdentityOptions = identityOptions; + CanObtainUserInfoWithoutPassword = true; } public abstract Task TryAuthenticateAsync(string userName, string plainPassword); - + public abstract Task IsEnabledAsync(); - public virtual async Task CreateUserAsync(string userName, string providerName) + public virtual async Task CreateUserAsync(string userName, string providerName, string plainPassword = null) { await IdentityOptions.SetAsync(); - var externalUser = await GetUserInfoAsync(userName); - NormalizeExternalLoginUserInfo(externalUser, userName); + var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(userName) : await GetUserInfoAsync(userName, plainPassword); + NormalizeExternalLoginUserInfo(externalUser, userName); + var user = new IdentityUser( GuidGenerator.Create(), userName, @@ -78,11 +82,17 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider return user; } - public virtual async Task UpdateUserAsync(IdentityUser user, string providerName) + public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null) { await IdentityOptions.SetAsync(); - var externalUser = await GetUserInfoAsync(user); + if (!CanObtainUserInfoWithoutPassword) + { + Check.NotNullOrWhiteSpace(plainPassword, nameof(plainPassword)); + } + + var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(user) : await GetUserInfoAsync(user, plainPassword); + NormalizeExternalLoginUserInfo(externalUser, user.UserName); if (!externalUser.Name.IsNullOrWhiteSpace()) @@ -147,10 +157,17 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider protected abstract Task GetUserInfoAsync(string userName); + protected abstract Task GetUserInfoAsync(string userName, string plainPassword); + protected virtual Task GetUserInfoAsync(IdentityUser user) { return GetUserInfoAsync(user.UserName); } + + protected virtual Task GetUserInfoAsync(IdentityUser user, string plainPassword) + { + return GetUserInfoAsync(user.UserName, plainPassword); + } private static void NormalizeExternalLoginUserInfo( ExternalLoginUserInfo externalUser, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs index 52d3895d13..7621c54de6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs @@ -4,6 +4,8 @@ namespace Volo.Abp.Identity; public interface IExternalLoginProvider { + bool CanObtainUserInfoWithoutPassword { get; set; } + /// /// Used to try authenticate a user by this source. /// @@ -18,8 +20,9 @@ public interface IExternalLoginProvider /// /// User name /// The name of this provider + /// Optional, plain password of the user /// Newly created user - Task CreateUserAsync(string userName, string providerName); + Task CreateUserAsync(string userName, string providerName, string plainPassword = null); /// /// This method is called after an existing user is authenticated by this source. @@ -27,7 +30,8 @@ public interface IExternalLoginProvider /// /// The name of this provider /// The user that can be updated - Task UpdateUserAsync(IdentityUser user, string providerName); + /// Optional, plain password of the user + Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null); /// /// Return a value indicating whether this source is enabled. diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs index fbfc0e2ef6..038e8cde0c 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs @@ -60,4 +60,9 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe } ); } + + protected override Task GetUserInfoAsync(string userName, string plainPassword) + { + return GetUserInfoAsync(userName); + } } From 7486582023e7835313135e81e65ad62730b7ee2a Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 15:39:01 +0800 Subject: [PATCH 02/10] Add IExternalLoginProviderWithPassword --- .../Identity/AspNetCore/AbpSignInManager.cs | 20 ++++++--- .../Abp/Identity/ExternalLoginProviderBase.cs | 45 +++++++++++++------ .../Abp/Identity/IExternalLoginProvider.cs | 8 ++-- .../IExternalLoginProviderWithPassword.cs | 26 +++++++++++ .../AspNetCore/FakeExternalLoginProvider.cs | 5 +++ 5 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs index 946435e87c..49959d930d 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs @@ -49,21 +49,27 @@ public class AbpSignInManager : SignInManager var user = await UserManager.FindByNameAsync(userName); if (user == null) { - user = externalLoginProvider.CanObtainUserInfoWithoutPassword - ? await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name) - : await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); + if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() && + externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) + { + user = await externalLoginProviderWithPassword.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); + } + else + { + user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name); + } } else { - if (externalLoginProvider.CanObtainUserInfoWithoutPassword) + if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() && + externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) { - await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + await externalLoginProviderWithPassword.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); } else { - await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); + await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); } - } return await SignInOrTwoFactorAsync(user, isPersistent); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs index ba85576ace..a19b0fb7c8 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs @@ -9,16 +9,13 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Identity; -public abstract class ExternalLoginProviderBase : IExternalLoginProvider +public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExternalLoginProviderWithPassword { protected IGuidGenerator GuidGenerator { get; } protected ICurrentTenant CurrentTenant { get; } protected IdentityUserManager UserManager { get; } protected IIdentityUserRepository IdentityUserRepository { get; } protected IOptions IdentityOptions { get; } - - public bool CanObtainUserInfoWithoutPassword { get; set; } - protected ExternalLoginProviderBase( IGuidGenerator guidGenerator, ICurrentTenant currentTenant, @@ -31,19 +28,32 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider UserManager = userManager; IdentityUserRepository = identityUserRepository; IdentityOptions = identityOptions; - CanObtainUserInfoWithoutPassword = true; } public abstract Task TryAuthenticateAsync(string userName, string plainPassword); public abstract Task IsEnabledAsync(); - public virtual async Task CreateUserAsync(string userName, string providerName, string plainPassword = null) + public virtual async Task CreateUserAsync(string userName, string providerName) { await IdentityOptions.SetAsync(); - var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(userName) : await GetUserInfoAsync(userName, plainPassword); + var externalUser = await GetUserInfoAsync(userName); + + return await CreateUserAsync(externalUser, userName, providerName); + } + public virtual async Task CreateUserAsync(string userName, string providerName, string plainPassword) + { + await IdentityOptions.SetAsync(); + + var externalUser = await GetUserInfoAsync(userName, plainPassword); + + return await CreateUserAsync(externalUser, userName, providerName); + } + + protected virtual async Task CreateUserAsync(ExternalLoginUserInfo externalUser, string userName, string providerName) + { NormalizeExternalLoginUserInfo(externalUser, userName); var user = new IdentityUser( @@ -82,17 +92,26 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider return user; } - public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null) + public virtual async Task UpdateUserAsync(IdentityUser user, string providerName) { await IdentityOptions.SetAsync(); + + var externalUser = await GetUserInfoAsync(user); - if (!CanObtainUserInfoWithoutPassword) - { - Check.NotNullOrWhiteSpace(plainPassword, nameof(plainPassword)); - } + await UpdateUserAsync(user, externalUser, providerName); + } + + public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword) + { + await IdentityOptions.SetAsync(); - var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(user) : await GetUserInfoAsync(user, plainPassword); + var externalUser = await GetUserInfoAsync(user, plainPassword); + await UpdateUserAsync(user, externalUser, providerName); + } + + protected virtual async Task UpdateUserAsync(IdentityUser user, ExternalLoginUserInfo externalUser ,string providerName) + { NormalizeExternalLoginUserInfo(externalUser, user.UserName); if (!externalUser.Name.IsNullOrWhiteSpace()) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs index 7621c54de6..2b9a267369 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs @@ -4,7 +4,7 @@ namespace Volo.Abp.Identity; public interface IExternalLoginProvider { - bool CanObtainUserInfoWithoutPassword { get; set; } + bool CanObtainUserInfoWithoutPassword(); /// /// Used to try authenticate a user by this source. @@ -20,9 +20,8 @@ public interface IExternalLoginProvider /// /// User name /// The name of this provider - /// Optional, plain password of the user /// Newly created user - Task CreateUserAsync(string userName, string providerName, string plainPassword = null); + Task CreateUserAsync(string userName, string providerName); /// /// This method is called after an existing user is authenticated by this source. @@ -30,8 +29,7 @@ public interface IExternalLoginProvider /// /// The name of this provider /// The user that can be updated - /// Optional, plain password of the user - Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null); + Task UpdateUserAsync(IdentityUser user, string providerName); /// /// Return a value indicating whether this source is enabled. diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs new file mode 100644 index 0000000000..ae91079a76 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.Identity +{ + public interface IExternalLoginProviderWithPassword + { + /// + /// This method is called when a user is authenticated by this source but the user does not exists yet. + /// So, the source should create the user and fill the properties. + /// + /// User name + /// The name of this provider + /// The plain password of the user + /// Newly created user + Task CreateUserAsync(string userName, string providerName, string plainPassword); + + /// + /// This method is called after an existing user is authenticated by this source. + /// It can be used to update some properties of the user by the source. + /// + /// The name of this provider + /// The user that can be updated + /// The plain password of the user + Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword); + } +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs index 038e8cde0c..8cfb3df04d 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs @@ -28,6 +28,11 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe } + public override bool CanObtainUserInfoWithoutPassword() + { + return true; + } + public override Task TryAuthenticateAsync(string userName, string plainPassword) { return Task.FromResult( From cf0bc4bab702a55b7e706778f9821749bfd6c0a5 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 15:41:07 +0800 Subject: [PATCH 03/10] Update ExternalLoginProviderBase --- .../Volo/Abp/Identity/ExternalLoginProviderBase.cs | 5 +++++ .../Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs index a19b0fb7c8..ce1680f5ea 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs @@ -30,6 +30,11 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExter IdentityOptions = identityOptions; } + public virtual bool CanObtainUserInfoWithoutPassword() + { + return true; + } + public abstract Task TryAuthenticateAsync(string userName, string plainPassword); public abstract Task IsEnabledAsync(); diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs index 8cfb3df04d..038e8cde0c 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs @@ -28,11 +28,6 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe } - public override bool CanObtainUserInfoWithoutPassword() - { - return true; - } - public override Task TryAuthenticateAsync(string userName, string plainPassword) { return Task.FromResult( From 4fbac360755b9ab68c3f1207316c4873255a72f1 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 16:18:11 +0800 Subject: [PATCH 04/10] Refactor --- .../Identity/AspNetCore/AbpSignInManager.cs | 6 +-- .../Abp/Identity/ExternalLoginProviderBase.cs | 34 +------------ .../ExternalLoginProviderWithPasswordBase.cs | 49 +++++++++++++++++++ .../Abp/Identity/IExternalLoginProvider.cs | 6 +-- .../AspNetCore/FakeExternalLoginProvider.cs | 5 -- 5 files changed, 55 insertions(+), 45 deletions(-) create mode 100644 modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs index 49959d930d..bbba6e63ec 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs @@ -49,8 +49,7 @@ public class AbpSignInManager : SignInManager var user = await UserManager.FindByNameAsync(userName); if (user == null) { - if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() && - externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) + if (externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) { user = await externalLoginProviderWithPassword.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); } @@ -61,8 +60,7 @@ public class AbpSignInManager : SignInManager } else { - if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() && - externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) + if (externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) { await externalLoginProviderWithPassword.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); } diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs index ce1680f5ea..240bf208d8 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs @@ -9,7 +9,7 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Identity; -public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExternalLoginProviderWithPassword +public abstract class ExternalLoginProviderBase : IExternalLoginProvider { protected IGuidGenerator GuidGenerator { get; } protected ICurrentTenant CurrentTenant { get; } @@ -30,11 +30,6 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExter IdentityOptions = identityOptions; } - public virtual bool CanObtainUserInfoWithoutPassword() - { - return true; - } - public abstract Task TryAuthenticateAsync(string userName, string plainPassword); public abstract Task IsEnabledAsync(); @@ -47,15 +42,6 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExter return await CreateUserAsync(externalUser, userName, providerName); } - - public virtual async Task CreateUserAsync(string userName, string providerName, string plainPassword) - { - await IdentityOptions.SetAsync(); - - var externalUser = await GetUserInfoAsync(userName, plainPassword); - - return await CreateUserAsync(externalUser, userName, providerName); - } protected virtual async Task CreateUserAsync(ExternalLoginUserInfo externalUser, string userName, string providerName) { @@ -105,16 +91,7 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExter await UpdateUserAsync(user, externalUser, providerName); } - - public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword) - { - await IdentityOptions.SetAsync(); - - var externalUser = await GetUserInfoAsync(user, plainPassword); - - await UpdateUserAsync(user, externalUser, providerName); - } - + protected virtual async Task UpdateUserAsync(IdentityUser user, ExternalLoginUserInfo externalUser ,string providerName) { NormalizeExternalLoginUserInfo(externalUser, user.UserName); @@ -181,17 +158,10 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExter protected abstract Task GetUserInfoAsync(string userName); - protected abstract Task GetUserInfoAsync(string userName, string plainPassword); - protected virtual Task GetUserInfoAsync(IdentityUser user) { return GetUserInfoAsync(user.UserName); } - - protected virtual Task GetUserInfoAsync(IdentityUser user, string plainPassword) - { - return GetUserInfoAsync(user.UserName, plainPassword); - } private static void NormalizeExternalLoginUserInfo( ExternalLoginUserInfo externalUser, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs new file mode 100644 index 0000000000..612091f8ea --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Options; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Identity; + +public abstract class ExternalLoginProviderWithPasswordBase : ExternalLoginProviderBase, IExternalLoginProviderWithPassword +{ + public ExternalLoginProviderWithPasswordBase( + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant, + IdentityUserManager userManager, + IIdentityUserRepository identityUserRepository, + IOptions identityOptions) : + base(guidGenerator, + currentTenant, + userManager, + identityUserRepository, + identityOptions) + { + } + + public async Task CreateUserAsync(string userName, string providerName, string plainPassword) + { + await IdentityOptions.SetAsync(); + + var externalUser = await GetUserInfoAsync(userName, plainPassword); + + return await CreateUserAsync(externalUser, userName, providerName); + } + + public async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword) + { + await IdentityOptions.SetAsync(); + + var externalUser = await GetUserInfoAsync(user, plainPassword); + + await UpdateUserAsync(user, externalUser, providerName); + } + + protected abstract Task GetUserInfoAsync(string userName, string plainPassword); + + protected virtual Task GetUserInfoAsync(IdentityUser user, string plainPassword) + { + return GetUserInfoAsync(user.UserName, plainPassword); + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs index 2b9a267369..774c5a41db 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs @@ -4,8 +4,6 @@ namespace Volo.Abp.Identity; public interface IExternalLoginProvider { - bool CanObtainUserInfoWithoutPassword(); - /// /// Used to try authenticate a user by this source. /// @@ -30,10 +28,10 @@ public interface IExternalLoginProvider /// The name of this provider /// The user that can be updated Task UpdateUserAsync(IdentityUser user, string providerName); - + /// /// Return a value indicating whether this source is enabled. /// /// Task IsEnabledAsync(); -} +} \ No newline at end of file diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs index 038e8cde0c..fbfc0e2ef6 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs @@ -60,9 +60,4 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe } ); } - - protected override Task GetUserInfoAsync(string userName, string plainPassword) - { - return GetUserInfoAsync(userName); - } } From 80ea30be0a63e634495314b12433a72201cf2d9b Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 18:30:14 +0800 Subject: [PATCH 05/10] Improved --- .../ExternalLoginProviderWithPasswordBase.cs | 27 ++++++++++++++++--- .../IExternalLoginProviderWithPassword.cs | 2 ++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs index 612091f8ea..e791004fd0 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Options; using Volo.Abp.Guids; @@ -8,22 +9,31 @@ namespace Volo.Abp.Identity; public abstract class ExternalLoginProviderWithPasswordBase : ExternalLoginProviderBase, IExternalLoginProviderWithPassword { + public bool CanObtainUserInfoWithoutPassword { get; } + public ExternalLoginProviderWithPasswordBase( IGuidGenerator guidGenerator, ICurrentTenant currentTenant, IdentityUserManager userManager, IIdentityUserRepository identityUserRepository, - IOptions identityOptions) : + IOptions identityOptions, + bool canObtainUserInfoWithoutPassword = false) : base(guidGenerator, currentTenant, userManager, identityUserRepository, identityOptions) { + CanObtainUserInfoWithoutPassword = canObtainUserInfoWithoutPassword; } public async Task CreateUserAsync(string userName, string providerName, string plainPassword) { + if (CanObtainUserInfoWithoutPassword) + { + return await CreateUserAsync(userName, providerName); + } + await IdentityOptions.SetAsync(); var externalUser = await GetUserInfoAsync(userName, plainPassword); @@ -33,13 +43,24 @@ public abstract class ExternalLoginProviderWithPasswordBase : ExternalLoginProvi public async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword) { + if (CanObtainUserInfoWithoutPassword) + { + await UpdateUserAsync(user, providerName); + return; + } + await IdentityOptions.SetAsync(); var externalUser = await GetUserInfoAsync(user, plainPassword); await UpdateUserAsync(user, externalUser, providerName); } - + + protected override Task GetUserInfoAsync(string userName) + { + throw new NotImplementedException($"{nameof(GetUserInfoAsync)} is not implemented default. It should be overriden and implemented by the deriving class!"); + } + protected abstract Task GetUserInfoAsync(string userName, string plainPassword); protected virtual Task GetUserInfoAsync(IdentityUser user, string plainPassword) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs index ae91079a76..fa811c852e 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs @@ -4,6 +4,8 @@ namespace Volo.Abp.Identity { public interface IExternalLoginProviderWithPassword { + bool CanObtainUserInfoWithoutPassword { get; } + /// /// This method is called when a user is authenticated by this source but the user does not exists yet. /// So, the source should create the user and fill the properties. From 81a37772da078d8ce564dbcd13e4624bbf93b942 Mon Sep 17 00:00:00 2001 From: Roc Date: Sat, 28 May 2022 15:36:08 +0800 Subject: [PATCH 06/10] Update Default.cshtml --- .../ProfileManagementGroup/PersonalInfo/Default.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml index ec65f49834..ba695a8557 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Components/ProfileManagementGroup/PersonalInfo/Default.cshtml @@ -20,7 +20,7 @@

@L["PersonalSettings"]


- + From 853d82f5ac9deaca07df17d2173dc3195db5ba80 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 30 May 2022 10:01:39 +0300 Subject: [PATCH 07/10] Update NpmPackagesUpdater.cs --- .../Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs index 64517b1900..135c04feaf 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs @@ -314,13 +314,13 @@ public class NpmPackagesUpdater : ITransientDependency protected virtual void RunYarn(string fileDirectory) { Logger.LogInformation($"Running Yarn on {fileDirectory}"); - CmdHelper.RunCmd($"cd {fileDirectory} && yarn"); + CmdHelper.RunCmd($"yarn", fileDirectory); } protected virtual void RunNpmInstall(string fileDirectory) { Logger.LogInformation($"Running npm install on {fileDirectory}"); - CmdHelper.RunCmd($"cd {fileDirectory} && npm install"); + CmdHelper.RunCmd($"npm install", fileDirectory); } protected virtual List GetPackageVersionList(JProperty package) From d24a9ed3019bad1b53804f06b3a23b8cd1bcaa04 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Mon, 30 May 2022 10:45:44 +0300 Subject: [PATCH 08/10] Update InstallLibsService.cs --- .../Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs index 56fa776904..71cf789c9c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/LIbs/InstallLibsService.cs @@ -236,13 +236,13 @@ public class InstallLibsService : IInstallLibsService, ITransientDependency private void RunNpmInstall(string directory) { Logger.LogInformation($"Running npm install on {directory}"); - CmdHelper.RunCmd($"cd {directory} && npm install"); + CmdHelper.RunCmd($"npm install", directory); } private void RunYarn(string directory) { Logger.LogInformation($"Running Yarn on {directory}"); - CmdHelper.RunCmd($"cd {directory} && yarn"); + CmdHelper.RunCmd($"yarn", directory); } private bool IsNpmInstalled() From c409e0dd37204dc350fb7ee7577036d2a4f7724e Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Mon, 30 May 2022 14:25:34 +0300 Subject: [PATCH 09/10] Update en.json --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index f8d5de9688..cc190808c9 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -536,7 +536,7 @@ "Pricing_Page_Testimonial_3": "We love ABP. We don't have to write everything from scratch. We start from out-of-the-box features and just focus on what we really need to write. Also, ABP is well-architected and the code is high quality with fewer bugs. If we would have to write everything we needed on our own, we might have to spend years. Once more things we like is that the new version, or issue fixing, or improvement come out very soon every other week. We don't wait too long.", "Pricing_Page_Testimonial_4": "ABP Commercial is a fantastic product would recommend. Commercial products to market for our customers in a single configurable platform. The jump start that the framework and tooling provide any team is worth every cent. ABP Commercial was the best fit for our needs.", "AbpBookDownloadArea_ClaimYourEBook": "Claim your Mastering ABP Framework E-Book", - "AddMemberModal_Warning_1": "If the username you are trying to add doesn't exist in the system, please ask your team member to register on {0} and share the username of his/her account with you.", + "AddMemberModal_Warning_1": "If the username you are trying to add doesn't exist in the system, please ask your team member to register on {0} and share the username of his/her account with you.", "MyOrganizations_Detail_WelcomeMessage": "Welcome to your organization, {0}", "MyOrganizations_Detail_OrganizationManagement": "Organization Management", "OrganizationDisplayName": "Organization Display Name", From 71a062b72dda237dacf6ddfbc773b556dd025dcb Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Mon, 30 May 2022 15:37:10 +0300 Subject: [PATCH 10/10] Update en.json --- .../Commercial/Localization/Resources/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index cc190808c9..4283e64533 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -562,7 +562,7 @@ "MyOrganizations_Detail_PaymentProviderInfo": "If you have purchased your license through {0} gateway, it sends the PDF invoice to your email address, see {0} invoicing.", "MyOrganizations_Detail_PayUInfo": "If you have purchased through the PayU gateway, click the \"Request Invoice\" button and fill in the billing information.", "MyOrganizations_Detail_ConclusionInfo": "Your invoice request will be concluded within {0} business days.", - "ExtendYourLicense": "Extend Your {0} License", + "ExtendYourLicense": "Extend your {0} license", "Continue": "Continue", "PurchaseLicense": "Purchase {0} license", "DownloadInvoiceModal_DownloadInvoice": "Download Invoice", @@ -628,7 +628,7 @@ "Tools_Page_Description": "ABP Commercial provides rapid application development tooling to increase developer productivity. ABP Suite allows you to create CRUD pages easily.", "DeveloperPrice": "Developer Price", "AdditionalDeveloperPaymentInfoSection_AdditionalDevelopers": "{0} developers", - "AdditionalDeveloperPaymentInfoSection_RemainingYear": "for {1} years", + "LicenseRemainingDays": "for {0} days", "ExtendPaymentInfoSection_Description": "By extending/renewing your license, you will continue to get premium support. You will also be able to get major updates for modules and themes. You will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.", "LicenseRenewalPrice": "License renewal price", "LicensePrice": "License Price",