aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Add interfaces for Identity classes (UserManager<>, SignInManager<>)

Open TheYoxy opened this issue 2 years ago • 0 comments

Background and Motivation

As is, the identity classes are called directly inside the code by using the instance and there aren't any interfaces defined to use them. (For unit testing purposes, ...)

Proposed API

namespace Microsoft.AspNetCore.Identity;

+ public interface IUserManager<TUser> where TUser: class {
+    public Task<IdentityResult> UpdateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> DeleteAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> CreateAsync(TUser user, string password, CancellationToken cancellationToken = default(CancellationToken));
+    public Task UpdateNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string?> GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetUserNameAsync(TUser user, string? userName, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> CheckPasswordAsync(TUser user, string password, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> HasPasswordAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddPasswordAsync(TUser user, string password, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ChangePasswordAsync(TUser user, string currentPassword, string newPassword, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemovePasswordAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GetSecurityStampAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> UpdateSecurityStampAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GeneratePasswordResetTokenAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ResetPasswordAsync(TUser user, string token, string newPassword, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> FindByLoginAsync(stringloginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddClaimAsync(TUser user, Claim claim, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveClaimAsync(TUser user, Claim claim, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveClaimsAsync(TUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<Claim>> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddToRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AddToRolesAsync(TUser user, IEnumerable<string> roles, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveFromRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveFromRolesAsync(TUser user, IEnumerable<string> roles, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<string>> GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> IsInRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string?> GetEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetEmailAsync(TUser user, string? email, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken));
+    public Task UpdateNormalizedEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GenerateEmailConfirmationTokenAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ConfirmEmailAsync(TUser user, string token, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> IsEmailConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GenerateChangeEmailTokenAsync(TUser user, string newEmail, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ChangeEmailAsync(TUser user, string newEmail, string token, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string?> GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetPhoneNumberAsync(TUser user, string? phoneNumber, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ChangePhoneNumberAsync(TUser user, string phoneNumber, string token, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> IsPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GenerateChangePhoneNumberTokenAsync(TUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> VerifyChangePhoneNumberTokenAsync(TUser user, string token, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> VerifyUserTokenAsync(TUser user, string tokenProvider, string purpose, string token, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GenerateUserTokenAsync(TUser user, string tokenProvider, string purpose, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<string>> GetValidTwoFactorProvidersAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string> GenerateTwoFactorTokenAsync(TUser user, string tokenProvider, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> IsLockedOutAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> GetLockoutEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<DateTimeOffset?> GetLockoutEndDateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> AccessFailedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<int> GetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<TUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string?> GetAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> SetAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName, string? tokenValue, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RemoveAuthenticationTokenAsync(TUser user, string loginProvider, string tokenName, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<string?> GetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> ResetAuthenticatorKeyAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IEnumerable<string>?> GenerateNewTwoFactorRecoveryCodesAsync(TUser user, int number, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> RedeemTwoFactorRecoveryCodeAsync(TUser user, string code, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<int> CountRecoveryCodesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<byte[]> CreateSecurityTokenAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+ }

+ public interface ISignInManager<TUser> where TUser : class
+ {
+    public Task<ClaimsPrincipal> CreateUserPrincipalAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> CanSignInAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task RefreshSignInAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task SignInAsync(TUser user, bool isPersistent, string? authenticationMethod = null, CancellationToken cancellationToken = default(CancellationToken));
+    public Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string? authenticationMethod = null, CancellationToken cancellationToken = default(CancellationToken));
+    public Task SignInWithClaimsAsync(TUser user, bool isPersistent, IEnumerable<Claim> additionalClaims, CancellationToken cancellationToken = default(CancellationToken));
+    public Task SignInWithClaimsAsync(TUser user, AuthenticationProperties? authenticationProperties, IEnumerable<Claim> additionalClaims, CancellationToken cancellationToken = default(CancellationToken));
+    public Task SignOutAsync(CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> ValidateSecurityStampAsync(ClaimsPrincipal? principal, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> ValidateTwoFactorSecurityStampAsync(ClaimsPrincipal? principal, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> ValidateSecurityStampAsync(TUser? user, string? securityStamp, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> PasswordSignInAsync(TUser user, string password, bool isPersistent, bool lockoutOnFailure, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> CheckPasswordSignInAsync(TUser user, string password, bool lockoutOnFailure, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<bool> IsTwoFactorClientRememberedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task RememberTwoFactorClientAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken));
+    public Task ForgetTwoFactorClientAsync(CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> TwoFactorRecoveryCodeSignInAsync(string recoveryCode, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> TwoFactorAuthenticatorSignInAsync(string code, bool isPersistent, bool rememberClient, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<TUser?> GetTwoFactorAuthenticationUserAsync(CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<SignInResult> ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, bool bypassTwoFactor, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IEnumerable<AuthenticationScheme>> GetExternalAuthenticationSchemesAsync(CancellationToken cancellationToken = default(CancellationToken));
+    public Task<ExternalLoginInfo?> GetExternalLoginInfoAsync(string? expectedXsrf = null, CancellationToken cancellationToken = default(CancellationToken));
+    public Task<IdentityResult> UpdateExternalAuthenticationTokensAsync(ExternalLoginInfo externalLogin, CancellationToken cancellationToken = default(CancellationToken));
+ }

- public class SignInManager<TUser> where TUser: class
+ public class SignInManager<TUser> : ISignInManager<TUser> where TUser: class

- public class UserManager<TUser> : IDisposable where TUser : class
+ public class UserManager<TUser> : IUserManager<TUser>, IDisposable where TUser : class

Usage Examples

Every usage of the UserManager<> can be replaced by the newly created IUserManager<>. Same thing for the SignInManager<>.

Alternative Designs

As is, only public methods were added inside the interface. As needed, some of them could be added or removed depending on the requirements.

Risks

The only risk depends on the usage of the replacement of the class by the newly created interface related to the service.

TheYoxy avatar Jan 05 '23 13:01 TheYoxy