public async Task EnrollSmsFactor()
        {
            var oktaClient = new OktaClient();
            var guid       = Guid.NewGuid();
            // MFA Group w/ SMS policy
            var groupId     = "{groupId}";
            var createdUser = await oktaClient.Users.CreateUserAsync(new CreateUserWithPasswordOptions
            {
                Profile = new UserProfile
                {
                    FirstName = "John",
                    LastName  = "Enroll-SMS",
                    Email     = $"john-enroll-sms-dotnet-authn-{guid}@example.com",
                    Login     = $"john-enroll-sms-dotnet-authn-{guid}@example.com",
                },
                Password = "******",
                Activate = true,
            });

            try
            {
                await oktaClient.Groups.AddUserToGroupAsync(groupId, createdUser.Id);

                var authnClient = TestAuthenticationClient.Create();

                var authnOptions = new AuthenticateOptions()
                {
                    Username = $"john-enroll-sms-dotnet-authn-{guid}@example.com",
                    Password = "******",
                    MultiOptionalFactorEnroll = true,
                    WarnBeforePasswordExpired = true,
                };

                var authnResponse = await authnClient.AuthenticateAsync(authnOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().NotBeNull();
                authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().HaveCountGreaterThan(0);
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.MfaEnroll);

                var enrollOptions = new EnrollSmsFactorOptions()
                {
                    PhoneNumber = "+1 415 555 5555",
                    StateToken  = authnResponse.StateToken,
                };

                authnResponse = await authnClient.EnrollFactorAsync(enrollOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.MfaEnrollActivate);
                authnResponse.GetProperty <Factor>("factor").Should().NotBeNull();
                authnResponse.GetProperty <Factor>("factor").Profile.GetProperty <string>("phoneNumber").Should().NotBeNullOrEmpty();
            }
            finally
            {
                await createdUser.DeactivateAsync();

                await createdUser.DeactivateOrDeleteAsync();
            }
        }
        public async Task AuthenticateUserWithExpiredPassword()
        {
            var oktaClient = new OktaClient();
            var guid       = Guid.NewGuid();

            var createdUser = await oktaClient.Users.CreateUserAsync(new CreateUserWithPasswordOptions
            {
                Profile = new UserProfile
                {
                    FirstName = "John",
                    LastName  = "Test",
                    Email     = $"john-expired-pass-dotnet-authn-{guid}@example.com",
                    Login     = $"john-expired-pass-dotnet-authn-{guid}@example.com",
                },
                Password = "******",
                Activate = true,
            });

            try
            {
                await createdUser.ExpirePasswordAsync();

                var authClient = TestAuthenticationClient.Create();

                var authnOptions = new AuthenticateOptions()
                {
                    Username = $"john-expired-pass-dotnet-authn-{guid}@example.com",
                    Password = "******",
                    MultiOptionalFactorEnroll = true,
                    WarnBeforePasswordExpired = true,
                };

                var authnResponse = await authClient.AuthenticateAsync(authnOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.StateToken.Should().NotBeNullOrEmpty();
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.PasswordExpired);
                authnResponse.Links.Should().NotBeNull();
            }
            finally
            {
                await createdUser.DeactivateAsync();

                await createdUser.DeactivateOrDeleteAsync();
            }
        }
        public async Task AuthenticateUserWithPendingEnroll()
        {
            var client = TestAuthenticationClient.Create();

            var authnOptions = new AuthenticateOptions()
            {
                Username = "******",
                Password = "******",
                MultiOptionalFactorEnroll = true,
                WarnBeforePasswordExpired = true,
            };

            var authnResponse = await client.AuthenticateAsync(authnOptions);

            authnResponse.Should().NotBeNull();
            authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().NotBeNull();
            authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().HaveCountGreaterThan(0);
            authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.MfaEnroll);
        }
        public async Task AuthenticateUserWithInvalidCredentials()
        {
            var oktaClient = new OktaClient();
            var guid       = Guid.NewGuid();

            var createdUser = await oktaClient.Users.CreateUserAsync(new CreateUserWithPasswordOptions
            {
                Profile = new UserProfile
                {
                    FirstName = "John",
                    LastName  = "Test",
                    Email     = $"john-invalid-cred-dotnet-authn-{guid}@example.com",
                    Login     = $"john-invalid-cred-dotnet-authn-{guid}@example.com",
                },
                Password = "******",
                Activate = true,
            });

            var authClient = TestAuthenticationClient.Create();

            var authnOptions = new AuthenticateOptions()
            {
                Username = $"john-invalid-cred-dotnet-authn-{guid}@example.com",
                Password = "******",
                MultiOptionalFactorEnroll = true,
                WarnBeforePasswordExpired = true,
            };

            try
            {
                Func <Task> act = async() => await authClient.AuthenticateAsync(authnOptions);

                act.Should().Throw <OktaApiException>();
            }
            finally
            {
                await createdUser.DeactivateAsync();

                await createdUser.DeactivateOrDeleteAsync();
            }
        }
        public async Task EnrollSecurityQuestionFactor()
        {
            var oktaClient = new OktaClient();
            var guid       = Guid.NewGuid();
            // MFA Group w/ Security Question policy
            var groupId     = "{groupId}";
            var createdUser = await oktaClient.Users.CreateUserAsync(new CreateUserWithPasswordOptions
            {
                Profile = new UserProfile
                {
                    FirstName = "John",
                    LastName  = "Enroll-Security-Question",
                    Email     = $"john-enroll-question-dotnet-authn-{guid}@example.com",
                    Login     = $"john-enroll-question-dotnet-authn-{guid}@example.com",
                },
                Password = "******",
                Activate = true,
            });

            try
            {
                await oktaClient.Groups.AddUserToGroupAsync(groupId, createdUser.Id);

                var authnClient = TestAuthenticationClient.Create();

                var authnOptions = new AuthenticateOptions()
                {
                    Username = $"john-enroll-question-dotnet-authn-{guid}@example.com",
                    Password = "******",
                    MultiOptionalFactorEnroll = true,
                    WarnBeforePasswordExpired = true,
                };

                var authnResponse = await authnClient.AuthenticateAsync(authnOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().NotBeNull();
                authnResponse.Embedded.GetArrayProperty <Factor>("factors").Should().HaveCountGreaterThan(0);
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.MfaEnroll);

                var enrollOptions = new EnrollSecurityQuestionFactorOptions()
                {
                    Question   = "name_of_first_plush_toy",
                    Answer     = "blah",
                    StateToken = authnResponse.StateToken,
                };

                authnResponse = await authnClient.EnrollFactorAsync(enrollOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.MfaEnroll);

                // Authenticate after enroll
                authnResponse = await authnClient.AuthenticateAsync(authnOptions);

                authnResponse.Should().NotBeNull();
                authnResponse.AuthenticationStatus.Should().Be(AuthenticationStatus.Success);
            }
            finally
            {
                await createdUser.DeactivateAsync();

                await createdUser.DeactivateOrDeleteAsync();
            }
        }