diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index f8d5de9688..4283e64533 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", @@ -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", 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() 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) 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"]


- + 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..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,11 +49,25 @@ public class AbpSignInManager : SignInManager var user = await UserManager.FindByNameAsync(userName); if (user == null) { - user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name); + if (externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) + { + user = await externalLoginProviderWithPassword.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); + } + else + { + user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name); + } } else { - await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + if (externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword) + { + await externalLoginProviderWithPassword.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); + } + else + { + 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 cfefad2a95..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 @@ -16,7 +16,6 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider protected IdentityUserManager UserManager { get; } protected IIdentityUserRepository IdentityUserRepository { get; } protected IOptions IdentityOptions { get; } - protected ExternalLoginProviderBase( IGuidGenerator guidGenerator, ICurrentTenant currentTenant, @@ -32,7 +31,7 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider } public abstract Task TryAuthenticateAsync(string userName, string plainPassword); - + public abstract Task IsEnabledAsync(); public virtual async Task CreateUserAsync(string userName, string providerName) @@ -40,8 +39,14 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider await IdentityOptions.SetAsync(); var externalUser = await GetUserInfoAsync(userName); - NormalizeExternalLoginUserInfo(externalUser, userName); + return await CreateUserAsync(externalUser, userName, providerName); + } + + protected virtual async Task CreateUserAsync(ExternalLoginUserInfo externalUser, string userName, string providerName) + { + NormalizeExternalLoginUserInfo(externalUser, userName); + var user = new IdentityUser( GuidGenerator.Create(), userName, @@ -81,8 +86,14 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider public virtual async Task UpdateUserAsync(IdentityUser user, string providerName) { await IdentityOptions.SetAsync(); - + var externalUser = await GetUserInfoAsync(user); + + 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/ExternalLoginProviderWithPasswordBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs new file mode 100644 index 0000000000..e791004fd0 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderWithPasswordBase.cs @@ -0,0 +1,70 @@ +using System; +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 bool CanObtainUserInfoWithoutPassword { get; } + + public ExternalLoginProviderWithPasswordBase( + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant, + IdentityUserManager userManager, + IIdentityUserRepository identityUserRepository, + 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); + + return await CreateUserAsync(externalUser, userName, providerName); + } + + 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) + { + 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 52d3895d13..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 @@ -28,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/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..fa811c852e --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; + +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. + /// + /// 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