diff --git a/samples/IdentitySample.Mvc/LocalConfig.json b/samples/IdentitySample.Mvc/LocalConfig.json index dd1dfa2c6b..cef3722445 100644 --- a/samples/IdentitySample.Mvc/LocalConfig.json +++ b/samples/IdentitySample.Mvc/LocalConfig.json @@ -8,5 +8,13 @@ "IdentityConnection": { "Connectionstring": "Server=(localdb)\\v11.0;Database=IdentityMvc-8-12-14;Trusted_Connection=True;MultipleActiveResultSets=true" } + }, + "Identity": { + "Password": { + "RequireDigit" : "false", + "RequireLowercase" : "false", + "RequireUppercase" : "false", + "RequireNonLetterOrDigit" : "false" + } } } \ No newline at end of file diff --git a/samples/IdentitySample.Mvc/Startup.cs b/samples/IdentitySample.Mvc/Startup.cs index e77d6b8367..c797c10071 100644 --- a/samples/IdentitySample.Mvc/Startup.cs +++ b/samples/IdentitySample.Mvc/Startup.cs @@ -36,12 +36,8 @@ namespace IdentitySamples options.DefaultAdminPassword = Configuration.Get("DefaultAdminPassword"); }); - services.AddDefaultIdentity(Configuration, options => + services.AddDefaultIdentity(Configuration.GetSubKey("Identity"), options => { - options.Password.RequireDigit = false; - options.Password.RequireLowercase = false; - options.Password.RequireUppercase = false; - options.Password.RequireNonLetterOrDigit = false; options.SecurityStampValidationInterval = TimeSpan.FromMinutes(20); }); diff --git a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs index b850e5a5a6..ae7bdfc960 100644 --- a/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/DataProtectionTokenProvider.cs @@ -1,4 +1,5 @@ using Microsoft.AspNet.Security.DataProtection; +using Microsoft.Framework.OptionsModel; using System; using System.IO; using System.Text; @@ -11,7 +12,6 @@ namespace Microsoft.AspNet.Identity { public string Name { get; set; } = "DataProtection"; public TimeSpan TokenLifespan { get; set; } = TimeSpan.FromDays(1); - } /// @@ -19,18 +19,19 @@ namespace Microsoft.AspNet.Identity /// public class DataProtectorTokenProvider : IUserTokenProvider where TUser : class { - public DataProtectorTokenProvider(DataProtectionTokenProviderOptions options, IDataProtector protector) + public DataProtectorTokenProvider(IDataProtectionProvider dataProtectionProvider, IOptions options) { - if (options == null) + if (options == null || options.Options == null) { throw new ArgumentNullException(nameof(options)); } - if (protector == null) + if (dataProtectionProvider == null) { - throw new ArgumentNullException(nameof(protector)); + throw new ArgumentNullException(nameof(dataProtectionProvider)); } - Options = options; - Protector = protector; + Options = options.Options; + // Use the Name as the purpose which should usually be distinct from others + Protector = dataProtectionProvider.CreateProtector(Name ?? "DataProtectorTokenProvider"); } public DataProtectionTokenProviderOptions Options { get; private set; } diff --git a/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs b/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs index a01f45e92e..6220037c94 100644 --- a/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/EmailTokenProvider.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Identity { @@ -24,14 +25,15 @@ namespace Microsoft.AspNet.Identity public class EmailTokenProvider : TotpSecurityStampBasedTokenProvider where TUser : class { - public EmailTokenProvider(EmailTokenProviderOptions options) + public EmailTokenProvider(IOptions options, string name = "") { - Options = options; + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + Options = options.GetNamedOptions(name); } - - public EmailTokenProvider() : this(new EmailTokenProviderOptions()) { } - public EmailTokenProviderOptions Options { get; private set; } public override string Name { get { return Options.Name; } } diff --git a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs index a6214cce5b..3368f3b6d0 100644 --- a/src/Microsoft.AspNet.Identity/IdentityBuilder.cs +++ b/src/Microsoft.AspNet.Identity/IdentityBuilder.cs @@ -43,9 +43,10 @@ namespace Microsoft.AspNet.Identity return AddInstance(validator); } - public IdentityBuilder AddTokenProvider(IUserTokenProvider tokenProvider) + public IdentityBuilder AddTokenProvider() where TTokenProvider : class, IUserTokenProvider { - return AddInstance(tokenProvider); + Services.AddScoped, TTokenProvider>(); + return this; } public IdentityBuilder ConfigureIdentity(Action action, int order = 0) diff --git a/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs index 015d026561..e4d97c5dc8 100644 --- a/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Identity/IdentityServiceCollectionExtensions.cs @@ -96,16 +96,14 @@ namespace Microsoft.Framework.DependencyInjection where TUser : class where TRole : class { - return services.AddIdentity(config, configureOptions) - .AddTokenProvider(new DataProtectorTokenProvider( - new DataProtectionTokenProviderOptions - { - Name = Resources.DefaultTokenProvider, - }, - // TODO: This needs to get IDataProtectionProvider from the environment - new EphemeralDataProtectionProvider().CreateProtector("ASP.NET Identity"))) - .AddTokenProvider(new PhoneNumberTokenProvider()) - .AddTokenProvider(new EmailTokenProvider()); + services.Configure(options => + { + options.Name = Resources.DefaultTokenProvider; + }); + return services.AddIdentity(config) + .AddTokenProvider>() + .AddTokenProvider>() + .AddTokenProvider>(); } public static IdentityBuilder AddIdentity(this IServiceCollection services) diff --git a/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs b/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs index 0a6f759af2..2f0ded3145 100644 --- a/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs +++ b/src/Microsoft.AspNet.Identity/PhoneNumberTokenProvider.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Identity { @@ -12,7 +13,7 @@ namespace Microsoft.AspNet.Identity /// /// Message contents which should contain a format string which the token will be the only argument /// - public string MessageFormat { get; set; } = "Your security code is: {0}"; + public string MessageFormat { get; set; } = Resources.DefaultPhoneNumberTokenProviderMessageFormat; } /// @@ -22,14 +23,15 @@ namespace Microsoft.AspNet.Identity public class PhoneNumberTokenProvider : TotpSecurityStampBasedTokenProvider where TUser : class { - public PhoneNumberTokenProvider(PhoneNumberTokenProviderOptions options) + public PhoneNumberTokenProvider(IOptions options) { - Options = options; + if (options == null || options.Options == null) + { + throw new ArgumentNullException(nameof(options)); + } + Options = options.Options; } - - public PhoneNumberTokenProvider() : this(new PhoneNumberTokenProviderOptions()) { } - public PhoneNumberTokenProviderOptions Options { get; private set; } public override string Name { get { return Options.Name; } } diff --git a/src/Microsoft.AspNet.Identity/UserManager.cs b/src/Microsoft.AspNet.Identity/UserManager.cs index 7788b6e0e0..5fd7a7f0ad 100644 --- a/src/Microsoft.AspNet.Identity/UserManager.cs +++ b/src/Microsoft.AspNet.Identity/UserManager.cs @@ -10,7 +10,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Framework.OptionsModel; -using Microsoft.AspNet.Security.DataProtection; namespace Microsoft.AspNet.Identity { diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs index ebbb92a98d..4ab71973bd 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/EntityInMemoryTestServiceCollectionExtensions.cs @@ -20,14 +20,10 @@ namespace Microsoft.AspNet.Identity where TRole : IdentityRole where TDbContext : DbContext { - var builder = services.AddIdentity(); + var builder = services.AddDefaultIdentity(); services.AddInstance>(new InMemoryUserStore(context)); var store = new RoleStore(context); services.AddInstance>(store); - //services.AddInstance(context); - //services.AddScoped(); - //services.AddScoped, InMemoryUserStore>(); - //services.AddScoped, RoleStore>(); return builder; } } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs index 72aa757d62..e8bd3397b6 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/InMemoryEFUserStoreTest.cs @@ -3,8 +3,6 @@ using Microsoft.AspNet.Identity.Test; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test { @@ -15,38 +13,15 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return new InMemoryContext(); } - protected override UserManager CreateManager(object context) + protected override void AddUserStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - var services = new ServiceCollection(); - services.Add(OptionsServices.GetDefaultServices()); - services.AddEntityFramework().AddInMemoryStore(); - services.AddIdentityInMemory((InMemoryContext)context); - services.ConfigureIdentity(options => - { - options.Password.RequireDigit = false; - options.Password.RequireLowercase = false; - options.Password.RequireNonLetterOrDigit = false; - options.Password.RequireUppercase = false; - options.User.UserNameValidationRegex = null; - }); - return services.BuildServiceProvider().GetRequiredService>(); + services.AddInstance>(new InMemoryUserStore((InMemoryContext)context)); } - protected override RoleManager CreateRoleManager(object context) + protected override void AddRoleStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - var services = new ServiceCollection(); - services.Add(OptionsServices.GetDefaultServices()); - services.AddEntityFramework().AddInMemoryStore(); - services.AddIdentityInMemory((InMemoryContext)context); - return services.BuildServiceProvider().GetRequiredService>(); + var store = new RoleStore((InMemoryContext)context); + services.AddInstance>(store); } } } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs index 95b40a13c1..1949243637 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/TestIdentityFactory.cs @@ -23,20 +23,10 @@ namespace Microsoft.AspNet.Identity.EntityFramework.InMemory.Test return db; } - public static UserManager CreateManager(InMemoryContext context) - { - return MockHelpers.CreateManager(new InMemoryUserStore(context)); - } - - public static UserManager CreateManager() - { - return CreateManager(CreateContext()); - } - public static RoleManager CreateRoleManager(InMemoryContext context) { var services = new ServiceCollection(); - services.AddIdentity().AddRoleStore(new RoleStore(context)); + services.AddDefaultIdentity().AddRoleStore(new RoleStore(context)); return services.BuildServiceProvider().GetRequiredService>(); } diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/project.json b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/project.json index e0d9073c7d..38d3deabe7 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/project.json +++ b/test/Microsoft.AspNet.Identity.EntityFramework.InMemory.Test/project.json @@ -1,5 +1,6 @@ { "dependencies": { + "Microsoft.AspNet.Hosting": "1.0.0-*", "Microsoft.AspNet.Http": "1.0.0-*", "Microsoft.AspNet.Identity": "3.0.0-*", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-*", diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs index f8013e73bc..0eda3c67f8 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/SqlStoreTestBase.cs @@ -7,13 +7,14 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Identity.Test; +using Microsoft.Data.Entity; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; using Xunit; namespace Microsoft.AspNet.Identity.EntityFramework.Test { - public abstract class SqlStoreTestBase : UserManagerTestBase where TUser : IdentityUser, new() where TRole : IdentityRole, new() @@ -59,24 +60,14 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return CreateContext(); } - protected override UserManager CreateManager(object context = null) + protected override void AddUserStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - return MockHelpers.CreateManager(new UserStore((TestDbContext)context)); + services.AddInstance>(new UserStore((TestDbContext)context)); } - protected override RoleManager CreateRoleManager(object context = null) + protected override void AddRoleStore(IServiceCollection services, object context = null) { - var services = DbUtil.ConfigureDbServices(ConnectionString); - if (context == null) - { - context = CreateTestContext(); - } - services.AddIdentity().AddRoleStore(new RoleStore((TestDbContext)context)); - return services.BuildServiceProvider().GetRequiredService>(); + services.AddInstance>(new RoleStore((TestDbContext)context)); } public void EnsureDatabase() diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs index 43185a33b8..7f3ca537d0 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreGuidKeyTest.cs @@ -4,7 +4,6 @@ using System; using Microsoft.AspNet.Identity.Test; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; using Xunit; namespace Microsoft.AspNet.Identity.EntityFramework.Test @@ -60,24 +59,14 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test } } - protected override UserManager CreateManager(object context) + protected override void AddUserStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - return MockHelpers.CreateManager(new ApplicationUserStore((TestDbContext)context)); + services.AddInstance>(new ApplicationUserStore((TestDbContext)context)); } - protected override RoleManager CreateRoleManager(object context) + protected override void AddRoleStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - var services = DbUtil.ConfigureDbServices(ConnectionString); - services.AddIdentity().AddRoleStore(new ApplicationRoleStore((TestDbContext)context)); - return services.BuildServiceProvider().GetRequiredService>(); + services.AddInstance>(new ApplicationRoleStore((TestDbContext)context)); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs index fbdc94a882..04a5e07c4e 100644 --- a/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.EntityFramework.Test/UserStoreTest.cs @@ -16,11 +16,11 @@ using Xunit; namespace Microsoft.AspNet.Identity.EntityFramework.Test { - public class ApplicationDbContext : IdentityDbContext { } - [TestCaseOrderer("Microsoft.AspNet.Identity.Test.PriorityOrderer", "Microsoft.AspNet.Identity.EntityFramework.Test")] public class UserStoreTest : UserManagerTestBase { + public class ApplicationDbContext : IdentityDbContext { } + private readonly string ConnectionString = @"Server=(localdb)\v11.0;Database=SqlUserStoreTest" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + ";Trusted_Connection=True;"; [TestPriority(-1000)] @@ -145,34 +145,14 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test return db; } - public static UserManager CreateManager(DbContext context) + protected override void AddUserStore(IServiceCollection services, object context = null) { - return MockHelpers.CreateManager(new UserStore(context)); + services.AddInstance>(new UserStore((IdentityDbContext)context)); } - protected override UserManager CreateManager(object context = null) + protected override void AddRoleStore(IServiceCollection services, object context = null) { - if (context == null) - { - context = CreateTestContext(); - } - return CreateManager((DbContext)context); - } - - public RoleManager CreateRoleManager(IdentityDbContext context) - { - var services = DbUtil.ConfigureDbServices(ConnectionString); - services.AddIdentity().AddRoleStore(new RoleStore(context)); - return services.BuildServiceProvider().GetRequiredService>(); - } - - protected override RoleManager CreateRoleManager(object context) - { - if (context == null) - { - context = CreateTestContext(); - } - return CreateRoleManager((IdentityDbContext)context); + services.AddInstance>(new RoleStore((IdentityDbContext)context)); } [Fact] diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/HttpSignInTest.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/HttpSignInTest.cs index a0066ca23d..3ba88219e8 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/HttpSignInTest.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/HttpSignInTest.cs @@ -36,7 +36,9 @@ namespace Microsoft.AspNet.Identity.InMemory.Test app.UseServices(services => { services.AddInstance(contextAccessor.Object); - services.AddIdentity().AddInMemory(); + services.AddIdentity(); + services.AddSingleton, InMemoryUserStore>(); + services.AddSingleton, InMemoryRoleStore>(); }); // Act diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/IdentityBuilderExtensions.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/IdentityBuilderExtensions.cs deleted file mode 100644 index 69d2f145a2..0000000000 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/IdentityBuilderExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Identity.InMemory; -using Microsoft.Framework.DependencyInjection; - -namespace Microsoft.AspNet.Identity -{ - public static class IdentityBuilderExtensions - { - public static IdentityBuilder AddInMemory(this IdentityBuilder builder) - where TUser : IdentityUser - where TRole : IdentityRole - { - builder.Services.AddSingleton, InMemoryUserStore>(); - builder.Services.AddScoped, UserManager>(); - builder.Services.AddSingleton, InMemoryRoleStore>(); - builder.Services.AddScoped, RoleManager>(); - return builder; - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs index 55b8e69c7b..e3de60ca21 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs @@ -1,11 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using Microsoft.AspNet.Identity.Test; using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Identity.InMemory.Test { @@ -16,27 +13,14 @@ namespace Microsoft.AspNet.Identity.InMemory.Test return null; } - protected override UserManager CreateManager(object context) + protected override void AddUserStore(IServiceCollection services, object context = null) { - var services = new ServiceCollection(); - services.Add(OptionsServices.GetDefaultServices()); - services.AddIdentity().AddInMemory(); - services.ConfigureIdentity(options => - { - options.Password.RequireDigit = false; - options.Password.RequireLowercase = false; - options.Password.RequireNonLetterOrDigit = false; - options.Password.RequireUppercase = false; - options.User.UserNameValidationRegex = null; - }); - return services.BuildServiceProvider().GetRequiredService>(); + services.AddSingleton, InMemoryUserStore>(); } - protected override RoleManager CreateRoleManager(object context) + protected override void AddRoleStore(IServiceCollection services, object context = null) { - var services = new ServiceCollection(); - services.AddIdentity().AddInMemory(); - return services.BuildServiceProvider().GetRequiredService>(); + services.AddSingleton, InMemoryRoleStore>(); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/StartupTest.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/StartupTest.cs deleted file mode 100644 index b8e2959d96..0000000000 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/StartupTest.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Identity.Test; -using Microsoft.Framework.DependencyInjection; -using Microsoft.Framework.DependencyInjection.Fallback; -using Microsoft.Framework.OptionsModel; -using System; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNet.Identity.InMemory.Test -{ - public class StartupTest - { - public class ApplicationUser : IdentityUser { } - - [Fact] - public async Task EnsureStartupUsageWorks() - { - var builder = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()); - - builder.UseServices(services => services.AddIdentity().AddInMemory()); - - var userStore = builder.ApplicationServices.GetRequiredService>(); - var roleStore = builder.ApplicationServices.GetRequiredService>(); - var userManager = builder.ApplicationServices.GetRequiredService>(); - var roleManager = builder.ApplicationServices.GetRequiredService>(); - - Assert.NotNull(userStore); - Assert.NotNull(userManager); - Assert.NotNull(roleStore); - Assert.NotNull(roleManager); - - await CreateAdminUser(builder.ApplicationServices); - } - - [Fact] - public void VerifyUseInMemoryLifetimes() - { - var builder = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()); - builder.UseServices(services => services.AddIdentity().AddInMemory()); - - var userStore = builder.ApplicationServices.GetRequiredService>(); - var roleStore = builder.ApplicationServices.GetRequiredService>(); - var userManager = builder.ApplicationServices.GetRequiredService>(); - var roleManager = builder.ApplicationServices.GetRequiredService>(); - - Assert.NotNull(userStore); - Assert.NotNull(userManager); - Assert.NotNull(roleStore); - Assert.NotNull(roleManager); - - var userStore2 = builder.ApplicationServices.GetRequiredService>(); - var roleStore2 = builder.ApplicationServices.GetRequiredService>(); - var userManager2 = builder.ApplicationServices.GetRequiredService>(); - var roleManager2 = builder.ApplicationServices.GetRequiredService>(); - - // Stores are singleton, managers are scoped - Assert.Equal(userStore, userStore2); - Assert.Equal(userManager, userManager2); - Assert.Equal(roleStore, roleStore2); - Assert.Equal(roleManager, roleManager2); - } - - - private static async Task CreateAdminUser(IServiceProvider serviceProvider) - { - const string userName = "admin"; - const string roleName = "Admins"; - const string password = "1qaz@WSX"; - var userManager = serviceProvider.GetRequiredService>(); - var roleManager = serviceProvider.GetRequiredService>(); - - var user = new ApplicationUser { UserName = userName }; - IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); - IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(new IdentityRole { Name = roleName })); - IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, roleName)); - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/project.json b/test/Microsoft.AspNet.Identity.InMemory.Test/project.json index 669128f47a..470267ba51 100644 --- a/test/Microsoft.AspNet.Identity.InMemory.Test/project.json +++ b/test/Microsoft.AspNet.Identity.InMemory.Test/project.json @@ -1,5 +1,6 @@ { "dependencies": { + "Microsoft.AspNet.Hosting": "1.0.0-*", "Microsoft.AspNet.Http" : "1.0.0-*", "Microsoft.AspNet.Identity" : "3.0.0-*", "Microsoft.AspNet.PipelineCore" : "1.0.0-*", diff --git a/test/Microsoft.AspNet.Identity.Test/project.json b/test/Microsoft.AspNet.Identity.Test/project.json index 803c03e7d6..75d6ba15c1 100644 --- a/test/Microsoft.AspNet.Identity.Test/project.json +++ b/test/Microsoft.AspNet.Identity.Test/project.json @@ -1,5 +1,6 @@ { "dependencies": { + "Microsoft.AspNet.Hosting" : "1.0.0-*", "Microsoft.AspNet.Http" : "1.0.0-*", "Microsoft.AspNet.Identity" : "3.0.0-*", "Microsoft.AspNet.PipelineCore" : "1.0.0-*", diff --git a/test/Shared/MockHelpers.cs b/test/Shared/MockHelpers.cs index ff52d292ae..0eb2418d2c 100644 --- a/test/Shared/MockHelpers.cs +++ b/test/Shared/MockHelpers.cs @@ -1,34 +1,35 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNet.Hosting; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection.Fallback; using Microsoft.Framework.OptionsModel; using Moq; -using System; -using System.Collections.Generic; namespace Microsoft.AspNet.Identity.Test { public static class MockHelpers { - public static UserManager CreateManager(IUserStore store) where TUser : class - { - var services = new ServiceCollection(); - services.Add(OptionsServices.GetDefaultServices()); - services.AddIdentity().AddUserStore(store); - services.ConfigureIdentity(options => - { - options.Password.RequireDigit = false; - options.Password.RequireLowercase = false; - options.Password.RequireNonLetterOrDigit = false; - options.Password.RequireUppercase = false; - options.User.UserNameValidationRegex = null; - }); - return services.BuildServiceProvider().GetService>(); - } + //public static UserManager CreateManager(IUserStore store) where TUser : class + //{ + // var services = new ServiceCollection(); + // services.Add(OptionsServices.GetDefaultServices()); + // services.Add(HostingServices.GetDefaultServices()); + // services.AddDefaultIdentity().AddUserStore(store); + // services.ConfigureIdentity(options => + // { + // options.Password.RequireDigit = false; + // options.Password.RequireLowercase = false; + // options.Password.RequireNonLetterOrDigit = false; + // options.Password.RequireUppercase = false; + // options.User.UserNameValidationRegex = null; + // }); + // return services.BuildServiceProvider().GetService>(); + //} public static Mock> MockUserManager() where TUser : class { diff --git a/test/Shared/UserManagerTestBase.cs b/test/Shared/UserManagerTestBase.cs index c05a09d3f5..a9bf752c00 100644 --- a/test/Shared/UserManagerTestBase.cs +++ b/test/Shared/UserManagerTestBase.cs @@ -10,10 +10,13 @@ using System.Threading.Tasks; using Microsoft.AspNet.Testing; using Xunit; using Microsoft.AspNet.Security.DataProtection; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using Microsoft.AspNet.Hosting; +using Microsoft.Framework.DependencyInjection.Fallback; namespace Microsoft.AspNet.Identity.Test { - // Common functionality tests that all verifies user manager functionality regardless of store implementation public abstract class UserManagerTestBase : UserManagerTestBase where TUser : IdentityUser, new() @@ -25,10 +28,57 @@ namespace Microsoft.AspNet.Identity.Test where TRole: IdentityRole, new() where TKey : IEquatable { - protected abstract UserManager CreateManager(object context = null); - protected abstract RoleManager CreateRoleManager(object context = null); + protected virtual void SetupIdentityServices(IServiceCollection services, object context = null) + { + services.Add(OptionsServices.GetDefaultServices()); + services.Add(HostingServices.GetDefaultServices()); + services.AddDefaultIdentity(); + AddUserStore(services, context); + AddRoleStore(services, context); + services.ConfigureIdentity(options => + { + options.Password.RequireDigit = false; + options.Password.RequireLowercase = false; + options.Password.RequireNonLetterOrDigit = false; + options.Password.RequireUppercase = false; + options.User.UserNameValidationRegex = null; + }); + + } + + protected virtual UserManager CreateManager(object context = null, IServiceCollection services = null) + { + if (services == null) + { + services = new ServiceCollection(); + } + if (context == null) + { + context = CreateTestContext(); + } + SetupIdentityServices(services, context); + return services.BuildServiceProvider().GetService>(); + } + + protected RoleManager CreateRoleManager(object context = null, IServiceCollection services = null) + { + if (services == null) + { + services = new ServiceCollection(); + } + if (context == null) + { + context = CreateTestContext(); + } + SetupIdentityServices(services, context); + return services.BuildServiceProvider().GetService>(); + } + protected abstract object CreateTestContext(); + protected abstract void AddUserStore(IServiceCollection services, object context = null); + protected abstract void AddRoleStore(IServiceCollection services, object context = null); + protected TUser CreateTestUser(string namePrefix = "") { return new TUser() { UserName = namePrefix + Guid.NewGuid().ToString() }; } @@ -551,9 +601,6 @@ namespace Microsoft.AspNet.Identity.Test public async Task ConfirmTokenFailsAfterPasswordChange() { var manager = CreateManager(); - manager.RegisterTokenProvider(new DataProtectorTokenProvider(new DataProtectionTokenProviderOptions(), - new EphemeralDataProtectionProvider().CreateProtector("ASP.NET Identity"))); - manager.Options.EmailConfirmationTokenProvider = "DataProtection"; var user = new TUser() { UserName = "test" }; Assert.False(user.EmailConfirmed); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, "password")); @@ -1144,8 +1191,7 @@ namespace Microsoft.AspNet.Identity.Test var manager = CreateManager(); var messageService = new TestMessageService(); manager.EmailService = messageService; - const string factorId = "Email"; - manager.RegisterTokenProvider(new EmailTokenProvider()); + const string factorId = "Email"; // default var user = new TUser() { UserName = "EmailCodeTest", Email = "foo@foo.com" }; user.EmailConfirmed = true; const string password = "password"; @@ -1176,18 +1222,20 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task EmailTokenFactorWithFormatTest() { - var manager = CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailTestCode"; + // CONSIDER: do we want to support multiple email token options? + const string factorId = "Email"; // default const string subject = "Custom subject"; const string body = "Your code is {0}!"; - manager.RegisterTokenProvider(new EmailTokenProvider(new EmailTokenProviderOptions + var services = new ServiceCollection(); + services.Configure(o => { - Name = factorId, - Subject = subject, - BodyFormat = body - })); + o.Name = factorId; + o.Subject = subject; + o.BodyFormat = body; + }); + var manager = CreateManager(null, services); + var messageService = new TestMessageService(); + manager.EmailService = messageService; var user = CreateTestUser(); user.Email = user.UserName + "@foo.com"; const string password = "password"; @@ -1209,7 +1257,6 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); string factorId = "Email"; //default - manager.RegisterTokenProvider(new EmailTokenProvider()); var user = CreateTestUser(); user.Email = user.UserName + "@foo.com"; user.EmailConfirmed = true; @@ -1222,7 +1269,6 @@ namespace Microsoft.AspNet.Identity.Test Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, token)); } - [Fact] public async Task EnableTwoFactorChangesSecurityStamp() { @@ -1272,7 +1318,6 @@ namespace Microsoft.AspNet.Identity.Test var messageService = new TestMessageService(); manager.SmsService = messageService; const string factorId = "Phone"; // default - manager.RegisterTokenProvider(new PhoneNumberTokenProvider()); var user = CreateTestUser(); user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); @@ -1290,15 +1335,16 @@ namespace Microsoft.AspNet.Identity.Test [Fact] public async Task PhoneTokenFactorFormatTest() { - var manager = CreateManager(); + const string factorId = "Phone"; // default + var services = new ServiceCollection(); + services.Configure(o => + { + o.Name = factorId; + o.MessageFormat = "Your code is: {0}"; + }); + var manager = CreateManager(null, services); var messageService = new TestMessageService(); manager.SmsService = messageService; - const string factorId = "PhoneTestFactors"; - manager.RegisterTokenProvider(new PhoneNumberTokenProvider(new PhoneNumberTokenProviderOptions - { - Name = factorId, - MessageFormat = "Your code is: {0}" - })); var user = CreateTestUser(); user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); @@ -1342,8 +1388,6 @@ namespace Microsoft.AspNet.Identity.Test public async Task CanGetValidTwoFactor() { var manager = CreateManager(); - manager.RegisterTokenProvider(new PhoneNumberTokenProvider()); - manager.RegisterTokenProvider(new EmailTokenProvider()); var user = CreateTestUser(); IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); var factors = await manager.GetValidTwoFactorProvidersAsync(user); @@ -1374,7 +1418,6 @@ namespace Microsoft.AspNet.Identity.Test { var manager = CreateManager(); var factorId = "Phone"; // default - manager.RegisterTokenProvider(new PhoneNumberTokenProvider()); var user = CreateTestUser(); user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); @@ -1390,8 +1433,6 @@ namespace Microsoft.AspNet.Identity.Test public async Task VerifyTokenFromWrongTokenProviderFails() { var manager = CreateManager(); - manager.RegisterTokenProvider(new PhoneNumberTokenProvider()); - manager.RegisterTokenProvider(new EmailTokenProvider()); var user = CreateTestUser(); user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user)); @@ -1404,7 +1445,6 @@ namespace Microsoft.AspNet.Identity.Test public async Task VerifyWithWrongSmsTokenFails() { var manager = CreateManager(); - manager.RegisterTokenProvider(new PhoneNumberTokenProvider()); var user = CreateTestUser(); user.PhoneNumber = "4251234567"; IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));