From 1d2375d5c075fc20387aa1abb8f9e7f44bcc46e7 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 28 Dec 2023 15:46:33 +0800 Subject: [PATCH] Handle the case when email contains invalid chars. --- .../Volo/Abp/Identity/IdentityUserManager.cs | 66 ++++++++++--------- .../Abp/Identity/IdentityUserManager_Tests.cs | 7 +- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs index 3e116aaed9..f2f347944c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs @@ -439,54 +439,58 @@ public class IdentityUserManager : UserManager, IDomainService public virtual async Task GetUserNameFromEmailAsync(string email) { + const int maxTryCount = 20; + var tryCount = 0; + var userName = email.Split('@')[0]; + if (!Options.User.AllowedUserNameCharacters.IsNullOrWhiteSpace() && !userName.All(Options.User.AllowedUserNameCharacters.Contains)) { - // The user name contains not allowed characters. We will use the email address as user name. - return email; + // The username contains not allowed characters. So, we are generating a random username. + do + { + var randomUserName = await GetRandomUserNameAsync(userName.Length); + if ( await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); } - - if (await ValidateUserNameAsync(userName)) + else if (await ValidateUserNameAsync(userName)) { + // The username is valid. return userName; } - - const int maxTryCount = 10; - var tryCount = 0; - - if (Options.User.AllowedUserNameCharacters.IsNullOrWhiteSpace() || "0123456789".All(Options.User.AllowedUserNameCharacters.Contains)) + else if (Options.User.AllowedUserNameCharacters.IsNullOrWhiteSpace() || "0123456789".All(Options.User.AllowedUserNameCharacters.Contains)) { - var randomUserName = userName; - var isUserNameValid = await ValidateUserNameAsync(randomUserName); - while (tryCount < maxTryCount) + // The AllowedUserNameCharacters includes numbers. So, we are generating 4 random numbers and appending to the username. + tryCount = 0; + do { - randomUserName = userName + RandomHelper.GetRandom(1000, 9999); - isUserNameValid = await ValidateUserNameAsync(randomUserName); - if (isUserNameValid) + var randomUserName = userName + RandomHelper.GetRandom(1000, 9999); + if ( await ValidateUserNameAsync(randomUserName)) { return randomUserName; } tryCount++; - } - if (isUserNameValid) - { - return randomUserName; - } + } while (tryCount < maxTryCount); } - - tryCount = 0; - while (tryCount < maxTryCount) + else { - var randomUserName = userName + await GetRandomUserNameAsync(4); - var isUserNameValid = await ValidateUserNameAsync(randomUserName); - if (isUserNameValid) + tryCount = 0; + do { - return randomUserName; - } - tryCount++; + // The AllowedUserNameCharacters does not include numbers. So, we are generating 4 random characters and appending to the username. + var randomUserName = userName + await GetRandomUserNameAsync(4); + if (await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); } - // We could not find a valid user name so we are returning the email address. - return email; + throw new AbpException($"Could not get a valid user name for the given email address: {email}, allowed characters: {Options.User.AllowedUserNameCharacters}, tried {maxTryCount} times."); } } diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs index c90a84e0e0..52f50fba1d 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs @@ -427,7 +427,12 @@ public class IdentityUserManager_Tests : AbpIdentityDomainTestBase public async Task GetUserNameFromEmailAsync() { _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz0123456789"; - var username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); + var username = await _identityUserManager.GetUserNameFromEmailAsync("Yƶnetici@abp.io"); + username.Length.ShouldBe("Yƶnetici".Length); //random username + username.All(c => "abcdefghijklmnopqrstuvwxyz0123456789".Contains(c)).ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz0123456789"; + username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); username.Length.ShouldBe(9); //admin and random 4 numbers username.ShouldContain("admin"); Regex.IsMatch(username, @"\d{4}$").ShouldBeTrue();