public async Task <ActionResult> ValidateEmail(string id, string t) { if (id == null || t == null) { Log.Warn(LogTag.EmailValidationMissingParams, Request, new { aspNetUserId = id, encodedToken = t }); return(View(new EmailConfirmationViewModel())); } using (_db) { //Andriy: decodedExtendedToken has format "token:email" string decodedExtendedToken = EmailConfirmationHelper.TokenDecode(t); string[] compositeToken = decodedExtendedToken.Split(':'); AspNetUser aspNetUser = await UserManager.FindByIdAsync(id); if (!compositeToken[1].Equals(aspNetUser.Email, StringComparison.InvariantCulture)) { Log.Warn(LogTag.EmailValidationWrongEmail, Request, new { aspNetUserId = id, decodedToken = compositeToken[0], email = compositeToken[1] }); return(View(new EmailConfirmationViewModel())); } if (aspNetUser.EmailConfirmed) { Log.Warn(LogTag.EmailValidationIsAlreadyDone, Request, new { aspNetUserId = id, encodedToken = t }); await SignInManager.SignInAsync(aspNetUser, false, false); return(View(new EmailConfirmationViewModel { isSuccess = true })); } string securityToken = compositeToken[0]; var result = await UserManager.ConfirmEmailAsync(id, securityToken); if (result.Succeeded) { User user = await _db.Users.FindAsync(aspNetUser.Users.FirstOrDefault()?.Id); user.StatusId = UserStatuses.Valid; try { await _db.SaveChangesAsync(); } catch (Exception ex) { Log.Error(LogTag.SaveUserEmailConfirmedStatusError, ex, new { UserId = user.Id }); return(View(new EmailConfirmationViewModel())); } // Sign anyone out and sign the new user in await SignInManager.SignInAsync(aspNetUser, false, false); return(View(new EmailConfirmationViewModel { isSuccess = true })); } Log.Error(LogTag.EmailValidationFailed, Request, new { userId = id, errors = string.Join(";", result?.Errors), tokenFromEmail = t, decodedToken = decodedExtendedToken }); return(View(new EmailConfirmationViewModel())); } }
public async Task ConfirmationEmailStatusUpdateFailedTest() { string aspNetUserId = "123"; int userId = 5; string token = "token"; string email = "*****@*****.**"; string composedToken = $"{token}:{email}"; string encodedToken = EmailConfirmationHelper.TokenEncode(composedToken); string decodedToken = EmailConfirmationHelper.TokenDecode(encodedToken); List <User> userData = new List <User>() { new User() { Id = userId, StatusId = UserStatuses.PendingEmailValidation } }; AspNetUser aspNetUser = new AspNetUser() { Id = aspNetUserId, Email = email, Users = new List <User>() { new User() { Id = userId } } }; var entitiesMock = GetEntitiesMockForEmailValidationTests(userData); entitiesMock.Setup(e => e.SaveChangesAsync()) .Callback(() => { userData.FirstOrDefault().StatusId = UserStatuses.PendingEmailValidation; }) .Throws(new Exception("Saving is failed.")); var userManagerMock = GetApplicationUserManagerMock(new Mock <IUserStore <AspNetUser, string> >()); var signInManagerMock = GetSignInManagerMock(userManagerMock, GetAuthenticationManagerMock()); userManagerMock.Setup(m => m.FindByIdAsync(It.Is <string>((id) => id == aspNetUserId))).ReturnsAsync(aspNetUser); userManagerMock.Setup(m => m.ConfirmEmailAsync(It.Is <string>((id) => id == aspNetUserId), It.Is <string>((t) => t == token))) .ReturnsAsync(new IdentityResult()); AccountController controller = new AccountController(entitiesMock.Object, userManagerMock.Object, signInManagerMock.Object, new Mock <IEmailSender>().Object); controller.ControllerContext = GetDefaultAccountControllerRequest(controller); //Act ActionResult result = await controller.ValidateEmail(aspNetUserId, encodedToken); //Assert ViewResult viewResult = (ViewResult)result; Assert.AreEqual(composedToken, decodedToken); Assert.AreEqual("", viewResult.ViewName); Assert.AreEqual(userData.FirstOrDefault()?.StatusId, UserStatuses.PendingEmailValidation); }
public async Task ConfirmationEmailTest() { string aspNetUserId = "123"; int userId = 5; string token = "token"; string email = "*****@*****.**"; string composedToken = $"{token}:{email}"; string encodedToken = EmailConfirmationHelper.TokenEncode(composedToken); string decodedToken = EmailConfirmationHelper.TokenDecode(encodedToken); List <User> usertData = new List <User>() { new User() { Id = userId, StatusId = UserStatuses.PendingEmailValidation } }; AspNetUser aspNetUser = new AspNetUser() { Id = aspNetUserId, Email = email, Users = new List <User>() { new User() { Id = userId } } }; var entitiesMock = GetEntitiesMock(); var userManagerMock = GetApplicationUserManagerMock(new Mock <IUserStore <AspNetUser, string> >()); var signInManagerMock = GetSignInManagerMock(userManagerMock, GetAuthenticationManagerMock()); var usersDbSetMock = GetUsersDbSetMock(usertData); usersDbSetMock.Setup(u => u.FindAsync(It.Is <int>((id) => id == userId))).ReturnsAsync(usertData [0]); entitiesMock.Setup(e => e.Users).Returns(usersDbSetMock.Object); entitiesMock.Setup(e => e.SaveChangesAsync()).ReturnsAsync(0).Verifiable(); userManagerMock.Setup(m => m.FindByIdAsync(It.Is <string>((id) => id == aspNetUserId))).ReturnsAsync(aspNetUser); userManagerMock.Setup(m => m.ConfirmEmailAsync(It.Is <string>((id) => id == aspNetUserId), It.Is <string>((t) => t == token))) .ReturnsAsync(IdentityResult.Success); //Act AccountController controller = new AccountController(entitiesMock.Object, userManagerMock.Object, signInManagerMock.Object, new Mock <IEmailSender>().Object); ActionResult result = await controller.ValidateEmail(aspNetUserId, encodedToken); //Assert ViewResult viewResult = (ViewResult)result; Assert.AreEqual(composedToken, decodedToken); Assert.AreEqual((( EmailConfirmationViewModel )viewResult.Model).isSuccess, true); Assert.AreEqual(usertData.FirstOrDefault()?.StatusId, UserStatuses.Valid); entitiesMock.Verify(); }
public async Task ConfirmationEmailWrongUserEmailFailedTest() { string aspNetUserId = "123"; int userId = 5; string token = "token"; string email = "*****@*****.**"; string newEmail = "*****@*****.**"; string composedToken = $"{token}:{email}"; string encodedToken = EmailConfirmationHelper.TokenEncode(composedToken); string decodedToken = EmailConfirmationHelper.TokenDecode(encodedToken); List <User> userData = new List <User>() { new User() { Id = userId, StatusId = UserStatuses.PendingEmailValidation } }; AspNetUser aspNetUser = new AspNetUser() { Id = aspNetUserId, Email = newEmail, Users = new List <User>() { new User() { Id = userId } } }; var entitiesMock = GetEntitiesMockForEmailValidationTests(userData); var userManagerMock = GetApplicationUserManagerMock(new Mock <IUserStore <AspNetUser, string> >()); var signInManagerMock = GetSignInManagerMock(userManagerMock, GetAuthenticationManagerMock()); userManagerMock.Setup(m => m.FindByIdAsync(It.Is <string>((id) => id == aspNetUserId))).ReturnsAsync(aspNetUser); userManagerMock.Setup(m => m.ConfirmEmailAsync(It.Is <string>((id) => id == aspNetUserId), It.Is <string>((t) => t == decodedToken))) .ReturnsAsync(new IdentityResult()); AccountController controller = new AccountController(entitiesMock.Object, userManagerMock.Object, signInManagerMock.Object, new Mock <IEmailSender>().Object); controller.ControllerContext = GetDefaultAccountControllerRequest(controller); //Act ActionResult result = await controller.ValidateEmail(aspNetUserId, encodedToken); //Assert ViewResult viewResult = (ViewResult)result; Assert.AreEqual(composedToken, decodedToken); Assert.AreEqual((( EmailConfirmationViewModel )viewResult.Model).isSuccess, false); Assert.AreEqual(userData.FirstOrDefault()?.StatusId, UserStatuses.PendingEmailValidation); userManagerMock.Verify(m => m.ConfirmEmailAsync(It.Is <string>((id) => id == aspNetUserId), It.Is <string>((t) => t == token)), Times.Never); }
private async Task <string> GetEmailConfirmUrl(string aspNetUserId, string email) { //Andriy: we can't use token as parameter safe without such encoding, please look here: //http://stackoverflow.com/questions/28750480/aspnet-identit-2-1-0-confirmemailasync-always-returns-invalid-token string emailTtoken = await UserManager.GenerateEmailConfirmationTokenAsync(aspNetUserId); string extendedToken = $"{emailTtoken}:{email}"; string encodedToken = EmailConfirmationHelper.TokenEncode(extendedToken); string scheme = Request.RequestUri.Scheme; string host = Request.RequestUri.Host; string port = Request.RequestUri.Port != 80 ? $":{Request.RequestUri.Port}":null; string emailConfirmUrl = $"{scheme}://{host}{port}/validate-email?id={aspNetUserId}&t={encodedToken}"; return(emailConfirmUrl); }
public async Task <ActionResult> ConfirmationLink(string id) { //decode the confirmation token var token = EmailConfirmationHelper.DecodeConfirmationToken(id); //find the user based on the email address var user = await _userManager.FindByNameAsync(token.Email); if (user != null) { //check if the user has already confirmed their account if (user.IsConfirmed) { ViewBag.MessageTitle = "Already Confirmed"; ViewBag.Message = "Your account is already confirmed!"; return(View()); } //check if the confirmation token is older than a day, if it is send them a new token if ((DateTime.UtcNow - user.CreatedDate).TotalDays > 1) { await ResendConfirmationToken(user); ViewBag.MessageTitle = "Token Expired"; ViewBag.MessageTitle = "The confirmation token has expired. A new token has been generated and emailed to you."; return(View()); } //set the account to confirmed and updated the user user.IsConfirmed = true; await _userManager.UpdateAsync(user); //pop the view to let the user know the confirmation was successful ViewBag.MessageTitle = "Confirmation Successful"; ViewBag.Message = "Your account has been successfully activated! Click <a href='/Account/Login'>here</a> to login."; return(View()); } //if we got this far then the token is completely invalid ViewBag.MessageTitle = "Invalid Confirmation Token"; ViewBag.Message = "The confirmation token is invalid. If you feel you have received this message in error, please contact [your email]"; return(View()); }