Fix external login registration when RequireConfirmedAccount (#11572)

This commit is contained in:
Hao Kung 2019-06-25 17:51:43 -07:00 committed by GitHub
parent 921dd947b9
commit dc954e1936
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 6 deletions

View File

@ -193,9 +193,15 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
result = await _userManager.AddLoginAsync(user, info); result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded) if (result.Succeeded)
{ {
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email });
}
await _signInManager.SignInAsync(user, isPersistent: false);
var userId = await _userManager.GetUserIdAsync(user); var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Page( var callbackUrl = Url.Page(

View File

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
{ {
@ -192,9 +193,15 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
result = await _userManager.AddLoginAsync(user, info); result = await _userManager.AddLoginAsync(user, info);
if (result.Succeeded) if (result.Succeeded)
{ {
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
// If account confirmation is required, we need to show the link if we don't have a real email sender
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email });
}
await _signInManager.SignInAsync(user, isPersistent: false);
var userId = await _userManager.GetUserIdAsync(user); var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Page( var callbackUrl = Url.Page(

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@ -35,11 +36,24 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
{ {
["Input_Email"] = email ["Input_Email"] = email
}); });
var goToIndex = ResponseAssert.IsRedirect(response); var redirect = ResponseAssert.IsRedirect(response);
var indexResponse = await Client.GetAsync(goToIndex); var indexResponse = await Client.GetAsync(redirect);
var index = await ResponseAssert.IsHtmlDocumentAsync(indexResponse); var index = await ResponseAssert.IsHtmlDocumentAsync(indexResponse);
return new Index(Client, index, Context.WithAuthenticatedUser()); return new Index(Client, index, Context.WithAuthenticatedUser());
} }
public async Task<RegisterConfirmation> SendEmailWithConfirmationAsync(string email, bool hasRealEmail)
{
var response = await Client.SendAsync(_emailForm, new Dictionary<string, string>
{
["Input_Email"] = email
});
var redirect = ResponseAssert.IsRedirect(response);
Assert.True(String.Equals(RegisterConfirmation.Path + "?email=" + email, redirect.ToString(), StringComparison.OrdinalIgnoreCase));
var registerResponse = await Client.GetAsync(redirect);
var register = await ResponseAssert.IsHtmlDocumentAsync(registerResponse);
return new RegisterConfirmation(Client, register, hasRealEmail ? Context.WithRealEmailSender() : Context);
}
} }
} }

View File

@ -129,6 +129,52 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email); await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email);
} }
[Fact]
public async Task CanRegisterWithASocialLoginProviderFromLoginWithConfirmation()
{
// Arrange
void ConfigureTestServices(IServiceCollection services)
{
services.Configure<IdentityOptions>(o => o.SignIn.RequireConfirmedAccount = true)
.SetupTestThirdPartyLogin();
}
var client = ServerFactory
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
var guid = Guid.NewGuid();
var userName = $"{guid}";
var email = $"{guid}@example.com";
// Act & Assert
await UserStories.RegisterNewUserWithSocialLoginWithConfirmationAsync(client, userName, email);
}
[Fact]
public async Task CanRegisterWithASocialLoginProviderFromLoginWithConfirmationAndRealEmailSender()
{
// Arrange
void ConfigureTestServices(IServiceCollection services)
{
services.AddSingleton<IEmailSender, FakeEmailSender>();
services
.Configure<IdentityOptions>(o => o.SignIn.RequireConfirmedAccount = true)
.SetupTestThirdPartyLogin();
}
var client = ServerFactory
.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices))
.CreateClient();
var guid = Guid.NewGuid();
var userName = $"{guid}";
var email = $"{guid}@example.com";
// Act & Assert
await UserStories.RegisterNewUserWithSocialLoginWithConfirmationAsync(client, userName, email, hasRealEmailSender: true);
}
[Fact] [Fact]
public async Task CanRegisterWithASocialLoginProviderFromRegister() public async Task CanRegisterWithASocialLoginProviderFromRegister()
{ {

View File

@ -80,6 +80,19 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
return await externalLogin.SendEmailAsync(email); return await externalLogin.SendEmailAsync(email);
} }
internal static async Task<RegisterConfirmation> RegisterNewUserWithSocialLoginWithConfirmationAsync(HttpClient client, string userName, string email, bool hasRealEmailSender = false)
{
var index = await Index.CreateAsync(client, new DefaultUIContext().WithSocialLoginEnabled());
var login = await index.ClickLoginLinkAsync();
var contosoLogin = await login.ClickLoginWithContosoLinkAsync();
var externalLogin = await contosoLogin.SendNewUserNameAsync(userName);
return await externalLogin.SendEmailWithConfirmationAsync(email, hasRealEmailSender);
}
internal static async Task<Index> RegisterNewUserWithSocialLoginAsyncViaRegisterPage(HttpClient client, string userName, string email) internal static async Task<Index> RegisterNewUserWithSocialLoginAsyncViaRegisterPage(HttpClient client, string userName, string email)
{ {
var index = await Index.CreateAsync(client, new DefaultUIContext().WithSocialLoginEnabled()); var index = await Index.CreateAsync(client, new DefaultUIContext().WithSocialLoginEnabled());