From 228995c84c4509168e9b2aa654a54f75251b60da Mon Sep 17 00:00:00 2001 From: Hao Kung Date: Fri, 6 Feb 2015 13:25:34 -0800 Subject: [PATCH] Add missing virtuals Enable unit test verifying methods are virtual Fixes https://github.com/aspnet/Identity/issues/349 --- .../DataProtectionTokenProvider.cs | 9 ++-- .../IdentityBuilder.cs | 24 +++++----- .../SignInManager.cs | 6 +-- .../UpperInvariantLookupNormalizer.cs | 2 +- test/Shared/ApiConsistencyTestBase.cs | 45 ++++++++++--------- 5 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs index 988b569e32..ebe628175e 100644 --- a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs @@ -6,7 +6,6 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; - using Microsoft.AspNet.Security.DataProtection; using Microsoft.Framework.OptionsModel; @@ -66,7 +65,7 @@ namespace Microsoft.AspNet.Identity /// The the token will be generated from. /// A to observe while waiting for the tasks to complete. /// A that contains the protected token. - public async Task GenerateAsync(string purpose, UserManager manager, TUser user, + public virtual async Task GenerateAsync(string purpose, UserManager manager, TUser user, CancellationToken cancellationToken = default(CancellationToken)) { if (user == null) @@ -100,7 +99,7 @@ namespace Microsoft.AspNet.Identity /// The the token was generated for. /// A to observe while waiting for the tasks to complete. /// A that is true if the token is valid, otherwise false. - public async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user, + public virtual async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user, CancellationToken cancellationToken = default(CancellationToken)) { try @@ -156,7 +155,7 @@ namespace Microsoft.AspNet.Identity /// The the token was generated for. /// True if a token generated by this instance can be used as a Two Factor Authentication token, otherwise false. /// This method will always return false for instances of . - public Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user, + public virtual Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(false); @@ -170,7 +169,7 @@ namespace Microsoft.AspNet.Identity /// The the token was generated for. /// A to observe while waiting for the tasks to complete. /// A that represents the started task. - public Task NotifyAsync(string token, UserManager manager, TUser user, + public virtual Task NotifyAsync(string token, UserManager manager, TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(0); diff --git a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs index 4f78d0731d..80efa2f345 100644 --- a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs +++ b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs @@ -25,53 +25,53 @@ namespace Microsoft.AspNet.Identity return this; } - public IdentityBuilder AddUserValidator() where T : class + public virtual IdentityBuilder AddUserValidator() where T : class { return AddScoped(typeof(IUserValidator<>).MakeGenericType(UserType), typeof(T)); } - public IdentityBuilder AddRoleValidator() where T : class + public virtual IdentityBuilder AddRoleValidator() where T : class { return AddScoped(typeof(IRoleValidator<>).MakeGenericType(RoleType), typeof(T)); } - public IdentityBuilder AddErrorDescriber() where TDescriber : IdentityErrorDescriber + public virtual IdentityBuilder AddErrorDescriber() where TDescriber : IdentityErrorDescriber { Services.AddScoped(); return this; } - public IdentityBuilder AddPasswordValidator() where T : class + public virtual IdentityBuilder AddPasswordValidator() where T : class { return AddScoped(typeof(IPasswordValidator<>).MakeGenericType(UserType), typeof(T)); } - public IdentityBuilder AddUserStore() where T : class + public virtual IdentityBuilder AddUserStore() where T : class { return AddScoped(typeof(IUserStore<>).MakeGenericType(UserType), typeof(T)); } - public IdentityBuilder AddRoleStore() where T : class + public virtual IdentityBuilder AddRoleStore() where T : class { return AddScoped(typeof(IRoleStore<>).MakeGenericType(RoleType), typeof(T)); } - public IdentityBuilder AddTokenProvider() where TProvider : class + public virtual IdentityBuilder AddTokenProvider() where TProvider : class { return AddTokenProvider(typeof(TProvider)); } - public IdentityBuilder AddTokenProvider(Type provider) + public virtual IdentityBuilder AddTokenProvider(Type provider) { return AddScoped(typeof(IUserTokenProvider<>).MakeGenericType(UserType), provider); } - public IdentityBuilder AddMessageProvider() where TProvider : IIdentityMessageProvider + public virtual IdentityBuilder AddMessageProvider() where TProvider : IIdentityMessageProvider { return AddScoped(typeof(IIdentityMessageProvider), typeof(TProvider)); } - public IdentityBuilder AddDefaultTokenProviders() + public virtual IdentityBuilder AddDefaultTokenProviders() { Services.Configure(options => { @@ -83,12 +83,12 @@ namespace Microsoft.AspNet.Identity .AddTokenProvider(typeof(EmailTokenProvider<>).MakeGenericType(UserType)); } - public IdentityBuilder AddUserManager() where TUserManager : class + public virtual IdentityBuilder AddUserManager() where TUserManager : class { return AddScoped(typeof(UserManager<>).MakeGenericType(UserType), typeof(TUserManager)); } - public IdentityBuilder AddRoleManager() where TRoleManager : class + public virtual IdentityBuilder AddRoleManager() where TRoleManager : class { return AddScoped(typeof(RoleManager<>).MakeGenericType(RoleType), typeof(TRoleManager)); } diff --git a/src/Microsoft.AspNet.Identity/SignInManager.cs b/src/Microsoft.AspNet.Identity/SignInManager.cs index b28e480c26..43a5ed62c7 100644 --- a/src/Microsoft.AspNet.Identity/SignInManager.cs +++ b/src/Microsoft.AspNet.Identity/SignInManager.cs @@ -224,7 +224,7 @@ namespace Microsoft.AspNet.Identity return await LogResultAsync(true, user); } - public async Task IsTwoFactorClientRememberedAsync(TUser user, + public virtual async Task IsTwoFactorClientRememberedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { var userId = await UserManager.GetUserIdAsync(user, cancellationToken); @@ -306,7 +306,7 @@ namespace Microsoft.AspNet.Identity return await UserManager.FindByIdAsync(info.UserId, cancellationToken); } - public async Task ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, + public virtual async Task ExternalLoginSignInAsync(string loginProvider, string providerKey, bool isPersistent, CancellationToken cancellationToken = default(CancellationToken)) { var user = await UserManager.FindByLoginAsync(loginProvider, providerKey, cancellationToken); @@ -361,7 +361,7 @@ namespace Microsoft.AspNet.Identity return new ExternalLoginInfo(auth.Identity, provider, providerKey, auth.Description.Caption); } - public AuthenticationProperties ConfigureExternalAuthenticationProperties(string provider, string redirectUrl, string userId = null) + public virtual AuthenticationProperties ConfigureExternalAuthenticationProperties(string provider, string redirectUrl, string userId = null) { var properties = new AuthenticationProperties { RedirectUri = redirectUrl }; properties.Dictionary[LoginProviderKey] = provider; diff --git a/src/Microsoft.AspNet.Identity/UpperInvariantLookupNormalizer.cs b/src/Microsoft.AspNet.Identity/UpperInvariantLookupNormalizer.cs index 9bfa9454a3..9b0a8cbe9a 100644 --- a/src/Microsoft.AspNet.Identity/UpperInvariantLookupNormalizer.cs +++ b/src/Microsoft.AspNet.Identity/UpperInvariantLookupNormalizer.cs @@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Identity /// /// /// - public string Normalize(string key) + public virtual string Normalize(string key) { if (key == null) { diff --git a/test/Shared/ApiConsistencyTestBase.cs b/test/Shared/ApiConsistencyTestBase.cs index 11daf5f9c6..b1acf68be9 100644 --- a/test/Shared/ApiConsistencyTestBase.cs +++ b/test/Shared/ApiConsistencyTestBase.cs @@ -16,29 +16,32 @@ namespace Microsoft.AspNet.Identity.Test protected const BindingFlags PublicInstance = BindingFlags.Instance | BindingFlags.Public; - //protected const BindingFlags AnyInstance - // = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + protected const BindingFlags AnyInstance + = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - //[Fact] - //public void Public_inheritable_apis_should_be_virtual() - //{ - // var nonVirtualMethods - // = (from type in GetAllTypes(TargetAssembly.GetTypes()) - // where type.IsVisible - // && !type.IsSealed - // && type.GetConstructors(AnyInstance).Any(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly) - // && type.Namespace != null - // && !type.Namespace.EndsWith(".Compiled") - // from method in type.GetMethods(PublicInstance) - // where GetBasestTypeInAssembly(method.DeclaringType) == type - // && !(method.IsVirtual && !method.IsFinal) - // select type.Name + "." + method.Name) - // .ToList(); + [Fact] + public void Public_inheritable_apis_should_be_virtual() + { + var nonVirtualMethods + = (from type in GetAllTypes(TargetAssembly.GetTypes()) + where type.IsVisible + && !type.IsSealed + && type.GetConstructors(AnyInstance).Any(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly) + && type.Namespace != null + && !type.Namespace.EndsWith(".Compiled") + from method in type.GetMethods(PublicInstance) + where GetBasestTypeInAssembly(method.DeclaringType) == type + && !(method.IsVirtual && !method.IsFinal) + && !method.Name.StartsWith("get_") + && !method.Name.StartsWith("set_") + && !method.Name.Equals("Dispose") + select type.Name + "." + method.Name) + .ToList(); - // Assert.False( - // nonVirtualMethods.Any(), - // "\r\n-- Missing virtual APIs --\r\n" + string.Join("\r\n", nonVirtualMethods)); - //} + Assert.False( + nonVirtualMethods.Any(), + "\r\n-- Missing virtual APIs --\r\n" + string.Join("\r\n", nonVirtualMethods)); + } //[Fact] //public void Public_api_arguments_should_have_not_null_annotation()