diff --git a/src/Microsoft.AspNetCore.Identity.EntityFrameworkCore/UserStore.cs b/src/Microsoft.AspNetCore.Identity.EntityFrameworkCore/UserStore.cs index cac71ac9b6..d8d1422eb2 100644 --- a/src/Microsoft.AspNetCore.Identity.EntityFrameworkCore/UserStore.cs +++ b/src/Microsoft.AspNetCore.Identity.EntityFrameworkCore/UserStore.cs @@ -513,6 +513,66 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore return Task.FromResult(user.PasswordHash != null); } + /// + /// Return a role with the normalized name if it exists. + /// + /// The normalized role name. + /// The used to propagate notifications that the operation should be canceled. + /// The role if it exists. + protected virtual Task FindRoleAsync(string normalizedRoleName, CancellationToken cancellationToken) + { + return Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); + } + + /// + /// Return a user role for the userId and roleId if it exists. + /// + /// The user's id. + /// The role's id. + /// The used to propagate notifications that the operation should be canceled. + /// The user role if it exists. + protected virtual Task FindUserRoleAsync(TKey userId, TKey roleId, CancellationToken cancellationToken) + { + return UserRoles.FindAsync(new object[] { userId, roleId }, cancellationToken); + } + + /// + /// Return a user with the matching userId if it exists. + /// + /// The user's id. + /// The used to propagate notifications that the operation should be canceled. + /// The user if it exists. + protected virtual Task FindUserAsync(TKey userId, CancellationToken cancellationToken) + { + return Users.SingleOrDefaultAsync(u => u.Id.Equals(userId), cancellationToken); + } + + /// + /// Return a user login with the matching userId, provider, providerKey if it exists. + /// + /// The user's id. + /// The login provider name. + /// The key provided by the to identify a user. + /// The used to propagate notifications that the operation should be canceled. + /// The user login if it exists. + protected virtual Task FindUserLoginAsync(TKey userId, string loginProvider, string providerKey, CancellationToken cancellationToken) + { + return UserLogins.SingleOrDefaultAsync(userLogin => userLogin.UserId.Equals(userId) && userLogin.LoginProvider == loginProvider && userLogin.ProviderKey == providerKey, cancellationToken); + } + + /// + /// Return a user login with provider, providerKey if it exists. + /// + /// The login provider name. + /// The key provided by the to identify a user. + /// The used to propagate notifications that the operation should be canceled. + /// The user login if it exists. + protected virtual Task FindUserLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken) + { + return UserLogins.SingleOrDefaultAsync(userLogin => userLogin.LoginProvider == loginProvider && userLogin.ProviderKey == providerKey, cancellationToken); + } + + /// /// Adds the given to the specified . /// @@ -532,10 +592,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName)); } - var roleEntity = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); + var roleEntity = await FindRoleAsync(normalizedRoleName, cancellationToken); if (roleEntity == null) { - throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, normalizedRoleName)); + throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.RoleNotFound, normalizedRoleName)); } UserRoles.Add(CreateUserRole(user, roleEntity)); } @@ -559,10 +619,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName)); } - var roleEntity = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); + var roleEntity = await FindRoleAsync(normalizedRoleName, cancellationToken); if (roleEntity != null) { - var userRole = await UserRoles.FindAsync(new object[] { user.Id, roleEntity.Id }, cancellationToken); + var userRole = await FindUserRoleAsync(user.Id, roleEntity.Id, cancellationToken); if (userRole != null) { UserRoles.Remove(userRole); @@ -612,10 +672,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentException(Resources.ValueCannotBeNullOrEmpty, nameof(normalizedRoleName)); } - var role = await Roles.SingleOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, cancellationToken); + var role = await FindRoleAsync(normalizedRoleName, cancellationToken); if (role != null) { - var userRole = await UserRoles.FindAsync(new object[] { user.Id, role.Id }, cancellationToken); + var userRole = await FindUserRoleAsync(user.Id, role.Id, cancellationToken); return userRole != null; } return false; @@ -783,7 +843,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentNullException(nameof(user)); } - var entry = await UserLogins.SingleOrDefaultAsync(userLogin => userLogin.UserId.Equals(user.Id) && userLogin.LoginProvider == loginProvider && userLogin.ProviderKey == providerKey, cancellationToken); + var entry = await FindUserLoginAsync(user.Id, loginProvider, providerKey, cancellationToken); if (entry != null) { UserLogins.Remove(entry); @@ -825,10 +885,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); - var userLogin = await UserLogins.FindAsync(new object[] { loginProvider, providerKey }, cancellationToken); + var userLogin = await FindUserLoginAsync(loginProvider, providerKey, cancellationToken); if (userLogin != null) { - return await Users.FirstOrDefaultAsync(u => u.Id.Equals(userLogin.UserId), cancellationToken); + return await FindUserAsync(userLogin.UserId, cancellationToken); } return null; } @@ -1293,7 +1353,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore throw new ArgumentNullException(nameof(normalizedRoleName)); } - var role = await Roles.Where(x => x.NormalizedName == normalizedRoleName).FirstOrDefaultAsync(cancellationToken); + var role = await FindRoleAsync(normalizedRoleName, cancellationToken); if (role != null) { @@ -1307,7 +1367,15 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore return new List(); } - private Task FindToken(TUser user, string loginProvider, string name, CancellationToken cancellationToken) + /// + /// Find a user token if it exists. + /// + /// The token owner. + /// The login provider for the token. + /// The name of the token. + /// The used to propagate notifications that the operation should be canceled. + /// The user token if it exists. + protected virtual Task FindTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) => UserTokens.FindAsync(new object[] { user.Id, loginProvider, name }, cancellationToken); /// @@ -1329,7 +1397,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore throw new ArgumentNullException(nameof(user)); } - var token = await FindToken(user, loginProvider, name, cancellationToken); + var token = await FindTokenAsync(user, loginProvider, name, cancellationToken); if (token == null) { UserTokens.Add(CreateUserToken(user, loginProvider, name, value)); @@ -1357,7 +1425,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentNullException(nameof(user)); } - var entry = await FindToken(user, loginProvider, name, cancellationToken); + var entry = await FindTokenAsync(user, loginProvider, name, cancellationToken); if (entry != null) { UserTokens.Remove(entry); @@ -1381,7 +1449,7 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { throw new ArgumentNullException(nameof(user)); } - var entry = await FindToken(user, loginProvider, name, cancellationToken); + var entry = await FindTokenAsync(user, loginProvider, name, cancellationToken); return entry?.Value; }