// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder.Internal; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity.Test; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; namespace Microsoft.AspNetCore.Identity.InMemory.Test { public class ControllerTest { [Theory] [InlineData(true)] [InlineData(false)] public async Task VerifyAccountControllerSignIn(bool isPersistent) { var context = new DefaultHttpContext(); var auth = MockAuth(context); auth.Setup(a => a.SignInAsync(context, IdentityConstants.ApplicationScheme, It.IsAny(), It.IsAny())).Returns(Task.FromResult(0)).Verifiable(); // REVIEW: is persistant mocking broken //It.Is(v => v.IsPersistent == isPersistent))).Returns(Task.FromResult(0)).Verifiable(); var contextAccessor = new Mock(); contextAccessor.Setup(a => a.HttpContext).Returns(context); var services = new ServiceCollection() .AddSingleton(new ConfigurationBuilder().Build()) .AddLogging() .AddSingleton(contextAccessor.Object); services.AddIdentity(); services.AddSingleton, InMemoryStore>(); services.AddSingleton, InMemoryStore>(); var app = new ApplicationBuilder(services.BuildServiceProvider()); // Act var user = new TestUser { UserName = "Yolo" }; const string password = "Yol0Sw@g!"; var userManager = app.ApplicationServices.GetRequiredService>(); var signInManager = app.ApplicationServices.GetRequiredService>(); IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password)); var result = await signInManager.PasswordSignInAsync(user, password, isPersistent, false); // Assert Assert.True(result.Succeeded); auth.VerifyAll(); contextAccessor.VerifyAll(); } [Fact] public async Task VerifyAccountControllerExternalLoginWithTokensFlow() { // Setup the external cookie like it would look from a real OAuth2 var externalId = ""; var authScheme = ""; var externalIdentity = new ClaimsIdentity(); externalIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, externalId)); var externalPrincipal = new ClaimsPrincipal(externalIdentity); var externalLogin = new ExternalLoginInfo(externalPrincipal, authScheme, externalId, "displayname") { AuthenticationTokens = new[] { new AuthenticationToken { Name = "refresh_token", Value = "refresh" }, new AuthenticationToken { Name = "access_token", Value = "access" } } }; var context = new DefaultHttpContext(); var auth = MockAuth(context); auth.Setup(a => a.AuthenticateAsync(context, It.IsAny())).Returns(Task.FromResult(AuthenticateResult.NoResult())); var contextAccessor = new Mock(); contextAccessor.Setup(a => a.HttpContext).Returns(context); var services = new ServiceCollection() .AddSingleton(new ConfigurationBuilder().Build()) .AddLogging() .AddSingleton(contextAccessor.Object); services.AddIdentity(); services.AddSingleton, InMemoryStore>(); services.AddSingleton, InMemoryStore>(); var app = new ApplicationBuilder(services.BuildServiceProvider()); // Act var user = new TestUser { UserName = "Yolo" }; var userManager = app.ApplicationServices.GetRequiredService>(); var signInManager = app.ApplicationServices.GetRequiredService>(); IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await userManager.AddLoginAsync(user, new UserLoginInfo(authScheme, externalId, "whatever"))); IdentityResultAssert.IsSuccess(await signInManager.UpdateExternalAuthenticationTokensAsync(externalLogin)); Assert.Equal("refresh", await userManager.GetAuthenticationTokenAsync(user, authScheme, "refresh_token")); Assert.Equal("access", await userManager.GetAuthenticationTokenAsync(user, authScheme, "access_token")); } private Mock MockAuth(HttpContext context) { var auth = new Mock(); context.RequestServices = new ServiceCollection().AddSingleton(auth.Object).BuildServiceProvider(); return auth; } } }