Ported changes from Umbraco 13 around not throwing exceptions with identity IDs that can't be parsed to an integer or GUID (#18389)
* Ported changes from Umbraco 13 around not throwing exceptions with identity IDs that can't be parsed to an integer or GUID. * Revert async changes (better done systemically in a separate update).
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -436,8 +437,7 @@ public class BackOfficeUserStore :
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
IUser? found = FindUserFromString(user.Id);
|
||||
if (found is not null)
|
||||
if (TryFindUserFromString(user.Id, out IUser? found))
|
||||
{
|
||||
DisableAsync(found).GetAwaiter().GetResult();
|
||||
}
|
||||
@@ -469,8 +469,7 @@ public class BackOfficeUserStore :
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
|
||||
IUser? user = FindUserFromString(userId);
|
||||
if (user == null)
|
||||
if (TryFindUserFromString(userId, out IUser? user) is false)
|
||||
{
|
||||
return Task.FromResult((BackOfficeIdentityUser?)null)!;
|
||||
}
|
||||
@@ -478,22 +477,28 @@ public class BackOfficeUserStore :
|
||||
return Task.FromResult(AssignLoginsCallback(_mapper.Map<BackOfficeIdentityUser>(user)))!;
|
||||
}
|
||||
|
||||
private IUser? FindUserFromString(string userId)
|
||||
private bool TryFindUserFromString(string userId, [NotNullWhen(true)] out IUser? user)
|
||||
{
|
||||
// We could use ResolveEntityIdFromIdentityId here, but that would require multiple DB calls, so let's not.
|
||||
if (TryConvertIdentityIdToInt(userId, out var id))
|
||||
{
|
||||
return GetAsync(id).GetAwaiter().GetResult();
|
||||
user = GetAsync(id).GetAwaiter().GetResult();
|
||||
return user is not null;
|
||||
}
|
||||
|
||||
// We couldn't directly convert the ID to an int, this is because the user logged in with external login.
|
||||
// So we need to look up the user by key.
|
||||
if (Guid.TryParse(userId, out Guid key))
|
||||
{
|
||||
return GetAsync(key).GetAwaiter().GetResult();
|
||||
user = GetAsync(key).GetAwaiter().GetResult();
|
||||
return user is not null;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Unable to resolve user with ID {userId}");
|
||||
// Maybe we have some other format of user Id from an external login flow, so don't throw but return null.
|
||||
// We won't be able to find the user via this ID in a local database lookup so we'll handle the same as if they don't exist.
|
||||
|
||||
user = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override async Task<int> ResolveEntityIdFromIdentityId(string? identityId)
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Data;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
@@ -322,9 +321,15 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
throw new ArgumentNullException(nameof(userId));
|
||||
}
|
||||
|
||||
IMember? user = Guid.TryParse(userId, out Guid key)
|
||||
? _memberService.GetByKey(key)
|
||||
: _memberService.GetById(ResolveEntityIdFromIdentityId(userId).GetAwaiter().GetResult());
|
||||
IMember? user = null;
|
||||
if (Guid.TryParse(userId, out Guid key))
|
||||
{
|
||||
user = _memberService.GetByKey(key);
|
||||
}
|
||||
else if (TryResolveEntityIdFromIdentityId(userId, out int id))
|
||||
{
|
||||
user = _memberService.GetById(id);
|
||||
}
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
@@ -334,11 +339,11 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
return Task.FromResult(AssignLoginsCallback(_mapper.Map<MemberIdentityUser>(user)))!;
|
||||
}
|
||||
|
||||
protected override Task<int> ResolveEntityIdFromIdentityId(string? identityId)
|
||||
private bool TryResolveEntityIdFromIdentityId(string? identityId, out int entityId)
|
||||
{
|
||||
if (TryConvertIdentityIdToInt(identityId, out var id))
|
||||
if (TryConvertIdentityIdToInt(identityId, out entityId))
|
||||
{
|
||||
return Task.FromResult(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Guid.TryParse(identityId, out Guid key))
|
||||
@@ -346,10 +351,21 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
IMember? member = _memberService.GetByKey(key);
|
||||
if (member is not null)
|
||||
{
|
||||
return Task.FromResult(member.Id);
|
||||
entityId = member.Id;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override Task<int> ResolveEntityIdFromIdentityId(string? identityId)
|
||||
{
|
||||
if (TryResolveEntityIdFromIdentityId(identityId, out var entityId))
|
||||
{
|
||||
return Task.FromResult(entityId);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Unable to resolve user with ID {identityId}");
|
||||
}
|
||||
|
||||
|
||||
@@ -35,29 +35,18 @@ public abstract class UmbracoUserStore<TUser, TRole>
|
||||
[Obsolete("Use TryConvertIdentityIdToInt instead. Scheduled for removal in V15.")]
|
||||
protected static int UserIdToInt(string? userId)
|
||||
{
|
||||
if (TryUserIdToInt(userId, out int result))
|
||||
if (int.TryParse(userId, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Unable to convert user ID ({userId})to int using InvariantCulture");
|
||||
}
|
||||
|
||||
protected static bool TryUserIdToInt(string? userId, out int result)
|
||||
{
|
||||
if (int.TryParse(userId, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Guid.TryParse(userId, out Guid key))
|
||||
{
|
||||
// Reverse the IntExtensions.ToGuid
|
||||
result = BitConverter.ToInt32(key.ToByteArray(), 0);
|
||||
return true;
|
||||
return BitConverter.ToInt32(key.ToByteArray(), 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
throw new InvalidOperationException($"Unable to convert user ID ({userId})to int using InvariantCulture");
|
||||
}
|
||||
|
||||
protected abstract Task<int> ResolveEntityIdFromIdentityId(string? identityId);
|
||||
|
||||
Reference in New Issue
Block a user