From 2e864c32fa545ef77848ecaad9916b87399a24bc Mon Sep 17 00:00:00 2001 From: "nicolas.dorier" Date: Fri, 12 Feb 2021 12:21:29 +0900 Subject: [PATCH] Profile email change should check email's availability --- BTCPayServer.Tests/README.md | 9 ++++ BTCPayServer.Tests/SeleniumTester.cs | 15 +++++-- BTCPayServer.Tests/SeleniumTests.cs | 41 +++++++++++++++++++ BTCPayServer/Controllers/ManageController.cs | 34 +++++---------- .../Models/ManageViewModels/IndexViewModel.cs | 5 --- BTCPayServer/Views/Manage/Index.cshtml | 4 +- 6 files changed, 74 insertions(+), 34 deletions(-) diff --git a/BTCPayServer.Tests/README.md b/BTCPayServer.Tests/README.md index dd66ebc7f..f0b8d4224 100644 --- a/BTCPayServer.Tests/README.md +++ b/BTCPayServer.Tests/README.md @@ -74,3 +74,12 @@ If you still have issues, try to restart docker. Run `dotnet user-secrets set RunSeleniumInBrowser true` to run tests in browser. To switch back to headless mode (recommended) you can run `dotnet user-secrets remove RunSeleniumInBrowser`. + +### Session not created: This version of ChromeDriver only supports Chrome version 88 + +When you run tests for selenium, you may end up with this error. +This happen when we update the selenium packages on BTCPay Server while you did not update your chrome version. + +If you want to use a older chrome driver on [this page](https://chromedriver.chromium.org/downloads) then point to it with + +`dotnet user-secrets set ChromeDriverDirectory "path/to/the/driver/directory"` diff --git a/BTCPayServer.Tests/SeleniumTester.cs b/BTCPayServer.Tests/SeleniumTester.cs index 6dff08de5..63876bb00 100644 --- a/BTCPayServer.Tests/SeleniumTester.cs +++ b/BTCPayServer.Tests/SeleniumTester.cs @@ -46,6 +46,10 @@ namespace BTCPayServer.Tests var runInBrowser = config["RunSeleniumInBrowser"] == "true"; // Reset this using `dotnet user-secrets remove RunSeleniumInBrowser` + + var chromeDriverPath = config["ChromeDriverDirectory"] ?? + (Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory()); + var options = new ChromeOptions(); if (Server.PayTester.InContainer) { @@ -58,7 +62,7 @@ namespace BTCPayServer.Tests } options.AddArguments($"window-size={windowSize.Width}x{windowSize.Height}"); options.AddArgument("shm-size=2g"); - Driver = new ChromeDriver(Server.PayTester.InContainer ? "/usr/bin" : Directory.GetCurrentDirectory(), options); + Driver = new ChromeDriver(chromeDriverPath, options); if (runInBrowser) { @@ -74,8 +78,13 @@ namespace BTCPayServer.Tests Driver.AssertNoError(); } - internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success) => - Driver.FindElement(By.ClassName($"alert-{StatusMessageModel.ToString(severity)}")); + internal IWebElement FindAlertMessage(StatusMessageModel.StatusSeverity severity = StatusMessageModel.StatusSeverity.Success) + { + var el = Driver.FindElements(By.ClassName($"alert-{StatusMessageModel.ToString(severity)}")).FirstOrDefault(e => e.Displayed); + if (el is null) + throw new NoSuchElementException($"Unable to find alert-{StatusMessageModel.ToString(severity)}"); + return el; + } public static readonly TimeSpan ImplicitWait = TimeSpan.FromSeconds(5); public string Link(string relativeLink) diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 44fdb85ef..e9183f8d8 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -9,8 +9,10 @@ using BTCPayServer.Client.Models; using BTCPayServer.Data; using BTCPayServer.Services.Wallets; using BTCPayServer.Tests.Logging; +using BTCPayServer.Views.Manage; using BTCPayServer.Views.Server; using BTCPayServer.Views.Wallets; +using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using NBitcoin; using NBitcoin.DataEncoders; @@ -87,6 +89,45 @@ namespace BTCPayServer.Tests } } + [Fact(Timeout = TestTimeout)] + [Trait("Selenium", "Selenium")] + public async Task CanChangeUserMail() + { + using (var s = SeleniumTester.Create()) + { + await s.StartAsync(); + + var tester = s.Server; + var u1 = tester.NewAccount(); + u1.GrantAccess(); + await u1.MakeAdmin(false); + + var u2 = tester.NewAccount(); + u2.GrantAccess(); + await u2.MakeAdmin(false); + + s.GoToLogin(); + s.Login(u1.RegisterDetails.Email, u1.RegisterDetails.Password); + s.GoToProfile(ManageNavPages.Index); + s.Driver.FindElement(By.Id("Email")).Clear(); + s.Driver.FindElement(By.Id("Email")).SendKeys(u2.RegisterDetails.Email); + s.Driver.FindElement(By.Id("save")).Click(); + + s.FindAlertMessage(Abstractions.Models.StatusMessageModel.StatusSeverity.Error); + + s.GoToProfile(ManageNavPages.Index); + s.Driver.FindElement(By.Id("Email")).Clear(); + var changedEmail = Guid.NewGuid() + "@lol.com"; + s.Driver.FindElement(By.Id("Email")).SendKeys(changedEmail); + s.Driver.FindElement(By.Id("save")).Click(); + s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success); + + var manager = tester.PayTester.GetService>(); + Assert.NotNull(await manager.FindByNameAsync(changedEmail)); + Assert.NotNull(await manager.FindByEmailAsync(changedEmail)); + } + } + [Fact(Timeout = TestTimeout)] public async Task NewUserLogin() { diff --git a/BTCPayServer/Controllers/ManageController.cs b/BTCPayServer/Controllers/ManageController.cs index ab8187ac4..556e441bb 100644 --- a/BTCPayServer/Controllers/ManageController.cs +++ b/BTCPayServer/Controllers/ManageController.cs @@ -82,7 +82,6 @@ namespace BTCPayServer.Controllers { Username = user.UserName, Email = user.Email, - PhoneNumber = user.PhoneNumber, IsEmailConfirmed = user.EmailConfirmed }; return View(model); @@ -97,8 +96,6 @@ namespace BTCPayServer.Controllers return View(model); } - bool needUpdate = false; - var user = await _userManager.GetUserAsync(User); if (user == null) { @@ -108,33 +105,22 @@ namespace BTCPayServer.Controllers var email = user.Email; if (model.Email != email) { + if (!(await _userManager.FindByEmailAsync(model.Email) is null)) + { + TempData[WellKnownTempData.ErrorMessage] = "This email already exists"; + return RedirectToAction(nameof(Index)); + } + var setUserResult = await _userManager.SetUserNameAsync(user, model.Email); + if (!setUserResult.Succeeded) + { + throw new ApplicationException($"Unexpected error occurred setting email for user with ID '{user.Id}'."); + } var setEmailResult = await _userManager.SetEmailAsync(user, model.Email); if (!setEmailResult.Succeeded) { throw new ApplicationException($"Unexpected error occurred setting email for user with ID '{user.Id}'."); } - await _userManager.SetUserNameAsync(user, model.Username); } - - var phoneNumber = user.PhoneNumber; - if (model.PhoneNumber != phoneNumber) - { - var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, model.PhoneNumber); - if (!setPhoneResult.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred setting phone number for user with ID '{user.Id}'."); - } - } - - if (needUpdate) - { - var result = await _userManager.UpdateAsync(user); - if (!result.Succeeded) - { - throw new ApplicationException($"Unexpected error occurred updating user with ID '{user.Id}'."); - } - } - TempData[WellKnownTempData.SuccessMessage] = "Your profile has been updated"; return RedirectToAction(nameof(Index)); } diff --git a/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs b/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs index 643b0a88f..c85ce882b 100644 --- a/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs +++ b/BTCPayServer/Models/ManageViewModels/IndexViewModel.cs @@ -17,10 +17,5 @@ namespace BTCPayServer.Models.ManageViewModels public bool IsEmailConfirmed { get; set; } - [Phone] - [Display(Name = "Phone number")] - [MaxLength(50)] - public string PhoneNumber { get; set; } - } } diff --git a/BTCPayServer/Views/Manage/Index.cshtml b/BTCPayServer/Views/Manage/Index.cshtml index 65146ccdc..7f0fbbcf1 100644 --- a/BTCPayServer/Views/Manage/Index.cshtml +++ b/BTCPayServer/Views/Manage/Index.cshtml @@ -1,4 +1,4 @@ -@model IndexViewModel +@model IndexViewModel @{ ViewData.SetActivePageAndTitle(ManageNavPages.Index, "Profile"); } @@ -41,7 +41,7 @@ } - + @section Scripts {