public async Task SendsEmailChangeConfirmationNoticeWhenChangingAConfirmedEmailAddress()
            {
                var user = new User
                {
                    Username = "******",
                    EmailAddress = "*****@*****.**",
                    EmailAllowed = true
                };

                var authResult =
                    new PasswordAuthenticationResult(
                        PasswordAuthenticationResult.AuthenticationResult.Success,
                        new AuthenticatedUser(user, new Credential()));

                GetMock<AuthenticationService>()
                    .Setup(u => u.Authenticate("theUsername", "password"))
                    .CompletesWith(authResult);
                GetMock<IUserService>()
                    .Setup(u => u.ChangeEmailAddress(user, "*****@*****.**"))
                    .Callback(() => user.UpdateEmailAddress("*****@*****.**", () => "token"))
                    .Completes();
                var controller = GetController<UsersController>();
                controller.SetCurrentUser(user);

                var model = new AccountViewModel()
                {
                    ChangeEmail = new ChangeEmailViewModel
                    {
                        NewEmail = "*****@*****.**",
                        Password = "******"
                    }
                };

                var result = await controller.ChangeEmail(model);

                GetMock<IMessageService>()
                    .Verify(m => m.SendEmailChangeConfirmationNotice(It.IsAny<MailAddress>(), It.IsAny<string>()));
            }
            public async Task DoesNotSendEmailChangeConfirmationNoticeWhenAddressDoesntChange()
            {
                var user = new User
                {
                    EmailAddress = "*****@*****.**",
                    Username = "******",
                };

                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, new AuthenticatedUser(user, new Credential()));

                GetMock<AuthenticationService>()
                    .Setup(u => u.Authenticate("aUsername", "password"))
                    .CompletesWith(authResult);
                GetMock<IUserService>()
                    .Setup(u => u.ChangeEmailAddress(It.IsAny<User>(), It.IsAny<string>()))
                    .Callback(() => user.UpdateEmailAddress("*****@*****.**", () => "new-token"));
                var controller = GetController<UsersController>();
                controller.SetCurrentUser(user);

                var model = new AccountViewModel()
                {
                    ChangeEmail = new ChangeEmailViewModel
                    {
                        NewEmail = "*****@*****.**",
                        Password = "******"
                    }
                };

                await controller.ChangeEmail(model);

                GetMock<IUserService>()
                    .Verify(u => u.ChangeEmailAddress(user, "*****@*****.**"), Times.Never());
                GetMock<IMessageService>()
                    .Verify(m => m.SendEmailChangeConfirmationNotice(It.IsAny<MailAddress>(), It.IsAny<string>()), Times.Never());
            }
            public async Task DoesNotLetYouUseSomeoneElsesConfirmedEmailAddress()
            {
                var user = new User
                {
                    Username = "******",
                    EmailAddress = "*****@*****.**",
                    Key = 1,
                };

                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success,
                                                    new AuthenticatedUser(user, new Credential()));

                GetMock<AuthenticationService>()
                    .Setup(u => u.Authenticate(It.IsAny<string>(), It.IsAny<string>()))
                    .CompletesWith(authResult);
                GetMock<IUserService>()
                    .Setup(u => u.ChangeEmailAddress(user, "*****@*****.**"))
                    .Throws(new EntityException("msg"));
                var controller = GetController<UsersController>();
                controller.SetCurrentUser(user);

                var result = await controller.ChangeEmail(
                    new AccountViewModel()
                    {
                        ChangeEmail = new ChangeEmailViewModel
                        {
                            NewEmail = "*****@*****.**"
                        }
                    });
                Assert.False(controller.ModelState.IsValid);
                Assert.Equal("msg", controller.ModelState["ChangeEmail.NewEmail"].Errors[0].ErrorMessage);
            }
            public async Task GivenAdminLogsInWithValidExternalAuth_ItChallengesWhenNotUsingRequiredExternalProvider(string providerUsedForLogin, bool shouldChallenge)
            {
                var enforcedProvider = "AzureActiveDirectory";

                var mockConfig = GetMock<IGalleryConfigurationService>();
                mockConfig.Setup(x => x.Current).Returns(new AppConfiguration
                {
                    ConfirmEmailAddresses = false,
                    EnforcedAuthProviderForAdmin = enforcedProvider
                });

                var externalCred = new CredentialBuilder().CreateExternalCredential(providerUsedForLogin, "blorg", "Bloog");

                var authUser = new AuthenticatedUser(
                    new User("theUsername")
                    {
                        UnconfirmedEmailAddress = "*****@*****.**",
                        Roles =
                        {
                            new Role { Name = Constants.AdminRoleName }
                        }
                    },
                    externalCred);

                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser);

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authResult);

                GetMock<AuthenticationService>()
                    .Setup(x => x.AddCredential(authUser.User, externalCred))
                    .Completes()
                    .Verifiable();

                GetMock<IMessageService>()
                    .Setup(x => x.SendCredentialAddedNotice(authUser.User, externalCred))
                    .Verifiable();

                EnableAllAuthenticators(Get<AuthenticationService>());
                var controller = GetController<AuthenticationController>();

                if (shouldChallenge)
                {
                    GetMock<AuthenticationService>()
                        .Setup(x => x.Challenge(enforcedProvider, It.IsAny<string>()))
                        .Returns(new ChallengeResult(enforcedProvider, null))
                        .Verifiable();
                }
                else
                {
                    GetMock<AuthenticationService>()
                       .Setup(x => x.CreateSessionAsync(controller.OwinContext, It.IsAny<AuthenticatedUser>()))
                       .Returns(Task.FromResult(0))
                       .Verifiable();
                }
                
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult()
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                if (shouldChallenge)
                {
                    ResultAssert.IsChallengeResult(result, enforcedProvider);
                }
                else
                {
                    ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                }
                GetMock<AuthenticationService>().VerifyAll();
                GetMock<IMessageService>().VerifyAll();
            }
            public async Task GivenValidExternalAuth_ItLinksCredentialSendsEmailAndLogsIn()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { EmailAddress = "*****@*****.**" },
                    new Credential { Type = "Foo" });
                var externalCred = new CredentialBuilder().CreateExternalCredential("MicrosoftAccount", "blorg", "Bloog");
                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser);

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authResult);
                GetMock<AuthenticationService>()
                    .Setup(x => x.AddCredential(authUser.User, externalCred))
                    .Completes()
                    .Verifiable();
                GetMock<IMessageService>()
                    .Setup(x => x.SendCredentialAddedNotice(authUser.User, externalCred))
                    .Verifiable();

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.CreateSessionAsync(controller.OwinContext, It.IsAny<AuthenticatedUser>()))
                    .Returns(Task.FromResult(0))
                    .Verifiable();
                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult
                    {
                        ExternalIdentity = new ClaimsIdentity(),
                        Credential = externalCred
                    });

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>().VerifyAll();
                GetMock<IMessageService>().VerifyAll();
            }
            public async Task GivenExpiredExternalAuth_ItRedirectsBackToLogOnWithExternalAuthExpiredMessage()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { EmailAddress = "*****@*****.**" },
                    new Credential { Type = "Foo" });

                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser);

                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate(authUser.User.Username, "thePassword"))
                    .CompletesWith(authResult);

                var controller = GetController<AuthenticationController>();

                GetMock<AuthenticationService>()
                    .Setup(x => x.ReadExternalLoginCredential(controller.OwinContext))
                    .CompletesWith(new AuthenticateExternalLoginResult());

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            authUser.User.Username,
                            "thePassword")),
                    "theReturnUrl", linkingAccount: true);

                // Assert
                VerifyExternalLinkExpiredResult(controller, result);
                GetMock<AuthenticationService>()
                    .Verify(x => x.CreateSessionAsync(It.IsAny<IOwinContext>(), It.IsAny<AuthenticatedUser>()), Times.Never());
            }
            public async Task WillLogTheUserOnWithUsernameEvenWithoutConfirmedEmailAddress()
            {
                // Arrange
                var authUser = new AuthenticatedUser(
                    new User("theUsername") { UnconfirmedEmailAddress = "*****@*****.**" },
                    new Credential { Type = "Foo" });
                var authResult =
                    new PasswordAuthenticationResult(PasswordAuthenticationResult.AuthenticationResult.Success, authUser);
                GetMock<AuthenticationService>()
                    .Setup(x => x.Authenticate("*****@*****.**", "thePassword"))
                    .CompletesWith(authResult);
                var controller = GetController<AuthenticationController>();
                GetMock<AuthenticationService>()
                    .Setup(a => a.CreateSessionAsync(controller.OwinContext, authUser))
                    .Returns(Task.FromResult(0))
                    .Verifiable();

                // Act
                var result = await controller.SignIn(
                    new LogOnViewModel(
                        new SignInViewModel(
                            "*****@*****.**",
                            "thePassword")),
                    "theReturnUrl", linkingAccount: false);

                // Assert
                ResultAssert.IsSafeRedirectTo(result, "theReturnUrl");
                GetMock<AuthenticationService>().VerifyAll();
            }