Browse Source

Refactor user validation logic in AbpIdentityUserValidator

pull/24456/head
maliming 8 months ago
parent
commit
4d5307f953
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 124
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs

124
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
@ -93,10 +92,13 @@ namespace Volo.Abp.Identity
{
var errors = new List<IdentityError>();
var defaultValidationResult = await BuiltInValidateAsync(manager, user);
if (!defaultValidationResult.Succeeded)
using (CurrentTenant.Change(user.TenantId))
{
return defaultValidationResult;
var defaultValidationResult = await DefaultUserValidator.ValidateAsync(manager, user);
if (!defaultValidationResult.Succeeded)
{
return defaultValidationResult;
}
}
await using var handle = await DistributedLock.TryAcquireAsync(nameof(AbpIdentityUserValidator), TimeSpan.FromMinutes(1));
@ -114,107 +116,55 @@ namespace Volo.Abp.Identity
{
owner = await manager.FindByIdAsync(user.Id.ToString());
}
var normalizedUserName = manager.NormalizeName(user.UserName);
var normalizedEmail = manager.NormalizeEmail(user.Email);
var users = await UserRepository.GetUsersByNormalizedUserNamesAsync([normalizedUserName!, normalizedEmail], true);
users.RemoveAll(x => x.Id == user.Id);
var users = (await UserRepository.GetUsersByNormalizedUserNamesAsync([normalizedUserName!, normalizedEmail!], true)).Where(x => x.Id != user.Id).ToList();
var usersByUserName = users.Where(x => x.NormalizedUserName == normalizedUserName).ToList();
if (owner != null)
{
users.RemoveAll(x => x.NormalizedUserName == user.NormalizedUserName || x.NormalizedEmail == user.NormalizedEmail);
usersByUserName.RemoveAll(x => x.NormalizedUserName == user.NormalizedUserName);
}
if (users.Any())
if (usersByUserName.Any())
{
var userNames = users.Select(u => u.UserName).ToList();
errors.Add(userNames.Contains(user.UserName) ? ErrorDescriber.InvalidUserName(user.UserName!) : ErrorDescriber.InvalidEmail(user.Email!));
errors.Add(ErrorDescriber.DuplicateUserName(user.UserName!));
}
users = await UserRepository.GetUsersByNormalizedEmailsAsync([normalizedUserName!, normalizedEmail], true);
users.RemoveAll(x => x.Id == user.Id);
var usersByEmail = users.Where(x => x.NormalizedUserName == normalizedEmail).ToList();
if (owner != null)
{
users.RemoveAll(x => x.NormalizedUserName == user.NormalizedUserName || x.NormalizedEmail == user.NormalizedEmail);
usersByEmail.RemoveAll(x => x.NormalizedEmail == user.NormalizedEmail);
}
if (users.Any())
if (usersByEmail.Any())
{
var emails = users.Select(u => u.Email).ToList();
errors.Add(emails.Contains(user.Email) ? ErrorDescriber.InvalidEmail(user.Email!) : ErrorDescriber.InvalidUserName(user.UserName!));
errors.Add(ErrorDescriber.InvalidEmail(user.Email!));
}
}
}
return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
public virtual async Task<IdentityResult> BuiltInValidateAsync(UserManager<IdentityUser> manager, IdentityUser user)
{
var errors = await ValidateUserName(manager, user);
if (manager.Options.User.RequireUniqueEmail)
{
errors.AddRange(await ValidateEmail(manager, user));
}
return errors?.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
users = await UserRepository.GetUsersByNormalizedEmailsAsync([normalizedEmail!, normalizedUserName!], true);
usersByEmail = users.Where(x => x.NormalizedEmail == normalizedEmail).ToList();
if (owner != null)
{
usersByEmail.RemoveAll(x => x.NormalizedEmail == user.NormalizedEmail);
}
if (usersByEmail.Any())
{
errors.Add(ErrorDescriber.DuplicateEmail(user.Email!));
}
private async Task<List<IdentityError>> ValidateUserName(UserManager<IdentityUser> manager, IdentityUser user)
{
var errors = new List<IdentityError>();
var userName = await manager.GetUserNameAsync(user);
if (string.IsNullOrWhiteSpace(userName))
{
errors.Add(ErrorDescriber.InvalidUserName(userName));
}
else if (!string.IsNullOrEmpty(manager.Options.User.AllowedUserNameCharacters) &&
userName.Any(c => !manager.Options.User.AllowedUserNameCharacters.Contains(c)))
{
errors.Add(ErrorDescriber.InvalidUserName(userName));
}
else
{
IdentityUser owner;
using (CurrentTenant.Change(user.TenantId))
{
owner = await manager.FindByNameAsync(userName);
}
if (owner != null &&
!string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user)) &&
owner.TenantId == user.TenantId &&
owner.NormalizedUserName != manager.NormalizeName(userName))
{
errors.Add(ErrorDescriber.DuplicateUserName(userName));
usersByUserName = users.Where(x => x.NormalizedEmail == normalizedUserName).ToList();
if (owner != null)
{
usersByUserName.RemoveAll(x => x.NormalizedUserName == user.NormalizedUserName);
}
if (usersByUserName.Any())
{
errors.Add(ErrorDescriber.InvalidUserName(user.UserName!));
}
}
}
return errors;
}
// make sure email is not empty, valid, and unique
private async Task<List<IdentityError>> ValidateEmail(UserManager<IdentityUser> manager, IdentityUser user)
{
var errors = new List<IdentityError>();
var email = await manager.GetEmailAsync(user);
if (string.IsNullOrWhiteSpace(email))
{
errors.Add(ErrorDescriber.InvalidEmail(email));
return errors;
}
if (!new EmailAddressAttribute().IsValid(email))
{
errors.Add(ErrorDescriber.InvalidEmail(email));
return errors;
}
IdentityUser owner;
using (CurrentTenant.Change(user.TenantId))
{
owner = await manager.FindByEmailAsync(email);
}
if (owner != null &&
!string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user)) &&
owner.TenantId == user.TenantId &&
owner.NormalizedEmail != manager.NormalizeEmail(email))
{
errors.Add(ErrorDescriber.DuplicateEmail(email));
}
return errors;
return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
}
}

Loading…
Cancel
Save