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);
        }
Example #6
0
        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());
        }