Browse Source

Refactor user validation logic in AbpIdentityUserValidator

pull/24456/head
maliming 9 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
@ -93,10 +92,13 @@ namespace Volo.Abp.Identity
{ {
var errors = new List<IdentityError>(); var errors = new List<IdentityError>();
var defaultValidationResult = await BuiltInValidateAsync(manager, user); using (CurrentTenant.Change(user.TenantId))
if (!defaultValidationResult.Succeeded)
{ {
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)); 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()); owner = await manager.FindByIdAsync(user.Id.ToString());
} }
var normalizedUserName = manager.NormalizeName(user.UserName); var normalizedUserName = manager.NormalizeName(user.UserName);
var normalizedEmail = manager.NormalizeEmail(user.Email); 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) 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(ErrorDescriber.DuplicateUserName(user.UserName!));
errors.Add(userNames.Contains(user.UserName) ? ErrorDescriber.InvalidUserName(user.UserName!) : ErrorDescriber.InvalidEmail(user.Email!));
} }
users = await UserRepository.GetUsersByNormalizedEmailsAsync([normalizedUserName!, normalizedEmail], true); var usersByEmail = users.Where(x => x.NormalizedUserName == normalizedEmail).ToList();
users.RemoveAll(x => x.Id == user.Id);
if (owner != null) 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(ErrorDescriber.InvalidEmail(user.Email!));
errors.Add(emails.Contains(user.Email) ? ErrorDescriber.InvalidEmail(user.Email!) : ErrorDescriber.InvalidUserName(user.UserName!));
} }
}
}
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)
public virtual async Task<IdentityResult> BuiltInValidateAsync(UserManager<IdentityUser> manager, IdentityUser user) {
{ usersByEmail.RemoveAll(x => x.NormalizedEmail == user.NormalizedEmail);
var errors = await ValidateUserName(manager, user); }
if (manager.Options.User.RequireUniqueEmail) if (usersByEmail.Any())
{ {
errors.AddRange(await ValidateEmail(manager, user)); errors.Add(ErrorDescriber.DuplicateEmail(user.Email!));
} }
return errors?.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
private async Task<List<IdentityError>> ValidateUserName(UserManager<IdentityUser> manager, IdentityUser user) usersByUserName = users.Where(x => x.NormalizedEmail == normalizedUserName).ToList();
{ if (owner != null)
var errors = new List<IdentityError>(); {
var userName = await manager.GetUserNameAsync(user); usersByUserName.RemoveAll(x => x.NormalizedUserName == user.NormalizedUserName);
if (string.IsNullOrWhiteSpace(userName)) }
{ if (usersByUserName.Any())
errors.Add(ErrorDescriber.InvalidUserName(userName)); {
} errors.Add(ErrorDescriber.InvalidUserName(user.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));
} }
} }
return errors; return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
// 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;
} }
} }
} }

Loading…
Cancel
Save