[Fixes #1639] Reset password doesn't work
This commit is contained in:
parent
2511862a77
commit
3e30d52055
|
|
@ -36,7 +36,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<a asp-page="./ForgotPassword">Forgot your password?</a>
|
||||
<a id="forgot-password" asp-page="./ForgotPassword">Forgot your password?</a>
|
||||
</p>
|
||||
<p>
|
||||
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
|||
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
|
||||
public string ConfirmPassword { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Code { get; set; }
|
||||
|
||||
public virtual IActionResult OnGet(string code = null) => throw new NotImplementedException();
|
||||
|
||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||
}
|
||||
public virtual IActionResult OnGet(string code = null) => throw new NotImplementedException();
|
||||
|
||||
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal class ResetPasswordModel<TUser> : ResetPasswordModel where TUser : IdentityUser
|
||||
|
|
@ -48,7 +49,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
|||
_userManager = userManager;
|
||||
}
|
||||
|
||||
public IActionResult OnGet(string code = null)
|
||||
public override IActionResult OnGet(string code = null)
|
||||
{
|
||||
if (code == null)
|
||||
{
|
||||
|
|
@ -64,7 +65,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostAsync()
|
||||
public override async Task<IActionResult> OnPostAsync()
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -145,5 +145,32 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
await UserStories.RegisterNewUserWithSocialLoginAsync(client, userName, email);
|
||||
await UserStories.LoginWithSocialLoginAsync(newClient, userName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanLogInAfterResettingThePassword()
|
||||
{
|
||||
// Arrange
|
||||
var emailSender = new ContosoEmailSender();
|
||||
var server = ServerFactory.CreateServer(b => b.ConfigureServices(s =>
|
||||
s.SetupTestEmailSender(emailSender)));
|
||||
var client = ServerFactory.CreateDefaultClient(server);
|
||||
var resetPasswordClient = ServerFactory.CreateDefaultClient(server);
|
||||
var newClient = ServerFactory.CreateDefaultClient(server);
|
||||
|
||||
var userName = $"{Guid.NewGuid()}@example.com";
|
||||
var password = $"!Test.Password1$";
|
||||
var newPassword = $"!New.Password1$";
|
||||
|
||||
await UserStories.RegisterNewUserAsync(client, userName, password);
|
||||
var registrationEmail = Assert.Single(emailSender.SentEmails);
|
||||
await UserStories.ConfirmEmailAsync(registrationEmail, client);
|
||||
|
||||
// Act & Assert
|
||||
await UserStories.ForgotPasswordAsync(resetPasswordClient, userName);
|
||||
Assert.Equal(2, emailSender.SentEmails.Count);
|
||||
var email = emailSender.SentEmails[1];
|
||||
await UserStories.ResetPasswordAsync(resetPasswordClient, email, userName, newPassword);
|
||||
await UserStories.LoginExistingUserAsync(newClient, userName, newPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom.Html;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
||||
{
|
||||
public class ForgotPassword : DefaultUIPage
|
||||
{
|
||||
private readonly IHtmlFormElement _forgotPasswordForm;
|
||||
|
||||
public ForgotPassword(HttpClient client, IHtmlDocument document, DefaultUIContext context) : base(client, document, context)
|
||||
{
|
||||
_forgotPasswordForm = HtmlAssert.HasForm(document);
|
||||
}
|
||||
|
||||
public async Task<ForgotPasswordConfirmation> SendForgotPasswordAsync(string email)
|
||||
{
|
||||
var response = await Client.SendAsync(_forgotPasswordForm, new Dictionary<string, string>
|
||||
{
|
||||
["Input_Email"] = email
|
||||
});
|
||||
var goToForgotPasswordConfirmation = ResponseAssert.IsRedirect(response);
|
||||
var forgotPasswordConfirmationResponse = await Client.GetAsync(goToForgotPasswordConfirmation);
|
||||
var forgotPasswordConfirmation = await ResponseAssert.IsHtmlDocumentAsync(forgotPasswordConfirmationResponse);
|
||||
|
||||
return new ForgotPasswordConfirmation(Client, forgotPasswordConfirmation, Context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using AngleSharp.Dom.Html;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
||||
{
|
||||
public class ForgotPasswordConfirmation : DefaultUIPage
|
||||
{
|
||||
public ForgotPasswordConfirmation(HttpClient client, IHtmlDocument document, DefaultUIContext context) : base(client, document, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom.Html;
|
||||
using Microsoft.AspNetCore.Identity.FunctionalTests.Pages.Account;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
||||
|
|
@ -12,6 +13,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
|||
public class Login : DefaultUIPage
|
||||
{
|
||||
private readonly IHtmlFormElement _loginForm;
|
||||
private readonly IHtmlAnchorElement _forgotPasswordLink;
|
||||
private readonly IHtmlFormElement _externalLoginForm;
|
||||
private readonly IHtmlElement _contosoButton;
|
||||
|
||||
|
|
@ -22,6 +24,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
|||
: base(client, login, context)
|
||||
{
|
||||
_loginForm = HtmlAssert.HasForm("#account", login);
|
||||
_forgotPasswordLink = HtmlAssert.HasLink("#forgot-password", login);
|
||||
if (Context.ContosoLoginEnabled)
|
||||
{
|
||||
_externalLoginForm = HtmlAssert.HasForm("#external-account", login);
|
||||
|
|
@ -40,6 +43,14 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account
|
|||
return new Contoso.Login(Client, contosoLogin, Context);
|
||||
}
|
||||
|
||||
public async Task<ForgotPassword> ClickForgotPasswordLinkAsync()
|
||||
{
|
||||
var response = await Client.GetAsync(_forgotPasswordLink.Href);
|
||||
var forgotPassword = await ResponseAssert.IsHtmlDocumentAsync(response);
|
||||
|
||||
return new ForgotPassword(Client, forgotPassword, Context);
|
||||
}
|
||||
|
||||
public async Task<Index> LoginValidUserAsync(string userName, string password)
|
||||
{
|
||||
var loggedIn = await SendLoginForm(userName, password);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom.Html;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.FunctionalTests.Pages.Account
|
||||
{
|
||||
public class ResetPassword : DefaultUIPage
|
||||
{
|
||||
private readonly IHtmlFormElement _resetPasswordForm;
|
||||
|
||||
public ResetPassword(HttpClient client, IHtmlDocument resetPassword, DefaultUIContext context) : base(client, resetPassword, context)
|
||||
{
|
||||
_resetPasswordForm = HtmlAssert.HasForm(resetPassword);
|
||||
}
|
||||
|
||||
internal static async Task<ResetPassword> CreateAsync(IHtmlAnchorElement link, HttpClient client, DefaultUIContext context)
|
||||
{
|
||||
var resetPasswordResponse = await client.GetAsync(link.Href);
|
||||
var resetPassword = await ResponseAssert.IsHtmlDocumentAsync(resetPasswordResponse);
|
||||
|
||||
return new ResetPassword(client, resetPassword, context);
|
||||
}
|
||||
|
||||
public async Task<ResetPasswordConfirmation> SendNewPasswordAsync(string email, string newPassword)
|
||||
{
|
||||
var resetPasswordResponse = await Client.SendAsync(_resetPasswordForm, new Dictionary<string, string>
|
||||
{
|
||||
["Input_Email"] = email,
|
||||
["Input_Password"] = newPassword,
|
||||
["Input_ConfirmPassword"] = newPassword
|
||||
});
|
||||
|
||||
var goToResetPasswordConfirmation = ResponseAssert.IsRedirect(resetPasswordResponse);
|
||||
var resetPasswordConfirmationResponse = await Client.GetAsync(goToResetPasswordConfirmation);
|
||||
var resetPasswordConfirmation = await ResponseAssert.IsHtmlDocumentAsync(resetPasswordConfirmationResponse);
|
||||
|
||||
return new ResetPasswordConfirmation(Client, resetPasswordConfirmation, Context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System.Net.Http;
|
||||
using AngleSharp.Dom.Html;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.FunctionalTests.Pages.Account
|
||||
{
|
||||
public class ResetPasswordConfirmation : DefaultUIPage
|
||||
{
|
||||
public ResetPasswordConfirmation(HttpClient client, IHtmlDocument resetPasswordConfirmation, DefaultUIContext context)
|
||||
: base(client, resetPasswordConfirmation, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using System.Net.Http;
|
|||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom.Html;
|
||||
using Identity.DefaultUI.WebSite.Services;
|
||||
using Microsoft.AspNetCore.Identity.FunctionalTests.Account;
|
||||
using Microsoft.AspNetCore.Identity.FunctionalTests.Account.Manage;
|
||||
using Microsoft.AspNetCore.Identity.FunctionalTests.Pages.Account;
|
||||
using Xunit;
|
||||
|
|
@ -36,7 +37,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
|
||||
internal static async Task<Index> RegisterNewUserWithSocialLoginAsync(HttpClient client, string userName, string email)
|
||||
{
|
||||
var index = await Index.CreateAsync(client,new DefaultUIContext().WithSocialLoginEnabled());
|
||||
var index = await Index.CreateAsync(client, new DefaultUIContext().WithSocialLoginEnabled());
|
||||
|
||||
var login = await index.ClickLoginLinkAsync();
|
||||
|
||||
|
|
@ -114,5 +115,26 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests
|
|||
.WithExistingUser()
|
||||
.WithConfirmedEmail());
|
||||
}
|
||||
|
||||
internal static async Task<ForgotPasswordConfirmation> ForgotPasswordAsync(HttpClient client, string userName)
|
||||
{
|
||||
var index = await Index.CreateAsync(client);
|
||||
|
||||
var login = await index.ClickLoginLinkAsync();
|
||||
|
||||
var forgotPassword = await login.ClickForgotPasswordLinkAsync();
|
||||
|
||||
return await forgotPassword.SendForgotPasswordAsync(userName);
|
||||
}
|
||||
|
||||
internal static async Task<ResetPasswordConfirmation> ResetPasswordAsync(HttpClient client, IdentityEmail resetPasswordEmail, string email, string newPassword)
|
||||
{
|
||||
var emailBody = HtmlAssert.IsHtmlFragment(resetPasswordEmail.Body);
|
||||
var linkElement = HtmlAssert.HasElement("a", emailBody);
|
||||
var link = Assert.IsAssignableFrom<IHtmlAnchorElement>(linkElement);
|
||||
|
||||
var resetPassword = await ResetPassword.CreateAsync(link, client, new DefaultUIContext().WithExistingUser());
|
||||
return await resetPassword.SendNewPasswordAsync(email, newPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue